feat: add mobile font scale setting
New setting in Settings > Styling that scales all fonts on mobile devices (75% / 85% / 100% / 115% / 130%). Applies to day names, dates, tasks, events, and the mobile header date. Also scales the CW/date display in the mobile header via scaleRem(). New DB field: mobileFontScale (Float, default 1.0) v1.38.0
This commit is contained in:
parent
2ad55fe1bd
commit
43169c0bfc
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "my-weekly-todo-list",
|
||||
"version": "1.37.4",
|
||||
"version": "1.38.0",
|
||||
"description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
||||
@ -100,6 +100,7 @@ model User {
|
||||
weekdayFormat String? @default("long")
|
||||
weekdayCase String? @default("capitalize")
|
||||
customWeekdayNames String? @default("")
|
||||
mobileFontScale Float @default(1.0)
|
||||
startDayOffset Int @default(-1)
|
||||
quoteSourceUrls String[] @default([])
|
||||
quoteLanguages String[] @default(["en", "de"])
|
||||
|
||||
@ -96,6 +96,7 @@ export async function GET(request: NextRequest) {
|
||||
lightTheme: true,
|
||||
darkTheme: true,
|
||||
notificationsEnabled: true,
|
||||
mobileFontScale: true,
|
||||
createdAt: true
|
||||
}
|
||||
});
|
||||
@ -138,7 +139,7 @@ export async function PATCH(request: NextRequest) {
|
||||
yearFontFamily, yearFontSize, yearFontWeight, yearColor,
|
||||
showTaskCheckboxes, dayHeaderGap,
|
||||
showCompletedTasks, showLines, startDayOffset, weekdayFormat, weekdayCase, customWeekdayNames, quoteSourceUrls, quoteLanguages,
|
||||
kanbanStages, lightTheme, darkTheme, notificationsEnabled
|
||||
kanbanStages, lightTheme, darkTheme, notificationsEnabled, mobileFontScale
|
||||
} = body;
|
||||
|
||||
const updateData: any = {
|
||||
@ -223,6 +224,7 @@ export async function PATCH(request: NextRequest) {
|
||||
...(lightTheme !== undefined && { lightTheme }),
|
||||
...(darkTheme !== undefined && { darkTheme }),
|
||||
...(notificationsEnabled !== undefined && { notificationsEnabled }),
|
||||
...(mobileFontScale !== undefined && { mobileFontScale: parseFloat(mobileFontScale) || 1.0 }),
|
||||
};
|
||||
if (password && password.trim() !== "") {
|
||||
updateData.passwordHash = await bcrypt.hash(password, 10);
|
||||
@ -316,6 +318,7 @@ export async function PATCH(request: NextRequest) {
|
||||
lightTheme: true,
|
||||
darkTheme: true,
|
||||
notificationsEnabled: true,
|
||||
mobileFontScale: true,
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -4980,10 +4980,11 @@ export default function WeeklyView() {
|
||||
);
|
||||
|
||||
const fontSizeScale = fontSize === "S" ? 0.85 : fontSize === "L" ? 1.15 : 1;
|
||||
const mobileScale = isMobile ? (profile.mobileFontScale || 1.0) : 1.0;
|
||||
const fontVal = (v: string | undefined) => v && v !== "__custom__" ? v : "";
|
||||
const scaleRem = (base: string) => {
|
||||
const num = parseFloat(base);
|
||||
return `${(num * fontSizeScale).toFixed(3)}rem`;
|
||||
return `${(num * fontSizeScale * mobileScale).toFixed(3)}rem`;
|
||||
};
|
||||
const activeTheme = (darkMode ? profile.darkTheme : profile.lightTheme) as Record<string, string> | null;
|
||||
|
||||
@ -5548,7 +5549,7 @@ export default function WeeklyView() {
|
||||
{/* Center: Date display (tap to jump to date) */}
|
||||
<button className="mobile-header-date" onClick={() => setShowDatePicker(true)} style={{
|
||||
fontFamily: profile.cwFontFamily || "Inter",
|
||||
fontSize: profile.cwFontSize || "0.9rem",
|
||||
fontSize: scaleRem(profile.cwFontSize || "0.9rem"),
|
||||
fontWeight: Number(profile.cwFontWeight || "700"),
|
||||
color: adjustColorForDarkMode(profile.cwColor || (darkMode ? "#e5e7eb" : "#333333"), darkMode),
|
||||
}}>
|
||||
@ -11914,6 +11915,55 @@ function SettingsSidebar({
|
||||
<div
|
||||
style={{ display: "flex", flexDirection: "column", gap: "24px" }}
|
||||
>
|
||||
{/* Mobile Font Scale */}
|
||||
<div style={{
|
||||
background: "var(--weekly-settings-item-bg)",
|
||||
padding: "12px",
|
||||
borderRadius: "8px",
|
||||
}}>
|
||||
<label style={{
|
||||
display: "block", fontSize: "0.85rem", fontWeight: 600,
|
||||
marginBottom: "8px", color: "var(--weekly-settings-label)",
|
||||
}}>
|
||||
{(profile.language || "en") === "de" ? "Mobile Schriftgröße" : "Mobile Font Scale"}
|
||||
</label>
|
||||
<div style={{ display: "flex", gap: "6px" }}>
|
||||
{[
|
||||
{ label: "75%", value: 0.75 },
|
||||
{ label: "85%", value: 0.85 },
|
||||
{ label: "100%", value: 1.0 },
|
||||
{ label: "115%", value: 1.15 },
|
||||
{ label: "130%", value: 1.3 },
|
||||
].map(opt => (
|
||||
<button
|
||||
key={opt.value}
|
||||
onClick={() => {
|
||||
setProfile({ ...profile, mobileFontScale: opt.value });
|
||||
saveSetting("mobileFontScale", opt.value);
|
||||
}}
|
||||
style={{
|
||||
flex: 1, padding: "6px 4px", borderRadius: "6px",
|
||||
border: (profile.mobileFontScale || 1.0) === opt.value
|
||||
? "2px solid var(--weekly-teal, #0ea5e9)"
|
||||
: "1px solid var(--weekly-border, #ddd)",
|
||||
background: (profile.mobileFontScale || 1.0) === opt.value
|
||||
? "var(--weekly-teal, #0ea5e9)" : "transparent",
|
||||
color: (profile.mobileFontScale || 1.0) === opt.value
|
||||
? "white" : "var(--weekly-text)",
|
||||
fontSize: "0.8rem", fontWeight: 600, cursor: "pointer",
|
||||
}}
|
||||
>
|
||||
{opt.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<span style={{ fontSize: "0.7rem", color: "var(--weekly-text-light)", marginTop: "4px", display: "block" }}>
|
||||
{(profile.language || "en") === "de"
|
||||
? "Skaliert alle Schriften auf Mobilgeräten (< 768px)"
|
||||
: "Scales all fonts on mobile devices (< 768px)"}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Typography Settings */}
|
||||
<div
|
||||
style={{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user