feat:10分钟更换一次slogan

This commit is contained in:
肖应宇 2026-04-11 17:05:44 +08:00
parent b55072b0eb
commit 7ebd891258
4 changed files with 123 additions and 2 deletions

View File

@ -48,6 +48,7 @@
"@radix-ui/react-use-controllable-state": "^1.2.2",
"@t3-oss/env-nextjs": "^0.12.0",
"@tanstack/react-query": "^5.90.17",
"@tombcato/smart-ticker": "^1.2.4",
"@types/hast": "^3.0.4",
"@uiw/codemirror-theme-basic": "^4.25.4",
"@uiw/codemirror-theme-monokai": "^4.25.4",

View File

@ -92,6 +92,9 @@ importers:
'@tanstack/react-query':
specifier: ^5.90.17
version: 5.90.20(react@19.2.4)
'@tombcato/smart-ticker':
specifier: ^1.2.4
version: 1.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vue@3.5.28(typescript@5.9.3))
'@types/hast':
specifier: ^3.0.4
version: 3.0.4
@ -2030,6 +2033,9 @@ packages:
resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==}
engines: {node: '>=18'}
'@stackblitz/sdk@1.11.0':
resolution: {integrity: sha512-DFQGANNkEZRzFk1/rDP6TcFdM82ycHE+zfl9C/M/jXlH68jiqHWHFMQURLELoD8koxvu/eW5uhg94NSAZlYrUQ==}
'@standard-schema/spec@1.1.0':
resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
@ -2189,6 +2195,23 @@ packages:
'@tokenlens/models@1.3.0':
resolution: {integrity: sha512-9mx7ZGeewW4ndXAiD7AT1bbCk4OpJeortbjHHyNkgap+pMPPn1chY6R5zqe1ggXIUzZ2l8VOAKfPqOvpcrisJw==}
'@tombcato/smart-ticker@1.2.4':
resolution: {integrity: sha512-AJDoqvcwZ7MqEjkR8teGqkxXFmI0M35k4fdoDjCuTEhVYpryzequtZLO8Zmz2wvKSBKkZ8+LOWbVgBHivsZI9Q==}
peerDependencies:
react: '>=17.0.0'
react-dom: '>=17.0.0'
svelte: '>=4.0.0'
vue: '>=3.0.0'
peerDependenciesMeta:
react:
optional: true
react-dom:
optional: true
svelte:
optional: true
vue:
optional: true
'@ts-morph/common@0.28.1':
resolution: {integrity: sha512-W74iWf7ILp1ZKNYXY5qbddNaml7e9Sedv5lvU1V8lftlitkc9Pq1A+jlH23ltDgWYeZFFEqGCD1Ies9hqu3O+g==}
@ -7783,6 +7806,8 @@ snapshots:
'@sindresorhus/merge-streams@4.0.0': {}
'@stackblitz/sdk@1.11.0': {}
'@standard-schema/spec@1.1.0': {}
'@swc/helpers@0.5.15':
@ -7911,6 +7936,14 @@ snapshots:
dependencies:
'@tokenlens/core': 1.3.0
'@tombcato/smart-ticker@1.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vue@3.5.28(typescript@5.9.3))':
dependencies:
'@stackblitz/sdk': 1.11.0
optionalDependencies:
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
vue: 3.5.28(typescript@5.9.3)
'@ts-morph/common@0.28.1':
dependencies:
minimatch: 10.2.5

View File

@ -0,0 +1,42 @@
[
{
"text": "开工!摸鱼退散🐟💨",
"color": "#FF6B6B"
},
{
"text": "学习搞起,摆烂禁止🙅‍♂️",
"color": "#4ECDC4"
},
{
"text": "卷不动也得动💪",
"color": "#45B7D1"
},
{
"text": "搬砖学习,同步上线🧱",
"color": "#96CEB4"
},
{
"text": "别躺了,搞钱要紧💰",
"color": "#FFA559"
},
{
"text": "今日份努力已上线✨",
"color": "#A78BFA"
},
{
"text": "支棱起来,干活啦🚀",
"color": "#FF9F1C"
},
{
"text": "拒绝摆烂,从我做起😤",
"color": "#2EC4B6"
},
{
"text": "学习人,不犯困😪",
"color": "#E71D36"
},
{
"text": "冲冲冲,别摸鱼🐎",
"color": "#3A86FF"
}
]

View File

@ -40,10 +40,14 @@ import { env } from "@/env";
import { useSelectedSkillListener } from "@/hooks/use-selected-skill-listener";
import { cn } from "@/lib/utils";
import { IframeTestPanel } from "@/components/workspace/iframe-test-panel";
import { Ticker } from "@tombcato/smart-ticker";
import "@tombcato/smart-ticker/style.css";
import motivationSlogans from "./motivation-slogans.json";
export default function ChatPage() {
const { t } = useI18n();
useSpecificChatMode();
const [sloganIndex, setSloganIndex] = useState(0);
const [settings, setSettings] = useLocalSettings();
const { setOpen: setSidebarOpen } = useSidebar();
const router = useRouter();
@ -92,6 +96,35 @@ export default function ChatPage() {
const initializedThreadRef = useRef<string | null>(null);
const { showNotification } = useNotification();
const currentSlogan =
motivationSlogans[sloganIndex % motivationSlogans.length] ?? {
text: "来,一起学习工作吧",
color: "#333333",
};
const tickerCharacterList = useMemo(() => {
const seen = new Set<string>();
const uniqueChars: string[] = [];
for (const slogan of motivationSlogans) {
for (const char of slogan.text) {
if (seen.has(char)) continue;
seen.add(char);
uniqueChars.push(char);
}
}
return uniqueChars.join("");
}, []);
useEffect(() => {
if (motivationSlogans.length <= 1) return;
const timer = window.setInterval(() => {
setSloganIndex((prev) => (prev + 1) % motivationSlogans.length);
}, 10 * 60 * 1000);
return () => window.clearInterval(timer);
}, []);
useEffect(() => {
if (!isNewThread) {
@ -329,10 +362,22 @@ export default function ChatPage() {
</svg>
</Button>
</div>
<div className="flex items-center justify-center overflow-hidden text-sm font-bold font-medium whitespace-nowrap text-[#333333]">
<div
className="flex items-center justify-center overflow-hidden text-sm font-bold font-medium whitespace-nowrap text-[#333333]"
style={{
color: currentSlogan.color,
}}
>
{/* threadTitle={title} */}
{title !== "Untitled" && (
<ThreadTitle threadId={threadId} threadTitle={'来,一起学习工作吧'} />
// <ThreadTitle threadId={threadId} threadTitle={'来,一起学习工作吧'} />
<Ticker
value={currentSlogan.text}
duration={800}
easing="easeInOut"
charWidth={1}
characterLists={tickerCharacterList}
/>
)}
</div>
<div className="flex items-center justify-end gap-2 overflow-hidden">