From c6301a826ebcf38a34b93a02c8013dd1ef9e7abc Mon Sep 17 00:00:00 2001 From: molvqingtai Date: Sat, 9 Nov 2024 05:11:33 +0800 Subject: [PATCH 1/3] fix: the number of online users is inaccurate --- src/app/content/App.tsx | 40 ++++--- src/app/content/index.tsx | 2 +- src/app/content/views/AppButton/index.tsx | 14 ++- src/domain/AppStatus.ts | 2 +- src/domain/Room.ts | 137 ++++++++++++++-------- src/domain/Toast.ts | 12 ++ src/domain/externs/PeerRoom.ts | 2 +- src/domain/externs/Toast.ts | 16 ++- src/domain/impls/PeerRoom.ts | 2 +- src/domain/impls/PeerRoom2.ts | 2 +- src/domain/impls/Toast.ts | 24 ++-- src/domain/modules/Toast.ts | 79 ++++++++++--- 12 files changed, 232 insertions(+), 100 deletions(-) diff --git a/src/app/content/App.tsx b/src/app/content/App.tsx index e658204..7ff010a 100644 --- a/src/app/content/App.tsx +++ b/src/app/content/App.tsx @@ -62,19 +62,31 @@ export default function App() { }, [danmakuIsEnabled]) return ( - appStatusLoadIsFinished && ( -
- -
-
-
- {notUserInfo && } - - - - - -
- ) +
+ {appStatusLoadIsFinished && ( + <> + +
+
+
+ {notUserInfo && } + + + + + )} + +
) } diff --git a/src/app/content/index.tsx b/src/app/content/index.tsx index 153f9c6..1d317cb 100644 --- a/src/app/content/index.tsx +++ b/src/app/content/index.tsx @@ -13,10 +13,10 @@ import { NotificationImpl } from '@/domain/impls/Notification' import { ToastImpl } from '@/domain/impls/Toast' // import { PeerRoomImpl } from '@/domain/impls/PeerRoom' import { PeerRoomImpl } from '@/domain/impls/PeerRoom2' -import '@/assets/styles/tailwind.css' // Remove import after merging: https://github.com/emilkowalski/sonner/pull/508 import '@/assets/styles/sonner.css' import '@/assets/styles/overlay.css' +import '@/assets/styles/tailwind.css' import NotificationDomain from '@/domain/Notification' import { createElement } from '@/utils' diff --git a/src/app/content/views/AppButton/index.tsx b/src/app/content/views/AppButton/index.tsx index 0d463c2..e30fd53 100644 --- a/src/app/content/views/AppButton/index.tsx +++ b/src/app/content/views/AppButton/index.tsx @@ -107,7 +107,7 @@ const AppButton: FC = ({ className }) => { - - diff --git a/src/domain/AppStatus.ts b/src/domain/AppStatus.ts index 8a6b732..fb12dbf 100644 --- a/src/domain/AppStatus.ts +++ b/src/domain/AppStatus.ts @@ -40,7 +40,7 @@ const AppStatusDomain = Remesh.domain({ }) const StatusState = domain.state({ - name: 'AppStatus.OpenState', + name: 'AppStatus.StatusState', default: defaultStatusState }) diff --git a/src/domain/Room.ts b/src/domain/Room.ts index b1f9132..3833d0d 100644 --- a/src/domain/Room.ts +++ b/src/domain/Room.ts @@ -58,7 +58,7 @@ export interface TextMessage extends MessageUser { export type RoomMessage = SyncUserMessage | SyncHistoryMessage | LikeMessage | HateMessage | TextMessage -export type RoomUser = MessageUser & { peerId: string; joinTime: number } +export type RoomUser = MessageUser & { peerIds: string[]; joinTime: number } const MessageUserSchema = { userId: v.string(), @@ -165,7 +165,7 @@ const RoomDomain = Remesh.domain({ const SelfUserQuery = domain.query({ name: 'Room.SelfUserQuery', impl: ({ get }) => { - return get(UserListQuery()).find((user) => user.peerId === get(PeerIdQuery()))! + return get(UserListQuery()).find((user) => user.peerIds.includes(peerRoom.peerId))! } }) @@ -185,9 +185,7 @@ const RoomDomain = Remesh.domain({ const JoinRoomCommand = domain.command({ name: 'Room.JoinRoomCommand', impl: ({ get }) => { - peerRoom.joinRoom() const { id: userId, name: username, avatar: userAvatar } = get(userInfoDomain.query.UserInfoQuery())! - return [ UpdateUserListCommand({ type: 'create', @@ -204,15 +202,20 @@ const RoomDomain = Remesh.domain({ receiveTime: Date.now() }), JoinStatusModule.command.SetFinishedCommand(), - JoinRoomEvent(peerRoom.roomId) + JoinRoomEvent(peerRoom.roomId), + SelfJoinRoomEvent(peerRoom.roomId) ] } }) + JoinRoomCommand.after(() => { + peerRoom.joinRoom() + return null + }) + const LeaveRoomCommand = domain.command({ name: 'Room.LeaveRoomCommand', impl: ({ get }) => { - peerRoom.leaveRoom() const { id: userId, name: username, avatar: userAvatar } = get(userInfoDomain.query.UserInfoQuery())! return [ messageListDomain.command.CreateItemCommand({ @@ -230,11 +233,17 @@ const RoomDomain = Remesh.domain({ user: { peerId: peerRoom.peerId, joinTime: Date.now(), userId, username, userAvatar } }), JoinStatusModule.command.SetInitialCommand(), - LeaveRoomEvent(peerRoom.roomId) + LeaveRoomEvent(peerRoom.roomId), + SelfLeaveRoomEvent(peerRoom.roomId) ] } }) + LeaveRoomCommand.after(() => { + peerRoom.leaveRoom() + return null + }) + const SendTextMessageCommand = domain.command({ name: 'Room.SendTextMessageCommand', impl: ({ get }, message: string | { body: string; atUsers: AtUser[] }) => { @@ -314,6 +323,7 @@ const RoomDomain = Remesh.domain({ const syncUserMessage: SyncUserMessage = { ...self, id: nanoid(), + peerId: peerRoom.peerId, sendTime: Date.now(), lastMessageTime, type: SendType.SyncUser @@ -393,12 +403,32 @@ const RoomDomain = Remesh.domain({ const UpdateUserListCommand = domain.command({ name: 'Room.UpdateUserListCommand', - impl: ({ get }, action: { type: 'create' | 'delete'; user: RoomUser }) => { + impl: ({ get }, action: { type: 'create' | 'delete'; user: Omit & { peerId: string } }) => { const userList = get(UserListState()) + const existUser = userList.find((user) => user.userId === action.user.userId) if (action.type === 'create') { - return [UserListState().new(upsert(userList, action.user, 'userId'))] + return [ + UserListState().new( + upsert( + userList, + { ...action.user, peerIds: [...(existUser?.peerIds || []), action.user.peerId] }, + 'userId' + ) + ) + ] } else { - return [UserListState().new(userList.filter(({ userId }) => userId !== action.user.userId))] + return [ + UserListState().new( + upsert( + userList, + { + ...action.user, + peerIds: existUser?.peerIds?.filter((peerId) => peerId !== action.user.peerId) || [] + }, + 'userId' + ).filter((user) => user.peerIds.length) + ) + ] } } }) @@ -443,10 +473,18 @@ const RoomDomain = Remesh.domain({ name: 'Room.OnJoinRoomEvent' }) + const SelfJoinRoomEvent = domain.event({ + name: 'Room.SelfJoinRoomEvent' + }) + const OnLeaveRoomEvent = domain.event({ name: 'Room.OnLeaveRoomEvent' }) + const SelfLeaveRoomEvent = domain.event({ + name: 'Room.SelfLeaveRoomEvent' + }) + const OnErrorEvent = domain.event({ name: 'Room.OnErrorEvent' }) @@ -486,37 +524,33 @@ const RoomDomain = Remesh.domain({ const messageCommand$ = (() => { switch (message.type) { case SendType.SyncUser: { - const userList = get(UserListQuery()) const selfUser = get(SelfUserQuery()) - // If the browser has multiple tabs open, it can cause the same user to join multiple times with the same peerId but different userId - const isRepeatJoin = userList.some((user) => user.userId === message.userId) - // When a new user joins, it triggers join events for all users, i.e., newUser join event and oldUser join event - // Use joinTime to determine if it's a new user - const isNewJoinEvent = selfUser.joinTime < message.joinTime + + // If a new user joins after the current user has entered the room, a join log message needs to be created. + const existUser = get(UserListQuery()).find((user) => user.userId === message.userId) + const isNewJoinUser = !existUser && message.joinTime > selfUser.joinTime const lastMessageTime = get(LastMessageTimeQuery()) const needSyncHistory = lastMessageTime > message.lastMessageTime - return isRepeatJoin - ? EMPTY - : of( - UpdateUserListCommand({ type: 'create', user: message }), - isNewJoinEvent - ? messageListDomain.command.CreateItemCommand({ - ...message, - id: nanoid(), - body: `"${message.username}" joined the chat`, - type: MessageType.Prompt, - receiveTime: Date.now() - }) - : null, - needSyncHistory - ? SendSyncHistoryMessageCommand({ - peerId: message.peerId, - lastMessageTime: message.lastMessageTime - }) - : null - ) + return of( + UpdateUserListCommand({ type: 'create', user: message }), + isNewJoinUser + ? messageListDomain.command.CreateItemCommand({ + ...message, + id: nanoid(), + body: `"${message.username}" joined the chat`, + type: MessageType.Prompt, + receiveTime: Date.now() + }) + : null, + needSyncHistory + ? SendSyncHistoryMessageCommand({ + peerId: message.peerId, + lastMessageTime: message.lastMessageTime + }) + : null + ) } case SendType.SyncHistory: { @@ -574,20 +608,26 @@ const RoomDomain = Remesh.domain({ impl: ({ get }) => { const onLeaveRoom$ = fromEventPattern(peerRoom.onLeaveRoom).pipe( map((peerId) => { + if (get(JoinStatusModule.query.IsInitialQuery())) { + return null + } // console.log('onLeaveRoom', peerId) - const user = get(UserListQuery()).find((user) => user.peerId === peerId) - if (user) { + const existUser = get(UserListQuery()).find((user) => user.peerIds.includes(peerId)) + + if (existUser) { return [ - UpdateUserListCommand({ type: 'delete', user }), - messageListDomain.command.CreateItemCommand({ - ...user, - id: nanoid(), - body: `"${user.username}" left the chat`, - type: MessageType.Prompt, - sendTime: Date.now(), - receiveTime: Date.now() - }), + UpdateUserListCommand({ type: 'delete', user: { ...existUser, peerId } }), + existUser.peerIds.length === 1 + ? messageListDomain.command.CreateItemCommand({ + ...existUser, + id: nanoid(), + body: `"${existUser.username}" left the chat`, + type: MessageType.Prompt, + sendTime: Date.now(), + receiveTime: Date.now() + }) + : null, OnLeaveRoomEvent(peerId) ] } else { @@ -612,7 +652,6 @@ const RoomDomain = Remesh.domain({ } }) - // TODO: Move this to a service worker in the future, so we don't need to send a leave room message every time the page refreshes domain.effect({ name: 'Room.OnUnloadEffect', impl: ({ get }) => { @@ -647,7 +686,9 @@ const RoomDomain = Remesh.domain({ SendSyncUserMessageEvent, SendSyncHistoryMessageEvent, JoinRoomEvent, + SelfJoinRoomEvent, LeaveRoomEvent, + SelfLeaveRoomEvent, OnMessageEvent, OnTextMessageEvent, OnJoinRoomEvent, diff --git a/src/domain/Toast.ts b/src/domain/Toast.ts index 6ff3dc5..32c1abb 100644 --- a/src/domain/Toast.ts +++ b/src/domain/Toast.ts @@ -8,6 +8,18 @@ const ToastDomain = Remesh.domain({ impl: (domain) => { const roomDomain = domain.getDomain(RoomDomain()) const toastModule = ToastModule(domain) + + domain.effect({ + name: 'Toast.OnRoomSelfJoinRoomEffect', + impl: ({ fromEvent }) => { + const onRoomJoin$ = fromEvent(roomDomain.event.SelfJoinRoomEvent).pipe( + map(() => toastModule.command.LoadingCommand('Connected to the chat.')) + ) + + return onRoomJoin$ + } + }) + domain.effect({ name: 'Toast.OnRoomErrorEffect', impl: ({ fromEvent }) => { diff --git a/src/domain/externs/PeerRoom.ts b/src/domain/externs/PeerRoom.ts index 5d79063..9e32627 100644 --- a/src/domain/externs/PeerRoom.ts +++ b/src/domain/externs/PeerRoom.ts @@ -5,7 +5,7 @@ export interface PeerRoom { readonly peerId: string readonly roomId: string joinRoom: () => PeerRoom - sendMessage: (message: RoomMessage, id?: string) => PeerRoom + sendMessage: (message: RoomMessage, id?: string | string[]) => PeerRoom onMessage: (callback: (message: RoomMessage) => void) => PeerRoom leaveRoom: () => PeerRoom onJoinRoom: (callback: (id: string) => void) => PeerRoom diff --git a/src/domain/externs/Toast.ts b/src/domain/externs/Toast.ts index 1ea08f9..0bf3030 100644 --- a/src/domain/externs/Toast.ts +++ b/src/domain/externs/Toast.ts @@ -1,10 +1,12 @@ import { Remesh } from 'remesh' export interface Toast { - success: (message: string) => void - error: (message: string) => void - info: (message: string) => void - warning: (message: string) => void + success: (message: string, duration?: number) => number | string + error: (message: string, duration?: number) => number | string + info: (message: string, duration?: number) => number | string + warning: (message: string, duration?: number) => number | string + loading: (message: string, duration?: number) => number | string + cancel: (id: number | string) => number | string } export const ToastExtern = Remesh.extern({ @@ -20,6 +22,12 @@ export const ToastExtern = Remesh.extern({ }, warning: () => { throw new Error('"warning" not implemented.') + }, + loading: () => { + throw new Error('"loading" not implemented.') + }, + cancel: () => { + throw new Error('"cancel" not implemented.') } } }) diff --git a/src/domain/impls/PeerRoom.ts b/src/domain/impls/PeerRoom.ts index 361f878..1f234b6 100644 --- a/src/domain/impls/PeerRoom.ts +++ b/src/domain/impls/PeerRoom.ts @@ -45,7 +45,7 @@ class PeerRoom extends EventHub { return this } - sendMessage(message: RoomMessage, id?: string) { + sendMessage(message: RoomMessage, id?: string | string[]) { if (!this.room) { this.once('action', () => { if (!this.room) { diff --git a/src/domain/impls/PeerRoom2.ts b/src/domain/impls/PeerRoom2.ts index 2336d70..30dc665 100644 --- a/src/domain/impls/PeerRoom2.ts +++ b/src/domain/impls/PeerRoom2.ts @@ -46,7 +46,7 @@ class PeerRoom extends EventHub { return this } - sendMessage(message: RoomMessage, id?: string) { + sendMessage(message: RoomMessage, id?: string | string[]) { if (!this.room) { this.once('action', () => { if (!this.room) { diff --git a/src/domain/impls/Toast.ts b/src/domain/impls/Toast.ts index db6c60d..7fb703b 100644 --- a/src/domain/impls/Toast.ts +++ b/src/domain/impls/Toast.ts @@ -2,16 +2,24 @@ import { toast } from 'sonner' import { ToastExtern } from '@/domain/externs/Toast' export const ToastImpl = ToastExtern.impl({ - success: (message: string) => { - toast.success(message) + success: (message: string, duration: number = 4000) => { + return toast.success(message, { duration }) }, - error: (message: string) => { - toast.error(message) + error: (message: string, duration: number = 4000) => { + return toast.error(message, { duration }) }, - info: (message: string) => { - toast.info(message) + info: (message: string, duration: number = 4000) => { + return toast.info(message, { duration }) }, - warning: (message: string) => { - toast.warning(message) + warning: (message: string, duration: number = 4000) => { + return toast.warning(message, { duration }) + }, + loading: (message: string, duration: number = 4000) => { + const id = toast.loading(message, { duration }) + setTimeout(() => toast.dismiss(id), duration) + return id + }, + cancel: (id: number | string) => { + return toast.dismiss(id) } }) diff --git a/src/domain/modules/Toast.ts b/src/domain/modules/Toast.ts index b117d84..788b08d 100644 --- a/src/domain/modules/Toast.ts +++ b/src/domain/modules/Toast.ts @@ -8,51 +8,90 @@ export interface ToastOptions { const ToastModule = (domain: RemeshDomainContext, options: ToastOptions = { name: 'MessageToastModule' }) => { const toast = domain.getExtern(ToastExtern) - const SuccessEvent = domain.event({ + const SuccessEvent = domain.event({ name: `${options.name}.SuccessEvent` }) const SuccessCommand = domain.command({ name: `${options.name}.SuccessCommand`, - impl: (_, message: string) => { - toast.success(message) - return [SuccessEvent()] + impl: (_, message: string | { message: string; duration?: number }) => { + const id = toast.success( + typeof message === 'string' ? message : message.message, + typeof message === 'string' ? undefined : message.duration + ) + return [SuccessEvent(id)] } }) - const ErrorEvent = domain.event({ + const ErrorEvent = domain.event({ name: `${options.name}.ErrorEvent` }) const ErrorCommand = domain.command({ name: `${options.name}.ErrorCommand`, - impl: (_, message: string) => { - toast.error(message) - return [ErrorEvent()] + impl: (_, message: string | { message: string; duration?: number }) => { + const id = toast.error( + typeof message === 'string' ? message : message.message, + typeof message === 'string' ? undefined : message.duration + ) + return [ErrorEvent(id)] } }) - const InfoEvent = domain.event({ + const InfoEvent = domain.event({ name: `${options.name}.InfoEvent` }) const InfoCommand = domain.command({ name: `${options.name}.InfoCommand`, - impl: (_, message: string) => { - toast.info(message) - return [InfoEvent()] + impl: (_, message: string | { message: string; duration?: number }) => { + const id = toast.info( + typeof message === 'string' ? message : message.message, + typeof message === 'string' ? undefined : message.duration + ) + return [InfoEvent(id)] } }) - const WarningEvent = domain.event({ + const WarningEvent = domain.event({ name: `${options.name}.WarningEvent` }) const WarningCommand = domain.command({ name: `${options.name}.WarningCommand`, - impl: (_, message: string) => { - toast.warning(message) - return [WarningEvent()] + impl: (_, message: string | { message: string; duration?: number }) => { + const id = toast.warning( + typeof message === 'string' ? message : message.message, + typeof message === 'string' ? undefined : message.duration + ) + return [WarningEvent(id)] + } + }) + + const LoadingEvent = domain.event({ + name: `${options.name}.LoadingEvent` + }) + + const LoadingCommand = domain.command({ + name: `${options.name}.LoadingCommand`, + impl: (_, message: string | { message: string; duration?: number }) => { + const id = toast.loading( + typeof message === 'string' ? message : message.message, + typeof message === 'string' ? undefined : message.duration + ) + return [LoadingEvent(id)] + } + }) + + const CancelEvent = domain.event({ + name: `${options.name}.CancelEvent` + }) + + const CancelCommand = domain.command({ + name: `${options.name}.CancelCommand`, + impl: (_, id: number | string) => { + toast.cancel(id) + return [CancelEvent(id)] } }) @@ -61,13 +100,17 @@ const ToastModule = (domain: RemeshDomainContext, options: ToastOptions = { name SuccessEvent, ErrorEvent, InfoEvent, - WarningEvent + WarningEvent, + LoadingEvent, + CancelEvent }, command: { SuccessCommand, ErrorCommand, InfoCommand, - WarningCommand + WarningCommand, + LoadingCommand, + CancelCommand } } } From 6222e3f8af1bf4fad2466a9bf88c3b3159478a86 Mon Sep 17 00:00:00 2001 From: molvqingtai Date: Sat, 9 Nov 2024 05:57:00 +0800 Subject: [PATCH 2/3] perf: theme mode is compatible with website themes by default --- src/app/content/App.tsx | 17 ++++++++++++----- src/app/content/views/AppButton/index.tsx | 5 ++--- src/app/content/views/Setup/index.tsx | 4 ++-- src/app/options/components/ProfileForm.tsx | 4 ++-- src/domain/Toast.ts | 2 +- src/utils/checkDarkMode.ts | 11 +++++++++++ src/utils/checkSystemDarkMode.ts | 3 --- src/utils/index.ts | 2 +- 8 files changed, 31 insertions(+), 17 deletions(-) create mode 100644 src/utils/checkDarkMode.ts delete mode 100644 src/utils/checkSystemDarkMode.ts diff --git a/src/app/content/App.tsx b/src/app/content/App.tsx index 7ff010a..0d51785 100644 --- a/src/app/content/App.tsx +++ b/src/app/content/App.tsx @@ -14,7 +14,7 @@ import { Toaster } from 'sonner' import DanmakuContainer from './components/DanmakuContainer' import DanmakuDomain from '@/domain/Danmaku' import AppStatusDomain from '@/domain/AppStatus' -import { cn } from '@/utils' +import { checkDarkMode, cn } from '@/utils' /** * Fix requestAnimationFrame error in jest @@ -52,8 +52,6 @@ export default function App() { } }, [userInfoSetFinished, messageListLoadFinished]) - const danmakuContainerRef = useRef(null) - useEffect(() => { danmakuIsEnabled && send(danmakuDomain.command.MountCommand(danmakuContainerRef.current!)) return () => { @@ -61,8 +59,17 @@ export default function App() { } }, [danmakuIsEnabled]) + const themeMode = + userInfo?.themeMode === 'system' + ? checkDarkMode() + ? 'dark' + : 'light' + : (userInfo?.themeMode ?? (checkDarkMode() ? 'dark' : 'light')) + + const danmakuContainerRef = useRef(null) + return ( -
+
{appStatusLoadIsFinished && ( <> @@ -72,7 +79,7 @@ export default function App() { {notUserInfo && } = ({ className }) => { const DayLogo = [LogoIcon0, LogoIcon1, LogoIcon2, LogoIcon3, LogoIcon4, LogoIcon5, LogoIcon6][getDay(Date())] - const isDarkMode = - userInfo?.themeMode === 'dark' ? true : userInfo?.themeMode === 'light' ? false : checkSystemDarkMode() + const isDarkMode = userInfo?.themeMode === 'dark' ? true : userInfo?.themeMode === 'light' ? false : checkDarkMode() const [menuOpen, setMenuOpen] = useState(false) diff --git a/src/app/content/views/Setup/index.tsx b/src/app/content/views/Setup/index.tsx index 73ea209..c2cedf7 100644 --- a/src/app/content/views/Setup/index.tsx +++ b/src/app/content/views/Setup/index.tsx @@ -2,7 +2,7 @@ import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/Avatar' import { MAX_AVATAR_SIZE } from '@/constants/config' import MessageListDomain, { Message, MessageType } from '@/domain/MessageList' import UserInfoDomain, { UserInfo } from '@/domain/UserInfo' -import { checkSystemDarkMode, generateRandomAvatar, generateRandomName } from '@/utils' +import { generateRandomAvatar, generateRandomName } from '@/utils' import { UserIcon } from 'lucide-react' import { nanoid } from 'nanoid' import { FC, useEffect, useState } from 'react' @@ -39,7 +39,7 @@ const generateUserInfo = async (): Promise => { name: generateRandomName(), avatar: await generateRandomAvatar(MAX_AVATAR_SIZE), createTime: Date.now(), - themeMode: checkSystemDarkMode() ? 'dark' : 'system', + themeMode: 'system', danmakuEnabled: true, notificationEnabled: true, notificationType: 'all' diff --git a/src/app/options/components/ProfileForm.tsx b/src/app/options/components/ProfileForm.tsx index f3bb1b0..48d7f19 100644 --- a/src/app/options/components/ProfileForm.tsx +++ b/src/app/options/components/ProfileForm.tsx @@ -9,7 +9,7 @@ import { Button } from '@/components/ui/Button' import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/Form' import { Input } from '@/components/ui/Input' import UserInfoDomain, { type UserInfo } from '@/domain/UserInfo' -import { checkSystemDarkMode, cn, generateRandomAvatar } from '@/utils' +import { cn, generateRandomAvatar } from '@/utils' import { RadioGroup, RadioGroupItem } from '@/components/ui/RadioGroup' import { Label } from '@/components/ui/Label' import { RefreshCcwIcon } from 'lucide-react' @@ -24,7 +24,7 @@ const defaultUserInfo: UserInfo = { name: '', avatar: '', createTime: Date.now(), - themeMode: checkSystemDarkMode() ? 'dark' : 'system', + themeMode: 'system', danmakuEnabled: true, notificationEnabled: true, notificationType: 'all' diff --git a/src/domain/Toast.ts b/src/domain/Toast.ts index 32c1abb..fe43f11 100644 --- a/src/domain/Toast.ts +++ b/src/domain/Toast.ts @@ -13,7 +13,7 @@ const ToastDomain = Remesh.domain({ name: 'Toast.OnRoomSelfJoinRoomEffect', impl: ({ fromEvent }) => { const onRoomJoin$ = fromEvent(roomDomain.event.SelfJoinRoomEvent).pipe( - map(() => toastModule.command.LoadingCommand('Connected to the chat.')) + map(() => toastModule.command.LoadingCommand({ message: 'Connected to the chat.', duration: 3000 })) ) return onRoomJoin$ diff --git a/src/utils/checkDarkMode.ts b/src/utils/checkDarkMode.ts new file mode 100644 index 0000000..8dd91f4 --- /dev/null +++ b/src/utils/checkDarkMode.ts @@ -0,0 +1,11 @@ +const checkDarkMode = () => { + const colorScheme = document.documentElement.style.getPropertyValue('color-scheme').trim() + + if (colorScheme === 'dark') { + return true // Prefer the website's color-scheme property value + } + + return window.matchMedia('(prefers-color-scheme: dark)').matches // Otherwise, check the system theme +} + +export default checkDarkMode diff --git a/src/utils/checkSystemDarkMode.ts b/src/utils/checkSystemDarkMode.ts deleted file mode 100644 index ac1f58a..0000000 --- a/src/utils/checkSystemDarkMode.ts +++ /dev/null @@ -1,3 +0,0 @@ -const checkSystemDarkMode = () => window.matchMedia('(prefers-color-scheme: dark)').matches - -export default checkSystemDarkMode diff --git a/src/utils/index.ts b/src/utils/index.ts index d5e36d2..a52912f 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -4,7 +4,7 @@ export { default as createElement } from './createElement' export { default as getSiteInfo } from './getSiteInfo' export { default as compressImage } from './compressImage' export { default as isNullish } from './isNullish' -export { default as checkSystemDarkMode } from './checkSystemDarkMode' +export { default as checkDarkMode } from './checkDarkMode' export { default as stringToHex } from './stringToHex' export { default as debounce } from './debounce' export { default as throttle } from './throttle' From 00f0bd08b04e49f83cee60bb5767acd460a1b5d0 Mon Sep 17 00:00:00 2001 From: molvqingtai Date: Sat, 9 Nov 2024 22:43:32 +0800 Subject: [PATCH 3/3] perf: optimize taost dark mode --- src/app/options/App.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/app/options/App.tsx b/src/app/options/App.tsx index 87d6036..f047294 100644 --- a/src/app/options/App.tsx +++ b/src/app/options/App.tsx @@ -16,7 +16,15 @@ function App() {
- +