generated from nhcarrigan/template
feat: add number format config, resource cap, and modal scroll fix
- Add user-configurable number format (suffix/scientific/engineering) - Suffix: K/M/B/T through Dc (1e33), then letter-based a/b/c... indefinitely - Scientific: 1.23e15 style via toExponential - Engineering: exponent always a multiple of 3 (1.23E15) - Stored in ProfileSettings, fetched from profile API on load - Picker UI in EditProfileModal with live examples - Cap all resource accumulation at 1e300 (RESOURCE_CAP constant) - Per-resource FULL badge with tooltip in ResourceBar - Amber notice strip when any resource is at cap - handleClick also respects the cap - Make EditProfileModal scrollable with viewport margin - Flex column layout with sticky header, scrollable form body - Bio textarea preserved as resizable with min-height - Fix ReferenceError: formatNumber not defined in BossPanel/AchievementPanel - Pass formatNumber as prop to BossCard and AchievementCard - Pass formatNumber as parameter to conditionDescription
This commit is contained in:
@@ -10,9 +10,14 @@ import { authMiddleware } from "../middleware/auth.js";
|
||||
|
||||
export const profileRouter = new Hono();
|
||||
|
||||
const VALID_NUMBER_FORMATS = new Set(["suffix", "scientific", "engineering"]);
|
||||
|
||||
const parseProfileSettings = (raw: unknown): ProfileSettings => {
|
||||
if (raw !== null && typeof raw === "object" && !Array.isArray(raw)) {
|
||||
const obj = raw as Record<string, unknown>;
|
||||
const numberFormat = VALID_NUMBER_FORMATS.has(obj.numberFormat as string)
|
||||
? (obj.numberFormat as ProfileSettings["numberFormat"])
|
||||
: "suffix";
|
||||
return {
|
||||
showTotalGold: obj.showTotalGold !== false,
|
||||
showTotalClicks: obj.showTotalClicks !== false,
|
||||
@@ -22,6 +27,7 @@ const parseProfileSettings = (raw: unknown): ProfileSettings => {
|
||||
showQuestsCompleted: obj.showQuestsCompleted !== false,
|
||||
showAdventurersRecruited: obj.showAdventurersRecruited !== false,
|
||||
showAchievementsUnlocked: obj.showAchievementsUnlocked !== false,
|
||||
numberFormat,
|
||||
};
|
||||
}
|
||||
return { ...DEFAULT_PROFILE_SETTINGS };
|
||||
@@ -73,6 +79,9 @@ profileRouter.put("/", authMiddleware, async (context) => {
|
||||
|
||||
const characterName = (body.characterName ?? "").trim().slice(0, 32);
|
||||
const bio = (body.bio ?? "").trim().slice(0, 200);
|
||||
const numberFormat = VALID_NUMBER_FORMATS.has(body.profileSettings?.numberFormat as string)
|
||||
? (body.profileSettings?.numberFormat as ProfileSettings["numberFormat"])
|
||||
: "suffix";
|
||||
const profileSettings: ProfileSettings = {
|
||||
showTotalGold: body.profileSettings?.showTotalGold !== false,
|
||||
showTotalClicks: body.profileSettings?.showTotalClicks !== false,
|
||||
@@ -82,6 +91,7 @@ profileRouter.put("/", authMiddleware, async (context) => {
|
||||
showQuestsCompleted: body.profileSettings?.showQuestsCompleted !== false,
|
||||
showAdventurersRecruited: body.profileSettings?.showAdventurersRecruited !== false,
|
||||
showAchievementsUnlocked: body.profileSettings?.showAchievementsUnlocked !== false,
|
||||
numberFormat,
|
||||
};
|
||||
|
||||
if (!characterName) {
|
||||
|
||||
Reference in New Issue
Block a user