Skip to content

Commit

Permalink
一键复制诗词
Browse files Browse the repository at this point in the history
  • Loading branch information
meetqy committed Feb 21, 2024
1 parent 4670ff3 commit 360429b
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 9 deletions.
61 changes: 61 additions & 0 deletions src/app/(.)/poem/[id]/components/Copy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
"use client";

import { type Poem, type Author } from "@prisma/client";
import { Check, ClipboardCopy } from "lucide-react";
import { Button } from "~/components/ui/button";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "~/components/ui/popover";
import { MyHost, cn } from "~/utils";

interface Props {
data: Poem & { author: Author };
className?: string;
}

const CopyButton = (props: Props) => {
const { data: poem } = props;

return (
<Popover>
<PopoverTrigger asChild>
<Button
variant={"secondary"}
size={"icon"}
className={cn(props.className)}
onClick={() => {
const text = `<p>${poem.content.replaceAll(
"\n",
"<br/>",
)}</p> <p>—— 《<a href="${MyHost}/poem/${poem.id}"><b>${
poem.title
}</b></a>》${poem.author.dynasty} · <a href="${MyHost}/author/${
poem.author.id
}"><b>${poem.author.name}</b></a></p>`;

const blobHtml = new Blob([text], { type: "text/html" });
const data = [
new ClipboardItem({
["text/html"]: blobHtml,
}),
];

void navigator.clipboard.write(data);
}}
>
<ClipboardCopy className="h-4 w-4" />
</Button>
</PopoverTrigger>
<PopoverContent>
<div className="flex items-center space-x-2">
<Check className="h-4 w-4 text-primary" />
<span>已复制</span>
</div>
</PopoverContent>
</Popover>
);
};

export default CopyButton;
29 changes: 20 additions & 9 deletions src/app/(.)/poem/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { Album, ChevronRight, InfoIcon, TwitterIcon } from "lucide-react";
import {
Album,
ChevronRight,
ClipboardCopy,
InfoIcon,
TwitterIcon,
} from "lucide-react";
import Link from "next/link";
import { notFound } from "next/navigation";
import { HeaderMain } from "~/components/ui/header";
Expand All @@ -11,6 +17,8 @@ import { MyHost, cn } from "~/utils";
import dynamic from "next/dynamic";
import { type Article, type WithContext } from "schema-dts";
import { getPoemTitle } from "./utils";
import { Separator } from "~/components/ui/separator";
import CopyButton from "./components/Copy";

const Twikoo = dynamic(() => import("./components/twikoo"), {
ssr: false,
Expand Down Expand Up @@ -143,7 +151,8 @@ export default async function Page({ params, searchParams }: Props) {
</div>
</HeaderMain>

<article className="py-8 text-center">
{/* 正文 */}
<article className="group relative select-none py-8 text-center">
{/* 标题 */}
<PinYinText
text={poem.title}
Expand Down Expand Up @@ -200,19 +209,20 @@ export default async function Page({ params, searchParams }: Props) {
);
})}
</div>

<CopyButton
data={poem}
className="absolute right-1 top-1 transition-all group-hover:opacity-100 md:opacity-0"
/>
</article>

{/* 标签 */}
<article className="chinese mt-8 px-4">
{poem.tags.length > 0 && (
<div className="mt-12 flex justify-start space-x-2">
<div className="mt-12 flex items-center justify-start space-x-2">
{poem.tags.map((item) => {
return (
<Button
variant={"secondary"}
key={item.id}
className={cn("text-base")}
asChild
>
<Button variant={"secondary"} key={item.id} asChild>
<Link href={`/tag/list/${item.id}?page=1`}>
{item.type === "词牌名" && (
<Album className="mr-1 h-4 w-4 opacity-70" />
Expand All @@ -224,6 +234,7 @@ export default async function Page({ params, searchParams }: Props) {
})}
</div>
)}

<h2 id="#译文" prose-h2="" className="text-left">
译文
</h2>
Expand Down

0 comments on commit 360429b

Please sign in to comment.