Skip to content

Commit

Permalink
feat: sonner
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <i@innei.in>
  • Loading branch information
Innei committed Jul 10, 2023
1 parent 856396d commit fb72500
Show file tree
Hide file tree
Showing 18 changed files with 211 additions and 150 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,12 @@
"react-dom": "18.2.0",
"react-error-boundary": "4.0.10",
"react-intersection-observer": "9.5.2",
"react-toastify": "9.1.3",
"react-tweet": "3.0.2",
"react-wrap-balancer": "1.0.0",
"remove-markdown": "0.5.0",
"shiki": "0.14.3",
"socket.io-client": "4.7.1",
"sonner": "0.6.0",
"tailwind-merge": "1.13.2"
},
"devDependencies": {
Expand Down
27 changes: 13 additions & 14 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions src/app/SonnerContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use client'

import { Toaster } from 'sonner'

import { useIsDark } from '~/hooks/common/use-is-dark'

export const SonnerContainer = () => {
const isDark = useIsDark()
return (
<Toaster
richColors
closeButton
duration={6666}
theme={isDark ? 'dark' : 'light'}
/>
)
}
4 changes: 2 additions & 2 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import '../styles/index.css'

import { Analytics } from '@vercel/analytics/react'
import { cache } from 'react'
import { ToastContainer } from 'react-toastify'
import type { AggregateRoot } from '@mx-space/api-client'
import type { AppConfig } from './config'

Expand All @@ -22,6 +21,7 @@ import { queries } from '~/queries/definition'
import { Providers } from '../providers/root'
import { Analyze } from './analyze'
import { init } from './init'
import { SonnerContainer } from './SonnerContainer'

const { version } = PKG
init()
Expand Down Expand Up @@ -128,8 +128,8 @@ export default async function RootLayout(props: Props) {

<TocAutoScroll />
<Analyze />
<SonnerContainer />
</Providers>
<ToastContainer />
</body>
</html>
<Analytics />
Expand Down
16 changes: 12 additions & 4 deletions src/atoms/owner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const login = async (username?: string, password?: string) => {
if (username && password) {
const user = await apiClient.user.login(username, password).catch((err) => {
console.error(err)
toast('再试试哦', 'error')
toast.error('再试试哦')
throw err
})
if (user) {
Expand All @@ -26,7 +26,7 @@ export const login = async (username?: string, password?: string) => {
jotaiStore.set(isLoggedAtom, true)

await fetchAppUrl()
toast(`欢迎回来,${jotaiStore.get(ownerAtom)?.name}`, 'success')
toast.success(`欢迎回来,${jotaiStore.get(ownerAtom)?.name}`)
}

return true
Expand All @@ -36,7 +36,15 @@ export const login = async (username?: string, password?: string) => {
if (!token) {
return
}
const outdateToast = () => toast('登录身份过期了,再登录一下吧!', 'warning')
const outdateToast = () =>
toast.message('登录身份过期了,再登录一下吧!', {
action: {
label: '登录',
onClick: () => {
window.location.href = '/login'
},
},
})
const validated = await apiClient.user
.checkTokenValid(token)
.then((res) => !!res.ok)
Expand All @@ -55,7 +63,7 @@ export const login = async (username?: string, password?: string) => {

await apiClient.user.proxy.login.put<{ token: string }>().then((res) => {
jotaiStore.set(isLoggedAtom, true)
toast(`欢迎回来,${jotaiStore.get(ownerAtom)?.name}`, 'success')
toast.message(`欢迎回来,${jotaiStore.get(ownerAtom)?.name}`)
setToken(res.token)
})

Expand Down
2 changes: 1 addition & 1 deletion src/components/layout/header/internal/AnimatedLogo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const TapableLogo = () => {
const adminUrl = getAdminUrl()
if (adminUrl) location.href = adminUrl
else {
toast('Admin url not found', 'error')
toast.error('Admin url not found')
}
return
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/code-highlighter/CodeHighlighter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const HighLighter: FC<Props> = (props) => {

const handleCopy = useCallback(() => {
navigator.clipboard.writeText(value)
toast('COPIED!', 'success')
toast.success('COPIED!')
}, [value])

const prevThemeCSS = useRef<ReturnType<typeof loadStyleSheet>>()
Expand Down
1 change: 1 addition & 0 deletions src/components/ui/input/TextArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const TextArea = forwardRef<
'h-full w-full resize-none bg-transparent',
'overflow-auto px-3 py-4',
'text-neutral-900/80 dark:text-slate-100/80',
// 'ring-accent/20 duration-200 focus:border-accent-focus focus:ring-2',
className,
)}
{...rest}
Expand Down
6 changes: 4 additions & 2 deletions src/components/ui/markdown/index.demo.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { useRef } from 'react'
import { ToastContainer } from 'react-toastify'
// import { ToastContainer } from 'react-toastify'
import { ThemeProvider } from 'next-themes'
import type { DocumentComponent } from 'storybook/typings'

import { SonnerContainer } from '~/app/SonnerContainer'

// @ts-expect-error
import customize from './customize.md?raw'
import { Markdown } from './Markdown'
Expand Down Expand Up @@ -31,7 +33,7 @@ export const MarkdownCustomize: DocumentComponent = () => {
/>
</main>

<ToastContainer />
<SonnerContainer />
</ThemeProvider>
</QueryClientProvider>
)
Expand Down
22 changes: 22 additions & 0 deletions src/components/ui/sonner/index.demo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { useEffect } from 'react'
import { toast, Toaster } from 'sonner'

export const Sonner = () => {
useEffect(() => {
requestAnimationFrame(() => {
toast.success('ss', {
action: {
label: 'test',
onClick(event) {
console.log(event)
},
},
})
})
}, [])
return (
<>
<Toaster closeButton richColors />
</>
)
}
4 changes: 2 additions & 2 deletions src/components/widgets/note/NoteActionAside.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ const LikeButton = () => {
control.start('tap', {
repeat: 5,
})
toast('谢谢你!', undefined, {
iconElement: (
toast('谢谢你!', {
icon: (
<m.i
className="icon-[mingcute--heart-fill] text-uk-red-light"
initial={{
Expand Down
2 changes: 1 addition & 1 deletion src/components/widgets/note/NoteHideIfSecret.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const NoteHideIfSecret: Component = ({ children }) => {
const MAX_TIMEOUT = (2 ^ 31) - 1
if (isSecret && timeout && timeout < MAX_TIMEOUT) {
timer = setTimeout(() => {
toast('刷新以查看解锁的文章', 'info', { autoClose: false })
toast.message('刷新以查看解锁的文章', { duration: Infinity })
}, timeout)
}

Expand Down
4 changes: 2 additions & 2 deletions src/components/widgets/post/PostActionAside.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ const LikeButton = () => {
onClick={() => {
handleLike()
control.start('tap')
toast('捕捉一只大佬!', undefined, {
iconElement: (
toast('捕捉一只大佬!', {
icon: (
<m.i
className="text-uk-orange-light"
initial={{
Expand Down
113 changes: 57 additions & 56 deletions src/components/widgets/shared/ToastCard.tsx
Original file line number Diff line number Diff line change
@@ -1,63 +1,64 @@
'use client'
// 'use client'

import { useId } from 'react'
import clsx from 'clsx'
import { m } from 'framer-motion'
import type { FC } from 'react'
import type { ToastProps, TypeOptions } from 'react-toastify/dist/types'
// import { useId } from 'react'
// import clsx from 'clsx'
// import { m } from 'framer-motion'
// import type { FC } from 'react'
// import type { ToastProps, TypeOptions } from 'react-toastify/dist/types'

import { MotionButtonBase } from '../../ui/button'
// import { MotionButtonBase } from '../../ui/button'

const typeMap: Record<TypeOptions, JSX.Element> = {
success: <i className="icon-[mingcute--check-fill] text-uk-green-light" />,
error: <i className="icon-[mingcute--close-fill] text-uk-red-light" />,
info: <i className="icon-[mingcute--information-fill] text-uk-blue-light" />,
warning: <i className="icon-[mingcute--alert-fill] text-uk-orange-light" />,
default: (
<i className="icon-[mingcute--information-fill] text-uk-blue-light" />
),
}
// const typeMap: Record<TypeOptions, JSX.Element> = {
// success: <i className="icon-[mingcute--check-fill] text-uk-green-light" />,
// error: <i className="icon-[mingcute--close-fill] text-uk-red-light" />,
// info: <i className="icon-[mingcute--information-fill] text-uk-blue-light" />,
// warning: <i className="icon-[mingcute--alert-fill] text-uk-orange-light" />,
// default: (
// <i className="icon-[mingcute--information-fill] text-uk-blue-light" />
// ),
// }

export const ToastCard: FC<{
message: string
toastProps?: ToastProps
iconElement?: JSX.Element
closeToast?: () => void
onClick?: () => void
}> = (props) => {
const { iconElement, message, closeToast, onClick } = props
const id = useId()
// export const ToastCard: FC<{
// message: string
// toastProps?: ToastProps
// iconElement?: JSX.Element
// closeToast?: () => void
// onClick?: () => void
// }> = (props) => {
// const { iconElement, message, closeToast, onClick } = props
// const id = useId()

const MotionTag = onClick ? m.button : m.div
// const MotionTag = onClick ? m.button : m.div

return (
<MotionTag
layoutId={id}
layout="position"
className={clsx(
'relative w-full overflow-hidden rounded-xl shadow-md shadow-slate-200 dark:shadow-stone-800',
'my-4 mr-4 px-4 py-5 pr-7',
'bg-slate-50/90 backdrop-blur-sm dark:bg-neutral-900/90',
'border border-slate-100/80 dark:border-neutral-900/80',
'space-x-4',
'flex items-center',
'select-none',
)}
onClick={onClick}
>
{iconElement ?? typeMap[props.toastProps?.type ?? 'default']}
<span>{message}</span>
// return (
// <MotionTag
// layoutId={id}
// layout="position"
// className={clsx(
// 'relative w-full overflow-hidden rounded-xl shadow-md shadow-slate-200 dark:shadow-stone-800',
// 'my-4 mr-4 px-4 py-5 pr-7',
// 'bg-slate-50/90 backdrop-blur-sm dark:bg-neutral-900/90',
// 'border border-slate-100/80 dark:border-neutral-900/80',
// 'space-x-4',
// 'flex items-center',
// 'select-none',
// )}
// onClick={onClick}
// >
// {iconElement ?? typeMap[props.toastProps?.type ?? 'default']}
// <span>{message}</span>

<MotionButtonBase
aria-label="Close toast"
className="absolute bottom-0 right-3 top-0 flex items-center text-sm text-base-content/40 duration-200 hover:text-base-content/80"
onClick={(e) => {
e.stopPropagation()
closeToast?.()
}}
>
<i className="icon-[mingcute--close-fill] p-2" />
</MotionButtonBase>
</MotionTag>
)
}
// <MotionButtonBase
// aria-label="Close toast"
// className="absolute bottom-0 right-3 top-0 flex items-center text-sm text-base-content/40 duration-200 hover:text-base-content/80"
// onClick={(e) => {
// e.stopPropagation()
// closeToast?.()
// }}
// >
// <i className="icon-[mingcute--close-fill] p-2" />
// </MotionButtonBase>
// </MotionTag>
// )
// }
export {}
2 changes: 1 addition & 1 deletion src/components/widgets/subscribe/SubscribeModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export const SubscribeModal: FC<SubscribeModalProps> = ({
Object.keys(types).filter((name) => state.types[name]) as any[],
)

toast('订阅成功,谢谢你!', 'success')
toast.success('订阅成功,谢谢你!')
dispatch({ type: 'reset' })
onConfirm()
}
Expand Down
Loading

1 comment on commit fb72500

@vercel
Copy link

@vercel vercel bot commented on fb72500 Jul 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

shiro – ./

springtide.vercel.app
shiro-innei.vercel.app
innei.in
shiro-git-main-innei.vercel.app

Please sign in to comment.