From e031643cd595954621bb4979396fbf37214c013b Mon Sep 17 00:00:00 2001 From: Lucas 'Paperboy' Rose-Winters Date: Fri, 24 Oct 2025 18:55:38 +1100 Subject: [PATCH] feat(dashboard): implement column-aware defaultSize for optimal 3-4 col widget layout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PROBLEM: - Reset/auto-layout placed userInfo at 1x1, mood at [1,0] blocking expansion - Expansion pass couldn't grow userInfo to 2x1 because mood already occupied column 1 - Result: 1x1 userInfo, 1x1 mood, empty space at [2,0] in 3-col layout ROOT CAUSE: - Static defaultSize 1x1 → placement happens first - Expansion happens second, but mood blocks userInfo horizontal growth SOLUTION - Column-aware defaultSize: 1. userInfoWidget.js: defaultSize now function of columns - Mobile (≤2 col): { w: 1, h: 1 } (compact, mood beside it) - Desktop (3-4 col): { w: 2, h: 1 } (starts at target size) 2. dashboardManager.js: resetWidgetSizesToDefault() supports function defaultSize - Calls defaultSize(columns) if function, otherwise uses static object - Same pattern as maxAutoSize support 3. widgetRegistry.js: Updated validation to accept function defaultSize - Skip validation for functions (can't validate until runtime) 4. dashboardManager.js: Reordered userWidgetOrder - mood(2) before stats(3) so mood sits beside userInfo in top row RESULT (3-4 columns): - userInfo starts at 2x1, placed at [0,0] - mood placed at [2,0] (beside 2-wide userInfo) - stats placed at [0,1] and expands to 3x? (full width below) - No expansion blocking, no wasted space MOBILE FIXES (from previous commits): - Stats widget: padding-bottom 0.5rem (was 0.3rem, prevent Arousal clipping) - Refresh button: Show with Dashboard v2 (#rpg-dashboard-container selector) - Mood text: 0.6rem font-size (improve readability) AFFECTED: - userInfoWidget.js: defaultSize + maxAutoSize column-aware functions - dashboardManager.js: resetWidgetSizesToDefault, userWidgetOrder - widgetRegistry.js: Validation allows function defaultSize - userStatsWidget.js: maxAutoSize column-aware (previous commit) - style.css: Stats padding fix 0.5rem --- src/systems/dashboard/dashboardManager.js | 19 ++++++++++++++----- src/systems/dashboard/widgetRegistry.js | 5 ++++- .../dashboard/widgets/userInfoWidget.js | 12 +++++++++--- style.css | 2 +- 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/systems/dashboard/dashboardManager.js b/src/systems/dashboard/dashboardManager.js index f1e0390..e3c8842 100644 --- a/src/systems/dashboard/dashboardManager.js +++ b/src/systems/dashboard/dashboardManager.js @@ -804,9 +804,9 @@ export class DashboardManager { // Specific widget type ordering within user category const userWidgetOrder = { - 'userInfo': 1, // Name/level at top - 'userStats': 2, // Health/energy bars - 'userMood': 3, // Mood + 'userInfo': 1, // Name/level at top-left + 'userMood': 2, // Mood at top-right (before stats so it sits beside userInfo) + 'userStats': 3, // Health/energy bars (after mood, goes below userInfo+mood) 'userAttributes': 4 // STR/DEX/etc }; @@ -1231,8 +1231,17 @@ export class DashboardManager { const definition = this.registry.get(widget.type); if (definition && definition.defaultSize) { const oldSize = `${widget.w}x${widget.h}`; - widget.w = definition.defaultSize.w; - widget.h = definition.defaultSize.h; + + // Support defaultSize as function (column-aware sizing) + let defaultSize; + if (typeof definition.defaultSize === 'function') { + defaultSize = definition.defaultSize(this.gridEngine.columns); + } else { + defaultSize = definition.defaultSize; + } + + widget.w = defaultSize.w; + widget.h = defaultSize.h; const newSize = `${widget.w}x${widget.h}`; if (oldSize !== newSize) { console.log(`[DashboardManager] Reset ${widget.type} from ${oldSize} to ${newSize}`); diff --git a/src/systems/dashboard/widgetRegistry.js b/src/systems/dashboard/widgetRegistry.js index 8af7a09..8ce572c 100644 --- a/src/systems/dashboard/widgetRegistry.js +++ b/src/systems/dashboard/widgetRegistry.js @@ -87,7 +87,10 @@ export class WidgetRegistry { if (!definition.minSize.w || !definition.minSize.h) { throw new Error('[WidgetRegistry] Widget minSize must have w and h properties'); } - if (!definition.defaultSize.w || !definition.defaultSize.h) { + // defaultSize can be a function (column-aware) or static object + if (typeof definition.defaultSize === 'function') { + // If function, we can't validate until runtime, skip validation + } else if (!definition.defaultSize.w || !definition.defaultSize.h) { throw new Error('[WidgetRegistry] Widget defaultSize must have w and h properties'); } diff --git a/src/systems/dashboard/widgets/userInfoWidget.js b/src/systems/dashboard/widgets/userInfoWidget.js index 59dfd00..8b12a7d 100644 --- a/src/systems/dashboard/widgets/userInfoWidget.js +++ b/src/systems/dashboard/widgets/userInfoWidget.js @@ -38,13 +38,19 @@ export function registerUserInfoWidget(registry, dependencies) { description: 'User avatar, name, and level display', category: 'user', minSize: { w: 1, h: 1 }, - defaultSize: { w: 1, h: 1 }, // Start compact (1x1), expansion will grow it based on columns - // Column-aware max size: mobile (2-col) stays 1x1, desktop (3-4 col) expands vertically to 1x2 + // Column-aware default size: start at 2x1 in desktop so mood doesn't block expansion + defaultSize: (columns) => { + if (columns <= 2) { + return { w: 1, h: 1 }; // Mobile: compact 1x1 + } + return { w: 2, h: 1 }; // Desktop: 2x1 from the start + }, + // Column-aware max size: same as defaultSize to prevent further expansion maxAutoSize: (columns) => { if (columns <= 2) { return { w: 1, h: 1 }; // Mobile: stay compact to allow mood widget beside it } - return { w: 1, h: 2 }; // Desktop: expand vertically, mood fits top-right + return { w: 2, h: 1 }; // Desktop: 2x1, mood sits in top-right }, requiresSchema: false, diff --git a/style.css b/style.css index fe5f7bb..66d67dd 100644 --- a/style.css +++ b/style.css @@ -4323,7 +4323,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld { /* User Stats Widget - add bottom padding to prevent last bar (Arousal) from being clipped */ .rpg-widget .rpg-stats-grid { - padding-bottom: 0.3rem !important; + padding-bottom: 0.5rem !important; } /* Mood Widget - increase conditions text size for readability */