diff --git a/README.md b/README.md index faeae86..42ddb80 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ You can also build and run Sucker as a Docker container with `docker compose bui ### Changelog -- 2.5: Fixed extraction for users whose Janitor sends a request without the blank turn before the first message — sucker read the parts by position rather than by role, so for them it read the wrong ones and errored. Now resolved by role, with tests for both shapes. +- 2.5: Unread dot on the Changelog button. Fixed extraction for users whose Janitor sends a request without the blank turn before the first message — sucker read the parts by position rather than by role, so for them it read the wrong ones and errored. Now resolved by role, with tests for both shapes. - 2.4: CSS editor for Janitor profiles. New banner links to the live-preview editor at tools.from-avalon.com/janitor-profile-maker. - 2.3: ECHO. Put ECHO: anywhere in a message and sucker repeats whatever comes after it in the reply — for triggering char-side script and lorebook keywords. - 2.2: Added support for directly inputting webp file names or character image links when creating PNG character cards diff --git a/src/app/api/proxy/route.ts b/src/app/api/proxy/route.ts index 77607ed..5f76ed9 100644 --- a/src/app/api/proxy/route.ts +++ b/src/app/api/proxy/route.ts @@ -121,16 +121,16 @@ function removePersonaTags(content: string): string { function extractCardData(messages: Message[]): ExtractedCard { const { system, greeting, nameSlot } = selectMessageSlots(messages); - if (!system?.content) { + if (!system) { throw new Error("No system message: this request carries no character card."); } - if (!greeting?.content) { + if (!greeting) { throw new Error("No assistant message: this chat has no greeting to read."); } - const first_mes = greeting.content.replace(/{user}/g, "{{user}}"); + const first_mes = greeting.replace(/{user}/g, "{{user}}"); - const nameContent = nameSlot?.content ?? ""; + const nameContent = nameSlot ?? ""; // If the name slot is actually a token, ignore it for naming purposes const tokenInNameSlot = parseConversationToken(nameContent); const lastColonIndex = nameContent.lastIndexOf(": "); @@ -140,7 +140,7 @@ function extractCardData(messages: Message[]): ExtractedCard { ? nameContent.substring(lastColonIndex + 2).trim() : ""; - let content = system.content.replace(/{user}/g, "{{user}}"); + let content = system.replace(/{user}/g, "{{user}}"); const inferredName = extractPersonaName(content); content = removePersonaTags(content); diff --git a/src/app/page.tsx b/src/app/page.tsx index 6781b56..e4d2b69 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -67,9 +67,36 @@ interface Card { initialVersion?: CardDataV2; } +/** Bumped once per release; the changelog dot keys off it. */ +const APP_VERSION = "2.5"; +const CHANGELOG_SEEN_KEY = "sucker:changelog-seen"; + export default function Home() { const [cards, setCards] = useState([]); + // The changelog dot. Starts hidden so the server and the first client render + // agree; the effect below turns it on for anyone who has not opened the + // dialog since this version shipped. + const [changelogSeen, setChangelogSeen] = useState(true); const [dialogOpen, setDialogOpen] = useState(false); + useEffect(() => { + try { + setChangelogSeen(localStorage.getItem(CHANGELOG_SEEN_KEY) === APP_VERSION); + } catch { + // Private mode or blocked storage: just leave the dot off. + } + }, []); + + /** Open the changelog and remember that this version has been read. */ + const openChangelog = () => { + setChangelogDialogOpen(true); + setChangelogSeen(true); + try { + localStorage.setItem(CHANGELOG_SEEN_KEY, APP_VERSION); + } catch { + // Nothing to do; the dot simply comes back next time. + } + }; + const [selectedCardIndex, setSelectedCardIndex] = useState( null ); @@ -373,15 +400,21 @@ export default function Home() { {/* Row 1: Title on left, Hamburger on right */}
-

Sucker v2.5

+

Sucker v{APP_VERSION}

New: a live CSS editor for your profile.

- @@ -391,8 +424,11 @@ export default function Home() { setMirrorsDialogOpen(true)}> Mirrors - setChangelogDialogOpen(true)}> + Changelog + {!changelogSeen && ( + + )} @@ -411,7 +447,7 @@ export default function Home() { {/* Desktop Layout */}
-

Sucker v2.5

+

Sucker v{APP_VERSION}

New: a live CSS editor for your profile.

@@ -430,10 +466,17 @@ export default function Home() { Mirrors