refactor(characters): drive shared UI from active character

This commit is contained in:
2026-07-17 19:33:59 +08:00
parent 8bb1e21886
commit 7bd5defa5e
42 changed files with 335 additions and 118 deletions
@@ -17,21 +17,23 @@ describe("splash Tailwind components", () => {
});
it("renders SplashBackground with Tailwind fill image classes", () => {
const html = renderToStaticMarkup(<SplashBackground />);
const html = renderToStaticMarkup(
<SplashBackground src="/images/cover/maya.png" />,
);
expect(html).toContain("absolute");
expect(html).toContain("bg-sidebar-background");
expect(html).toContain("object-cover");
expect(html).toContain("%2Fimages%2Fcover%2Felio.png");
expect(html).toContain("%2Fimages%2Fcover%2Fmaya.png");
});
it("renders SplashContent with Tailwind typography classes", () => {
const html = renderToStaticMarkup(<SplashContent />);
const html = renderToStaticMarkup(<SplashContent characterName="Maya" />);
expect(html).toContain("flex flex-col gap-md");
expect(html).toContain("font-(family-name:--font-athelas)");
expect(html).toContain("whitespace-pre-line");
expect(html).toContain("Welcome to my secret hideout");
expect(html).toContain("Welcome to Maya");
});
it("renders SplashButton as an always-ready action", () => {
@@ -11,9 +11,9 @@
import Image from "next/image";
export function SplashBackground({
src = "/images/cover/elio.png",
src,
}: {
src?: string;
src: string;
}) {
return (
<div className="absolute inset-0 z-0 overflow-hidden bg-sidebar-background">
+2 -2
View File
@@ -4,11 +4,11 @@
const APOSTROPHE = "'";
export function SplashContent() {
export function SplashContent({ characterName }: { characterName: string }) {
return (
<div className="z-2 flex flex-col gap-md">
<h1 className="m-0 whitespace-pre-line text-left font-(family-name:--font-athelas) text-[clamp(28px,7.8vw,30px)] font-bold italic leading-[1.28] text-white">
Welcome to my secret hideout~
Welcome to {characterName}{APOSTROPHE}s secret hideout~
{"\n"}It{APOSTROPHE}s just the two of us now.
{"\n"}Feel free to whisper your
{"\n"}little secrets.
@@ -26,6 +26,7 @@ import { useSplashLatestMessage } from "../use-splash-latest-message";
function LatestMessageHarness() {
const state = useSplashLatestMessage({
characterId: "character_maya",
hasInitialized: true,
isAuthLoading: false,
loginStatus: "facebook",
@@ -64,5 +65,9 @@ describe("useSplashLatestMessage hydration", () => {
expect(hydrationErrors).toEqual([]);
expect(container.textContent).toBe("Loading");
expect(mocks.loadLatestMessage).toHaveBeenCalledOnce();
expect(mocks.loadLatestMessage).toHaveBeenCalledWith({
cache: mocks.cache,
characterId: "character_maya",
});
});
});
@@ -3,7 +3,6 @@
import { useEffect, useState } from "react";
import type { LoginStatus } from "@/data/schemas/auth";
import { DEFAULT_CHARACTER_ID } from "@/data/constants/character";
import { useHasHydrated } from "@/hooks/use-has-hydrated";
import { loadSplashLatestMessagePreview } from "@/lib/chat/splash_latest_message";
import { useSplashLatestMessageCache } from "@/providers/splash-latest-message-provider";
@@ -13,7 +12,7 @@ import { Result } from "@/utils/result";
const log = new Logger("SplashLatestMessage");
export interface UseSplashLatestMessageInput {
characterId?: string;
characterId: string;
hasInitialized: boolean;
isAuthLoading: boolean;
loginStatus: LoginStatus;
@@ -31,7 +30,7 @@ interface SplashLatestMessageState {
}
export function useSplashLatestMessage({
characterId = DEFAULT_CHARACTER_ID,
characterId,
hasInitialized,
isAuthLoading,
loginStatus,
+2 -2
View File
@@ -65,12 +65,12 @@ export function SplashScreen() {
isLoading={latestMessage.isLoading}
onOpenChat={handleStartChat}
/>
<SplashContent />
<SplashContent characterName={character.shortName} />
<div className={styles.buttonArea}>
<SplashButton onStartChat={handleStartChat} />
</div>
<p className={styles.bottom}>
{character.displayName}, {character.copy.splashRelationship}
{character.displayName}, {character.tagline}
<br />
24/7 online | Chat | Companion | Heal | Sweet moments
</p>