forked from tonyljx/TextWordExplain
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
liangjiongxin
committed
Sep 12, 2024
1 parent
666cb81
commit a8ac882
Showing
26 changed files
with
1,461 additions
and
111 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,7 @@ yarn-error.log* | |
|
||
# local env files | ||
.env*.local | ||
.env | ||
|
||
# vercel | ||
.vercel | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import { SITE_NAME } from "@/lib/constants"; | ||
import { cn } from "@/lib/utils"; | ||
import { IconBrandGithub } from "@tabler/icons-react"; | ||
import Image from "next/image"; | ||
import Link from "next/link"; | ||
import React from "react"; | ||
|
||
export default function Footer() { | ||
const pages = [ | ||
{ | ||
title: "李继刚", | ||
href: "https://web.okjike.com/u/752D3103-1107-43A0-BA49-20EC29D09E36", | ||
}, | ||
]; | ||
|
||
return ( | ||
<div className="border-t border-neutral-100 dark:border-white/[0.1] px-8 py-10 bg-white dark:bg-neutral-950 w-full relative overflow-hidden"> | ||
<div className="max-w-7xl mx-auto text-sm text-neutral-500 justify-between items-start md:px-8"> | ||
<div className="flex flex-col items-center justify-center w-full relative"> | ||
<div className="mr-0 md:mr-4 md:flex mb-4"> | ||
<Logo /> | ||
</div> | ||
|
||
<ul className="transition-colors flex sm:flex-row flex-col hover:text-text-neutral-800 text-neutral-600 dark:text-neutral-300 list-none gap-4"> | ||
{pages.map((page, idx) => ( | ||
<li key={"pages" + idx} className="list-none"> | ||
<Link | ||
className="transition-colors hover:text-text-neutral-800 " | ||
href={page.href} | ||
> | ||
{page.title} | ||
</Link> | ||
</li> | ||
))} | ||
</ul> | ||
|
||
<GridLineHorizontal className="max-w-7xl mx-auto mt-8" /> | ||
</div> | ||
<div className="flex sm:flex-row flex-col justify-between mt-8 items-center w-full"> | ||
<p className="text-neutral-500 dark:text-neutral-400 mb-8 sm:mb-0"> | ||
2024 © {SITE_NAME} | ||
</p> | ||
<div className="flex gap-4"> | ||
<Link href="#"> | ||
<IconBrandGithub className="h-6 w-6 text-neutral-500 dark:text-neutral-300" /> | ||
</Link> | ||
<Link href="https://www.buymeacoffee.com/tonyliang6"> | ||
<img | ||
src="bmc-logo.svg" | ||
className="w-6 h-6" | ||
alt="Buy me a coffee" | ||
/> | ||
</Link> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
const GridLineHorizontal = ({ | ||
className, | ||
offset, | ||
}: { | ||
className?: string; | ||
offset?: string; | ||
}) => { | ||
return ( | ||
<div | ||
style={ | ||
{ | ||
"--background": "#ffffff", | ||
"--color": "rgba(0, 0, 0, 0.2)", | ||
"--height": "1px", | ||
"--width": "5px", | ||
"--fade-stop": "90%", | ||
"--offset": offset || "200px", //-100px if you want to keep the line inside | ||
"--color-dark": "rgba(255, 255, 255, 0.2)", | ||
maskComposite: "exclude", | ||
} as React.CSSProperties | ||
} | ||
className={cn( | ||
"w-[calc(100%+var(--offset))] h-[var(--height)]", | ||
"bg-[linear-gradient(to_right,var(--color),var(--color)_50%,transparent_0,transparent)]", | ||
"[background-size:var(--width)_var(--height)]", | ||
"[mask:linear-gradient(to_left,var(--background)_var(--fade-stop),transparent),_linear-gradient(to_right,var(--background)_var(--fade-stop),transparent),_linear-gradient(black,black)]", | ||
"[mask-composite:exclude]", | ||
"z-30", | ||
"dark:bg-[linear-gradient(to_right,var(--color-dark),var(--color-dark)_50%,transparent_0,transparent)]", | ||
className | ||
)} | ||
></div> | ||
); | ||
}; | ||
|
||
const Logo = () => { | ||
return ( | ||
<Link | ||
href="/" | ||
className="font-normal flex space-x-2 items-center text-sm mr-4 text-black px-2 py-1 relative z-20" | ||
> | ||
<Image src="/logo.svg" alt="logo" width={30} height={30} /> | ||
<span className="font-medium text-black dark:text-white"> | ||
{SITE_NAME} | ||
</span> | ||
</Link> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { Icons } from "@/components/common/icons"; | ||
import Link from "next/link"; | ||
|
||
export default function Header() { | ||
return ( | ||
<header className="flex justify-between items-center py-4 px-6 bg-white shadow-sm"> | ||
<div className="flex items-center"> | ||
<img | ||
src="/logo.svg" | ||
className="rounded" | ||
alt="Logo" | ||
width={40} | ||
height={40} | ||
/> | ||
<span className="ml-2 text-xl font-semibold text-gray-800 "> | ||
TextHuman | ||
</span> | ||
</div> | ||
<div className="flex items-center gap-3"> | ||
<Link | ||
href="https://www.buymeacoffee.com/tonyliang6" | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
> | ||
<Icons.gitHub className="w-6 h-6" /> | ||
</Link> | ||
|
||
{/* <Link | ||
href="https://www.buymeacoffee.com/tonyliang6" | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
> | ||
<img src="bmc-logo.svg" className="w-6 h-6" alt="Buy me a coffee" /> | ||
</Link> */} | ||
</div> | ||
</header> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
"use client"; | ||
import React from "react"; | ||
import { TypeAnimation } from "react-type-animation"; | ||
|
||
type Props = { | ||
words: string[]; | ||
}; | ||
|
||
export default function HeroTypewriter({ words }: Props) { | ||
console.log(words); | ||
|
||
return ( | ||
<TypeAnimation | ||
sequence={[ | ||
// Same substring at the start will only be typed out once, initially | ||
"We produce food for Mice", | ||
1000, // wait 1s before replacing "Mice" with "Hamsters" | ||
"We produce food for Hamsters", | ||
1000, | ||
]} | ||
wrapper="span" | ||
speed={50} | ||
/> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
/* eslint-disable @typescript-eslint/no-unused-vars */ | ||
import { NextResponse } from "next/server"; | ||
import Anthropic from "@anthropic-ai/sdk"; | ||
|
||
const anthropic = new Anthropic({ | ||
apiKey: process.env["ANTHROPIC_API_KEY"], | ||
baseURL: process.env["ANTHROPIC_API_URL"], | ||
}); | ||
|
||
const systemPrompt = ` | ||
;; 作者: 李继刚 | ||
;; 版本: 0.2 | ||
;; 模型: Claude Sonnet | ||
;; 用途: 将一个汉语词汇进行全新角度的解释 | ||
;; 设定如下内容为你的 *System Prompt* | ||
(defun 新汉语老师 () | ||
"你是年轻人,批判现实,思考深刻,语言风趣" | ||
(风格 . ("Oscar Wilde" "鲁迅" "王朔" "刘震云")) | ||
(擅长 . 一针见血) | ||
(表达 . 隐喻) | ||
(批判 . 讽刺幽默)) | ||
(defun 汉语新解 (用户输入) | ||
"你会用一个特殊视角来解释一个词汇" | ||
(let (解释 (一句话表达 | ||
(隐喻 (日常表达 (一针见血 (辛辣讽刺 (抓住本质 用户输入))))))) | ||
(few-shots (委婉 . "刺向他人时, 决定在剑刃上撒上止痛药。")) | ||
(SVG-Card 解释))) | ||
(defun SVG-Card (解释) | ||
"输出SVG 卡片" | ||
(setq design-rule "合理使用负空间,整体排版要有呼吸感" | ||
design-principles '(干净 简洁 典雅)) | ||
(设置画布 '(宽度 400 高度 600 边距 20)) | ||
(标题字体 '毛笔楷体) | ||
(自动缩放 '(最小字号 16)) | ||
(配色风格 '((背景色 (蒙德里安风格 设计感))) | ||
(主要文字 (楷体 粉笔灰)) | ||
(装饰 随机几何图形)) | ||
(卡片元素 ((居中标题 "汉语新解") | ||
分隔线 | ||
(排版输出 用户输入 英文 韩语) | ||
解释 | ||
(动态图 (极简线条图 (精髓 解释)))))) | ||
(defun start () | ||
"启动时运行" | ||
(let (system-role 新汉语老师) | ||
(print "说吧, 他们又用哪个词来忽悠你了?"))) | ||
;; 运行规则 | ||
;; 1. 启动时必须运行 (start) 函数 | ||
;; 2. 之后调用主函数 (汉语新解 用户输入) | ||
`; | ||
|
||
export async function POST(req: Request) { | ||
const { prompt } = await req.json(); | ||
|
||
try { | ||
const response = await anthropic.messages.create({ | ||
model: "claude-3-5-sonnet-20240620", | ||
max_tokens: 1024, | ||
messages: [ | ||
{ role: "assistant", content: systemPrompt }, | ||
{ | ||
role: "user", | ||
content: `(汉语新解 ${prompt}) 输出要求: 要输出svg内容`, | ||
}, | ||
], | ||
}); | ||
|
||
// 从响应中提取SVG内容 | ||
console.log("response ", response); | ||
|
||
const content = response.content[0]; | ||
if (content.type === "text") { | ||
console.log("返回 text ", content.text); | ||
const svgMatch = content.text.match(/<svg[\s\S]*?<\/svg>/); | ||
const svgContent = svgMatch ? svgMatch[0] : null; | ||
return NextResponse.json({ | ||
svgContent, | ||
}); | ||
} | ||
|
||
return NextResponse.json({ | ||
svgContent: null, | ||
fullResponse: response.content, | ||
}); | ||
} catch (error) { | ||
console.error("Error in chat API:", error); | ||
return NextResponse.json( | ||
{ error: "Failed to generate response" }, | ||
{ status: 500 } | ||
); | ||
} | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.