Skip to content

Commit 71d6aa5

Browse files
committed
Use Sonner instead of Toast
1 parent abdefd7 commit 71d6aa5

File tree

14 files changed

+263
-472
lines changed

14 files changed

+263
-472
lines changed

.github/workflows/docker.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,4 @@ jobs:
4242
tags: ${{ steps.meta.outputs.tags }}
4343
labels: ${{ steps.meta.outputs.labels }}
4444
cache-from: type=gha
45-
cache-to: type=gha,mode=max
45+
cache-to: type=gha,mode=max

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@
1010
## ⚠️ 注意
1111

1212
- **❗接收到的邮件内容仅能保留10天**
13-
- **❗随机生成的邮箱地址任何人都可以使用,请勿用于注册重要账号**
13+
- **❗随机生成的邮箱地址任何人都可以使用,请勿用于注册重要账号**

app/layout.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import type { Metadata, Viewport } from "next";
22
import "./globals.css";
33
import React from "react";
4-
import { Toaster } from "@/components/ui/toaster";
4+
import { Toaster } from "@/components/ui/sonner";
5+
import { Analytics } from "@vercel/analytics/react";
56

67
export const metadata: Metadata = {
78
title: "临时邮箱 - 匿名的一次性邮箱",
@@ -37,7 +38,8 @@ export default function RootLayout({
3738
<html lang="zh">
3839
<body>
3940
{children}
40-
<Toaster />
41+
<Toaster richColors position="top-right" />
42+
{process.env.VERCEL && <Analytics />}
4143
</body>
4244
</html>
4345
);

components/actions.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { useConfig } from "@/lib/store/config";
1010
import { Skeleton } from "@/components/ui/skeleton";
1111
import { randomMail } from "@/lib/utils";
1212
import { emitter, mittKey } from "@/lib/mitt";
13+
import { toast } from "sonner";
1314

1415
function Actions() {
1516
const config = useConfig();
@@ -28,6 +29,7 @@ function Actions() {
2829
setEdited(false);
2930
if (config.mail != mail || config.domain != domain) {
3031
config.update(mail, domain);
32+
toast.success("已修改至新地址 " + mail + domain);
3133
setTimeout(() => emitter.emit(mittKey.REFRESH));
3234
}
3335
}
@@ -37,10 +39,15 @@ function Actions() {
3739
setMail(random);
3840
config.update(random, domain);
3941
setTimeout(() => emitter.emit(mittKey.REFRESH));
42+
toast.success("已随机至新地址 " + random + domain);
4043
}
4144

4245
function onMailChange(e: React.ChangeEvent<HTMLInputElement>) {
43-
setMail(e.currentTarget.value.replace(/[^a-zA-Z0-9-_.]/g, ""));
46+
const value = e.currentTarget.value.replace(/[^a-zA-Z0-9-_.]/g, "");
47+
if (value.length > 64) {
48+
return;
49+
}
50+
setMail(value);
4451
}
4552

4653
function onKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {

components/mail-detail.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ import {
77
DialogTitle,
88
DialogTrigger,
99
} from "@/components/ui/dialog";
10-
import { useToast } from "@/components/ui/use-toast";
1110
import { Envelope } from "@/lib/types";
1211
import { fmtLocaleTime } from "@/lib/utils";
12+
import { toast } from "sonner";
1313

1414
const loadingHtml = `<style>.lds-ellipsis{display:inline-block;position:relative;width:76px;height:50px}.lds-ellipsis div{position:absolute;top:20px;width:13px;height:13px;border-radius:50%;animation-timing-function:cubic-bezier(0,1,1,0)}.lds-ellipsis div:nth-child(1){left:8px;animation:lds-ellipsis1 0.6s infinite}.lds-ellipsis div:nth-child(2){left:8px;animation:lds-ellipsis2 0.6s infinite}.lds-ellipsis div:nth-child(3){left:32px;animation:lds-ellipsis2 0.6s infinite}.lds-ellipsis div:nth-child(4){left:56px;animation:lds-ellipsis3 0.6s infinite}@keyframes lds-ellipsis1{0%{transform:scale(0)}100%{transform:scale(1)}}@keyframes lds-ellipsis3{0%{transform:scale(1)}100%{transform:scale(0)}}@keyframes lds-ellipsis2{0%{transform:translate(0,0)}100%{transform:translate(24px,0)}}</style>
1515
<div class="h-full flex justify-center items-center">
@@ -23,7 +23,6 @@ function MailDetail({
2323
children: ReactNode;
2424
envelope: Envelope;
2525
}) {
26-
const { toast } = useToast();
2726
const [controller, setController] = useState<AbortController>();
2827
const [html, setHtml] = useState<{ __html: string }>();
2928

@@ -48,10 +47,11 @@ function MailDetail({
4847
setHtml(res);
4948
} catch (e: any) {
5049
if (e.message !== "The user aborted a request.") {
51-
toast({ description: e.message, variant: "destructive" });
50+
toast.error(e.message);
5251
}
5352
}
5453
}
54+
5555
return (
5656
<Dialog onOpenChange={onOpenChange}>
5757
<DialogTrigger asChild>{children}</DialogTrigger>

components/mail-refresh.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,15 @@ import { RefreshCw } from "lucide-react";
55
import { REFRESH_SECONDS } from "@/lib/constant";
66
import { useEnvelope } from "@/lib/store/envelope";
77
import { useConfig } from "@/lib/store/config";
8-
import { useToast } from "@/components/ui/use-toast";
98
import { emitter, mittKey } from "@/lib/mitt";
9+
import { toast } from "sonner";
1010

1111
function MailRefresh() {
1212
const [seconds, setSeconds] = useState(0);
1313
const [timer, setTimer] = useState<NodeJS.Timeout>();
1414
const [loading, setLoading] = useState(false);
1515
const setEnvelope = useEnvelope((state) => state.setEnvelope);
1616
const mailAddress = useConfig((state) => state.mail + state.domain);
17-
const { toast } = useToast();
1817

1918
useEffect(() => {
2019
emitter.on(mittKey.REFRESH, onRefresh);
@@ -51,7 +50,7 @@ function MailRefresh() {
5150
}
5251
setEnvelope(res);
5352
} catch (e: any) {
54-
toast({ description: e.message, variant: "destructive" });
53+
toast.error(e.message);
5554
} finally {
5655
setSeconds((seconds) => (seconds === 0 ? 1 : 0));
5756
setLoading(false);

components/mail-title.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@ import { Skeleton } from "@/components/ui/skeleton";
55
import { Button } from "@/components/ui/button";
66
import { ClipboardCopy } from "lucide-react";
77
import { useConfig } from "@/lib/store/config";
8-
import { useToast } from "@/components/ui/use-toast";
8+
import { toast } from "sonner";
99

1010
function MailTitle() {
1111
const config = useConfig();
12-
const { toast } = useToast();
1312

1413
function onCopy() {
1514
navigator.clipboard
1615
.writeText(config.mail + config.domain)
17-
.then(() => toast({ description: "已拷贝至剪切板" }))
18-
.catch((e) =>
19-
toast({ variant: "destructive", description: `出错啦: ${e.message}` }),
20-
);
16+
.then(() =>
17+
toast.success("已拷贝至剪切板 " + config.mail + config.domain),
18+
)
19+
.catch((e) => toast.error(`出错啦: ${e.message}`));
2120
}
21+
2222
return (
2323
<div className="flex items-center gap-1">
2424
<Mounted fallback={<Skeleton className="h-7 w-40" />}>

components/ui/skeleton.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { cn } from "@/lib/utils"
1+
import { cn } from "@/lib/utils";
22

33
function Skeleton({
44
className,
@@ -9,7 +9,7 @@ function Skeleton({
99
className={cn("animate-pulse rounded-md bg-primary/10", className)}
1010
{...props}
1111
/>
12-
)
12+
);
1313
}
1414

15-
export { Skeleton }
15+
export { Skeleton };

components/ui/sonner.tsx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"use client";
2+
3+
import { useTheme } from "next-themes";
4+
import { Toaster as Sonner } from "sonner";
5+
6+
type ToasterProps = React.ComponentProps<typeof Sonner>;
7+
8+
const Toaster = ({ ...props }: ToasterProps) => {
9+
const { theme = "system" } = useTheme();
10+
11+
return (
12+
<Sonner
13+
theme={theme as ToasterProps["theme"]}
14+
className="toaster group"
15+
toastOptions={{
16+
classNames: {
17+
toast:
18+
"group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg",
19+
description: "group-[.toast]:text-muted-foreground",
20+
actionButton:
21+
"group-[.toast]:bg-primary group-[.toast]:text-primary-foreground",
22+
cancelButton:
23+
"group-[.toast]:bg-muted group-[.toast]:text-muted-foreground",
24+
},
25+
}}
26+
{...props}
27+
/>
28+
);
29+
};
30+
31+
export { Toaster };

components/ui/toast.tsx

Lines changed: 0 additions & 127 deletions
This file was deleted.

0 commit comments

Comments
 (0)