Skip to content

Commit f36ae70

Browse files
committed
perf: custom toast style
1 parent 415b9f5 commit f36ae70

13 files changed

Lines changed: 841 additions & 94 deletions

File tree

src/app/content/App.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ import AppButton from '@/app/content/views/AppButton'
55
import AppContainer from '@/app/content/views/AppContainer'
66
import { useRemeshDomain, useRemeshQuery, useRemeshSend } from 'remesh-react'
77
import RoomDomain from '@/domain/Room'
8-
import { Toaster } from '@/components/ui/Sonner'
98
import UserInfoDomain from '@/domain/UserInfo'
109
import Setup from '@/app/content/views/Setup'
1110
import MessageListDomain from '@/domain/MessageList'
1211
import { useEffect } from 'react'
12+
import { Toaster } from 'sonner'
1313

1414
export default function App() {
1515
const send = useRemeshSend()
@@ -23,8 +23,13 @@ export default function App() {
2323
const notUserInfo = userInfoLoadFinished && !userInfoSetFinished
2424

2525
useEffect(() => {
26-
if (userInfoSetFinished && messageListLoadFinished) {
27-
send(roomDomain.command.JoinRoomCommand())
26+
if (messageListLoadFinished) {
27+
if (userInfoSetFinished) {
28+
send(roomDomain.command.JoinRoomCommand())
29+
} else {
30+
// Clear simulated data when refreshing on the setup page
31+
send(messageListDomain.command.ClearListCommand())
32+
}
2833
}
2934
}, [userInfoSetFinished, messageListLoadFinished])
3035

@@ -35,9 +40,9 @@ export default function App() {
3540
<Main />
3641
<Footer />
3742
{notUserInfo && <Setup />}
43+
<Toaster richColors offset="70px" visibleToasts={1} duration={5000} position="top-center"></Toaster>
3844
</AppContainer>
3945
<AppButton></AppButton>
40-
<Toaster richColors offset="104px" position="top-center"></Toaster>
4146
</>
4247
)
4348
}

src/app/content/index.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { IndexDBStorageImpl, BrowserSyncStorageImpl } from '@/domain/impls/Stora
1111
import { PeerRoomImpl } from '@/domain/impls/PeerRoom'
1212
// import { PeerRoomImpl } from '@/domain/impls/PeerRoom2'
1313
import '@/assets/styles/tailwind.css'
14+
import '@/assets/styles/sonner.css'
1415
import { createElement } from '@/utils'
1516
import { ToastImpl } from '@/domain/impls/Toast'
1617

@@ -27,19 +28,18 @@ export default defineContentScript({
2728
name: __NAME__,
2829
position: 'inline',
2930
anchor: 'body',
30-
isolateEvents: ['scroll', 'click'],
3131
mode: __DEV__ ? 'open' : 'closed',
3232
onMount: (container) => {
3333
const app = createElement('<div id="app"></div>')
3434
container.append(app)
3535

3636
const root = createRoot(app)
3737
root.render(
38-
// <React.StrictMode>
39-
<RemeshRoot store={store}>
40-
<App />
41-
</RemeshRoot>
42-
// </React.StrictMode>
38+
<React.StrictMode>
39+
<RemeshRoot store={store}>
40+
<App />
41+
</RemeshRoot>
42+
</React.StrictMode>
4343
)
4444
return root
4545
},

src/app/content/views/AppButton/index.tsx

Lines changed: 76 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { type ReactNode, type FC, useState, type MouseEvent, useRef } from 'react'
22
import { SettingsIcon, MoonIcon, SunIcon } from 'lucide-react'
3+
import { motion, AnimatePresence } from 'framer-motion'
34

45
import { browser } from 'wxt/browser'
56
import { useRemeshDomain, useRemeshQuery, useRemeshSend } from 'remesh-react'
@@ -25,14 +26,12 @@ const AppButton: FC<AppButtonProps> = ({ children }) => {
2526

2627
const menuRef = useRef<HTMLDivElement>(null)
2728

28-
/**
29-
* Waiting for PR merge
30-
* @see https://github.com/streamich/react-use/pull/2528
31-
*/
3229
useClickAway(menuRef, () => {
3330
setOpen(false)
3431
}, ['click'])
3532

33+
const handleToggleApp = () => {}
34+
3635
const handleToggleMenu = (e: MouseEvent<HTMLButtonElement>) => {
3736
e.preventDefault()
3837
setOpen(!open)
@@ -52,35 +51,80 @@ const AppButton: FC<AppButtonProps> = ({ children }) => {
5251

5352
return (
5453
<div ref={menuRef} className="fixed bottom-5 right-5 z-infinity grid select-none justify-center gap-y-3">
55-
{/* <div className="grid gap-y-3" inert={!open && ''}> */}
56-
<div className="pointer-events-none grid gap-y-3">
57-
<Button
58-
onClick={handleSwitchTheme}
59-
variant="outline"
60-
data-state={open ? 'open' : 'closed'}
61-
className="pointer-events-auto relative size-10 overflow-hidden rounded-full p-0 shadow fill-mode-forwards data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out data-[state=open]:fade-in data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom"
62-
>
63-
<div
64-
className={cn(
65-
'absolute -top-10 grid grid-rows-[repeat(2,minmax(0,2.5rem))] w-full justify-center items-center transition-all duration-500',
66-
isDarkMode ? 'top-0' : '-top-10 ',
67-
isDarkMode ? 'bg-slate-800 text-white' : 'bg-white text-orange-400'
68-
)}
54+
<AnimatePresence>
55+
{open && (
56+
<motion.div
57+
className="grid gap-y-3"
58+
initial="hidden"
59+
animate="visible"
60+
exit="exit"
61+
variants={{
62+
hidden: {},
63+
visible: {
64+
transition: {
65+
staggerChildren: 0.1,
66+
staggerDirection: -1
67+
}
68+
},
69+
exit: {
70+
transition: {
71+
staggerChildren: 0.1,
72+
staggerDirection: 1
73+
}
74+
}
75+
}}
6976
>
70-
<MoonIcon size={20} />
71-
<SunIcon size={20} />
72-
</div>
73-
</Button>
74-
<Button
75-
onClick={handleOpenOptionsPage}
76-
variant="outline"
77-
data-state={open ? 'open' : 'closed'}
78-
className="pointer-events-auto size-10 rounded-full p-0 shadow fill-mode-forwards data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out data-[state=open]:fade-in data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom"
79-
>
80-
<SettingsIcon size={20} />
81-
</Button>
82-
</div>
83-
<Button onContextMenu={handleToggleMenu} className="relative z-10 size-10 rounded-full p-0 text-xs shadow">
77+
<motion.div
78+
className="leading-none"
79+
variants={{
80+
hidden: { opacity: 0, y: 12 },
81+
visible: { opacity: 1, y: 0 },
82+
exit: { opacity: 0, y: 12 }
83+
}}
84+
transition={{ duration: 0.1 }}
85+
>
86+
<Button
87+
onClick={handleSwitchTheme}
88+
variant="outline"
89+
className="relative size-10 overflow-hidden rounded-full p-0 shadow"
90+
>
91+
<div
92+
className={cn(
93+
'absolute grid grid-rows-[repeat(2,minmax(0,2.5rem))] w-full justify-center items-center transition-all duration-500',
94+
isDarkMode ? 'top-0' : '-top-10',
95+
isDarkMode ? 'bg-slate-800 text-white' : 'bg-white text-orange-400'
96+
)}
97+
>
98+
<MoonIcon size={20} />
99+
<SunIcon size={20} />
100+
</div>
101+
</Button>
102+
</motion.div>
103+
104+
<motion.div
105+
variants={{
106+
hidden: { opacity: 0, y: 12 },
107+
visible: { opacity: 1, y: 0 },
108+
exit: { opacity: 0, y: 12 }
109+
}}
110+
transition={{ duration: 0.1 }}
111+
>
112+
<Button
113+
onClick={handleOpenOptionsPage}
114+
variant="outline"
115+
className="pointer-events-auto size-10 rounded-full p-0 shadow"
116+
>
117+
<SettingsIcon size={20} />
118+
</Button>
119+
</motion.div>
120+
</motion.div>
121+
)}
122+
</AnimatePresence>
123+
<Button
124+
onClick={handleToggleApp}
125+
onContextMenu={handleToggleMenu}
126+
className="relative z-10 size-10 rounded-full p-0 text-xs shadow"
127+
>
84128
{children}
85129
</Button>
86130
</div>

src/app/content/views/Main/index.tsx

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import PromptItem from '../../components/PromptItem'
77
import UserInfoDomain from '@/domain/UserInfo'
88
import RoomDomain, { MessageType } from '@/domain/Room'
99
import MessageListDomain from '@/domain/MessageList'
10+
import BlurFade from '@/components/magicui/blur-fade'
1011

1112
const Main: FC = () => {
1213
const send = useRemeshSend()
@@ -38,21 +39,24 @@ const Main: FC = () => {
3839
<MessageList>
3940
{messageList.map((message, index) =>
4041
message.type === MessageType.Normal ? (
41-
<MessageItem
42-
key={message.id}
43-
data={message}
44-
like={message.like}
45-
hate={message.hate}
46-
index={index}
47-
onLikeChange={() => handleLikeChange(message.id)}
48-
onHateChange={() => handleHateChange(message.id)}
49-
></MessageItem>
42+
<BlurFade key={message.id} duration={0.1} yOffset={0}>
43+
<MessageItem
44+
key={message.id}
45+
data={message}
46+
like={message.like}
47+
hate={message.hate}
48+
onLikeChange={() => handleLikeChange(message.id)}
49+
onHateChange={() => handleHateChange(message.id)}
50+
></MessageItem>
51+
</BlurFade>
5052
) : (
51-
<PromptItem
52-
key={message.id}
53-
data={message}
54-
className={`${index === 0 ? 'pt-4' : ''} ${index === messageList.length - 1 ? 'pb-4' : ''}`}
55-
></PromptItem>
53+
<BlurFade key={message.id} duration={0.1} yOffset={0}>
54+
<PromptItem
55+
key={message.id}
56+
data={message}
57+
className={`${index === 0 ? 'pt-4' : ''} ${index === messageList.length - 1 ? 'pb-4' : ''}`}
58+
></PromptItem>
59+
</BlurFade>
5660
)
5761
)}
5862
</MessageList>

src/app/content/views/Setup/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ const Setup: FC = () => {
9696
return (
9797
<div className="absolute inset-0 z-50 flex rounded-xl bg-black/10 shadow-2xl backdrop-blur-sm">
9898
<div className="m-auto flex flex-col items-center justify-center gap-y-8 pb-40 drop-shadow-lg">
99-
<BlurFade key={userInfo?.avatar} delay={0.1} inView>
99+
<BlurFade key={userInfo?.avatar} inView>
100100
<Avatar className="size-24 cursor-pointer border-4 border-white ">
101101
<AvatarImage src={userInfo?.avatar} alt="avatar" />
102102
<AvatarFallback>

src/app/options/components/ProfileForm.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { RefreshCcwIcon } from 'lucide-react'
1616
import { MAX_AVATAR_SIZE } from '@/constants/config'
1717
import ToastDomain from '@/domain/Toast'
1818
import BlurFade from '@/components/magicui/blur-fade'
19+
import debounce from './../../../utils/debounce'
1920

2021
const defaultUserInfo: UserInfo = {
2122
id: nanoid(),
@@ -95,7 +96,7 @@ const ProfileForm = () => {
9596
render={({ field }) => (
9697
<FormItem className="absolute inset-x-1 top-0 mx-auto grid w-fit -translate-y-1/2 justify-items-center">
9798
<FormControl>
98-
<BlurFade key={form.getValues().avatar} delay={0.1}>
99+
<BlurFade key={form.getValues().avatar} duration={0.1}>
99100
<AvatarSelect
100101
compressSize={MAX_AVATAR_SIZE}
101102
onError={handleError}

src/app/options/main.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { RemeshLogger } from 'remesh-logger'
66
import App from './App'
77
import { BrowserSyncStorageImpl } from '@/domain/impls/Storage'
88
import '@/assets/styles/tailwind.css'
9+
910
import { ToastImpl } from '@/domain/impls/Toast'
1011

1112
const store = Remesh.store({

0 commit comments

Comments
 (0)