Commit Graph

26 Commits

Author SHA1 Message Date
Lucas 'Paperboy' Rose-Winters 95f4ae1848 feat(dashboard): add Recent Events widget for v2 system
- Add registerRecentEventsWidget() in infoBoxWidgets.js
- Implement notebook-style UI with rings, bullet points, and editable events
- Support max 3 events with + placeholders for new entries
- Parse 'Recent Events: event1, event2, event3' format from infoBox
- Register widget in dashboardIntegration.js
- Add to default layout Scene tab (row 4-5, below location)
- Integrate with tracker system:
  - Add to WIDGET_TO_TAB_MAP (maps to tab-scene)
  - Add to shouldWidgetBeRemoved() rules
  - Add to detectConfigChanges() for re-addition support
- Completes v2 widget migration - all tracker features now have widgets
2025-11-02 16:21:56 +11:00
Lucas 'Paperboy' Rose-Winters 339413a6fa feat(dashboard): implement reactive tracker-dashboard integration
Replaced surface-level "disabled" messages with true reactive integration.
When tracker editor saves config changes, dashboard now automatically
updates without page reload - removing disabled widgets and refreshing
remaining ones with new field names/settings.

**Event-Based Architecture:**
- trackerEditor.js dispatches 'rpg:trackerConfigChanged' custom event
- dashboardManager.js subscribes to event and reacts to changes
- Decoupled, extensible, browser-native event system

**Dashboard Reactive Methods:**
- onTrackerConfigChanged(config): Main handler coordinating refresh flow
- removeDisabledWidgets(config): Removes widgets with disabled fields
  - Cleans up DOM, drag/resize handlers, state
  - Removes from tab.widgets arrays
- shouldWidgetBeRemoved(type, config): Decision logic per widget type
  - calendar → remove if date disabled
  - weather → remove if weather disabled
  - temperature → remove if temperature disabled
  - clock → remove if time disabled
  - location → remove if location disabled
  - userStats → remove only if ALL stats disabled
  - presentCharacters → remove if thoughts disabled
- refreshAllWidgets(): Re-renders all remaining widgets with new config

**Widget Auto-Removal Flow:**
1. User disables field in tracker editor
2. Clicks "Save & Apply"
3. Event fires → dashboard receives notification
4. Disabled widgets removed from all tabs
5. Affected tabs auto-layout to fill space
6. Remaining widgets re-render with new config
7. Layout saved automatically

**Removed Surface-Level Bandaid:**
- Deleted checkFieldEnabled() from infoBoxWidgets.js (-36 lines)
- Removed all checkFieldEnabled() calls from widget renders (-25 lines)
- Removed empty state message from userStatsWidget.js (-8 lines)
- Removed tracker settings link handler (-7 lines)
- Widgets no longer show "⚠️ Field disabled" messages
- Dashboard handles removal elegantly instead

**Result:**
True reactive integration. Disable "Arousal" → instantly disappears from
all userStats widgets. Disable "Date" → calendar widget removed and tab
auto-layouts. Rename "Health" to "HP" → updates instantly everywhere.
All changes happen immediately without page reload.

Files modified:
- src/systems/dashboard/dashboardManager.js (+129 lines)
- src/systems/ui/trackerEditor.js (+11 lines)
- src/systems/dashboard/widgets/infoBoxWidgets.js (-67 lines)
- src/systems/dashboard/widgets/userStatsWidget.js (-21 lines)
2025-11-02 10:35:35 +11:00
Lucas 'Paperboy' Rose-Winters d3c1f0a137 feat(dashboard): integrate tracker editor with widget system
Implemented hierarchical customization where trackerConfig controls content
(fields, names, AI instructions) and dashboard controls layout (positioning,
tabs, widget instances). Both systems now work together instead of conflicting.

**Widget Integration:**
- userStatsWidget: Respects trackerConfig for stat names and enable/disable
- userStatsWidget: Supports per-widget stat filtering via config.visibleStats
- userStatsWidget: Dynamically generates config options from trackerConfig
- infoBoxWidgets: All widgets (calendar, weather, temperature, clock, location)
  check trackerConfig.infoBox.widgets.*.enabled before rendering
- Widgets show "disabled" state with link to Tracker Settings when field disabled

**Dashboard UI:**
- Added Tracker Settings button to dashboard header (sliders icon)
- Button opens tracker editor modal for global field configuration
- Button positioned next to Edit Layout for clear separation of concerns

**Tracker Editor:**
- Added help text explaining relationship with dashboard system
- Help text clarifies: Tracker Settings = content, Edit Layout = positioning
- Styled with info banner at top of modal

**Migration:**
- Enhanced migrateV1ToV2Dashboard() to respect trackerConfig
- Removes userStats widget if all stats disabled in trackerConfig
- Removes presentCharacters widget if thoughts disabled in trackerConfig
- Ensures smooth upgrade path from v1.x

**CSS:**
- Added .rpg-editor-help styling for tracker editor help banner
- Added .rpg-widget-empty-state for disabled widget messaging
- Info-style banner with icon and clear typography

**Result:**
Two-level customization system:
1. Tracker Settings (global): What fields exist, their names, AI instructions
2. Edit Layout (local): Where widgets appear, per-widget overrides

Files modified:
- src/systems/dashboard/widgets/userStatsWidget.js (+75 lines)
- src/systems/dashboard/widgets/infoBoxWidgets.js (+67 lines)
- src/systems/dashboard/dashboardIntegration.js (+15 lines)
- src/systems/dashboard/dashboardTemplate.html (+4 lines)
- src/systems/dashboard/defaultLayout.js (+22 lines)
- template.html (+6 lines)
- style.css (+58 lines)
2025-11-02 10:23:36 +11:00
Lucas 'Paperboy' Rose-Winters f6ba2642f7 fix(dashboard): quest widget auto-arrange tab placement
Fixed auto-arrange placing quest widget into wrong tab.

Problem:
- Quest widget had category: 'scene' but needs dedicated tab
- Auto-arrange only created Status/Scene/Social/Inventory tabs
- Quest widget got grouped with scene widgets
- No 'quests' category existed in the system

Solution:
1. Changed quest widget category from 'scene' to 'quests'
2. Added 'quests' to category groups in distributeWidgetsByCategory()
3. Added Quests tab creation in auto-arrange logic
4. Updated category sort order to include 'quests' (order 5)

Changes:
- questsWidget.js: category: 'quests' (line 396)
- dashboardManager.js: Added 'quests' to groups object (line 870)
- dashboardManager.js: Added Quests tab creation (lines 942-954)
- dashboardManager.js: Updated categoryOrder to include 'quests': 5 (line 983)

Result:
- Auto-arrange now creates dedicated Quests tab 
- Quest widget correctly placed in Quests tab 
- Matches default layout structure 
- Clean separation of scene info vs quests 
2025-10-30 08:44:33 +11:00
Lucas 'Paperboy' Rose-Winters 9f92c4af87 feat(dashboard): add quest widget + fix 4-tab header layout
Quest Widget Integration:
- Created questsWidget.js with Main/Optional quest sub-tabs
- Added dedicated Quests tab (4th tab after Inventory)
- Registered quest widget in dashboardIntegration.js
- Widget features: inline editing, add/remove quests, contenteditable
- Fixed tab switching to use inline re-rendering (not full widget render)

Header Layout Fixes (4+ Tabs):
- Changed header flex-wrap from wrap to nowrap (prevents button wrapping)
- Added icon-only mode for 4+ tabs (disables hover expansion)
- Tab count detection in renderTabs() adds rpg-tabs-icon-only class
- Prevents layout breaking when tabs expand on hover

Technical Details:
- Quest widget follows inventory widget pattern (sub-tabs, per-instance state)
- Split event handlers: attachQuestHandlers (tabs) + attachQuestContentHandlers (buttons)
- Tab switching updates innerHTML inline and re-attaches content handlers
- Default size: 2w × 5h, category: 'scene'

Benefits:
- Quest tracking fully integrated with Dashboard v2 drag/drop
- No header wrapping issues with 4 tabs
- Cleaner icon-only UX when space is constrained
- Horizontal scrolling handles overflow gracefully
2025-10-30 08:40:46 +11:00
Lucas 'Paperboy' Rose-Winters 7628bb84c1 feat(dashboard): replace emojis with Font Awesome, add theme support, and styled dialogs
This commit implements three major improvements to the dashboard system:

1. **Font Awesome Icons for Tabs**
   - Replace emoji tab icons (📊, 🌍, 🎒) with Font Awesome classes
   - Update defaultLayout.js with fa-solid icon classes
   - Add automatic migration for existing saved dashboards with emoji icons
   - Implement migrateEmojiIcons() to convert old emoji icons on load
   - Update fallback icons throughout the system

2. **Custom Theme Support for Dashboard**
   - Replace all --SmartTheme* variables with --rpg-* variables
   - Ensure custom themes (sci-fi, fantasy, cyberpunk) apply to dashboard
   - Update CSS for tabs, buttons, dropdowns, modals, and widget cards
   - Dashboard now respects extension themes instead of main SillyTavern theme

3. **Styled Confirmation Dialogs**
   - Create confirmDialog.js with showConfirmDialog() and showAlertDialog()
   - Support three variants: danger (red), warning (yellow), info (blue)
   - Add keyboard navigation (Enter/Escape) and accessibility features
   - Replace all native confirm() and alert() calls with styled dialogs
   - Add confirmation dialog modal to dashboardTemplate.html

Files Modified:
- src/systems/dashboard/confirmDialog.js (NEW)
- src/systems/dashboard/dashboardManager.js
- src/systems/dashboard/defaultLayout.js
- src/systems/dashboard/tabManager.js
- src/systems/dashboard/dashboardIntegration.js
- src/systems/dashboard/editModeManager.js
- src/systems/dashboard/widgets/inventoryWidget.js
- src/systems/dashboard/dashboardTemplate.html
- style.css
2025-10-27 20:41:36 +11:00
Lucas 'Paperboy' Rose-Winters 45c5853dcb feat(dashboard): improve mobile inventory UX and fix desktop viewport overflow
Mobile Inventory Improvements:
- Add icon-based sub-tabs (user/box/building) with responsive labels
- Desktop shows icon + label, mobile shows icon-only for compact layout
- Add proper scroll containers for inventory content with flex layout
- Increase touch drag delay from 150ms to 500ms to prevent accidental widget moves during scrolling

Widget Content Fixes:
- Add max-height constraint to .rpg-widget to prevent grid cell overflow
- Add flex properties (flex: 1, min-height: 0, overflow: auto) to all widget content
- Ensures content scrolls internally instead of expanding widget bounds
- Fix .rpg-inventory-widget to use flex properties instead of height: 100%

Layout Fixes:
- Change characters widget default size from 2x3 to 2x2 for better viewport fit
- Remove excess spacing from dashboard container (gap: 0.75rem)
- Remove vertical padding from dashboard header
- Eliminates desktop scrollbar caused by cumulative spacing

All widgets now fit properly within viewport on both desktop and mobile.
2025-10-27 10:18:07 +11:00
Lucas 'Paperboy' Rose-Winters 04bb52ed71 feat(dashboard): improve mood widget readability with balanced two-line layout
- Increase conditions font size from 0.45rem to 0.6rem (33% larger)
- Reduce mood emoji size from 1rem to 0.9rem for better proportion
- Add font-weight: 600 to mood for better hierarchy
- Improve line-height from 1 to 1.2 for readability
- Reduce -webkit-line-clamp from 3 to 2 lines for conditions
- Add slight opacity (0.9) to conditions for visual separation
- Update onResize scaling to maintain balanced proportions (1.4rem / 0.9rem for larger widgets)
- Increase mobile conditions size to 0.7rem with 1.3 line-height

Result: Conditions text is now much more readable while maintaining good visual balance
with the mood emoji in the compact 1x1 widget.
2025-10-26 21:23:11 +11:00
Lucas 'Paperboy' Rose-Winters 6af499b07a fix(dashboard): resolve presentCharacters widget styling and auto-layout issues
- Remove double left border accent on character cards by hiding inner border when inside widget container
- Increase maxAutoSize width from 3 to 4 columns to support large displays
- Fix viewport height calculation to use visible area instead of scrollable container height
- Change auto-layout boundary check from > to >= to prevent widgets extending beyond viewport
- Add Done button for cleaner edit mode exit UX
- Wire up Done button event listener in dashboardIntegration
2025-10-26 14:52:02 +11:00
Lucas 'Paperboy' Rose-Winters 8317471922 fix(dashboard): improve edit mode UX and remove redundant weather subtitle
- Disable contenteditable fields in edit widget mode to prevent keyboard popup
- Re-enable content editing when exiting edit mode
- Change button tooltip from 'Toggle Edit Mode' to 'Toggle Edit Widget Mode' for clarity
- Remove redundant 'WEATHER' subtitle from weather widget (only show single editable field)
- Prevents layout shift on mobile when keyboard appears during widget arrangement
2025-10-26 10:29:55 +11:00
Lucas 'Paperboy' Rose-Winters e031643cd5 feat(dashboard): implement column-aware defaultSize for optimal 3-4 col widget layout
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
2025-10-24 18:55:38 +11:00
Lucas 'Paperboy' Rose-Winters ac5bd22e55 feat(dashboard): optimize 3-4 column desktop layout + fix mobile widget issues
DESKTOP LAYOUT OPTIMIZATION (3-4 columns):
- userInfo: Changed maxAutoSize from 2x1 to 1x2 (expands vertically)
- userStats: Changed to column-aware function, 3x3 in 3-4 col (full width horizontal)
- Layout: userInfo 1x2 (left) + mood 1x1 (top-right), stats 3x3 below (full width)
- Result: Better horizontal space utilization, less vertical stacking

MOBILE FIXES (Dashboard v2):
1. Refresh button visibility
   - Added #rpg-dashboard-container to CSS selector
   - Now shows with Dashboard v2, not just old panel UI

2. Stats widget Arousal bar clipping
   - Added padding-bottom: 0.5rem to .rpg-stats-grid
   - Prevents last stat bar from being cut off

3. Mood conditions text too small
   - Increased from 0.45rem to 0.6rem with line-height 1.2
   - "Focused, Awakening Qi" now readable under emoji

AFFECTED:
- userInfoWidget.js: maxAutoSize 1x2 for desktop vertical expansion
- userStatsWidget.js: Column-aware maxAutoSize function (2x2 mobile, 3x3 desktop)
- style.css: Mobile refresh visibility, stats padding, mood text size
2025-10-24 16:36:18 +11:00
Lucas 'Paperboy' Rose-Winters 4994c09563 feat(dashboard): implement column-aware widget sizing for optimal mobile/desktop layouts
PROBLEM:
- Mobile (2-col): userInfo defaulted to 2x1 (full width), pushed mood to row 2
- After mobile CSS fixes, 1x1 widgets display perfectly
- Want userInfo 1x1 + mood 1x1 side-by-side in top row on mobile
- Desktop (3-4 col): userInfo should still expand to 2x1 for better space usage

SOLUTION:
- gridEngine: Support maxAutoSize as function (receives column count)
- userInfoWidget:
  - Changed defaultSize from 2x1 to 1x1 (starts compact)
  - Changed maxAutoSize to column-aware function:
    * 2 columns (mobile): maxAutoSize 1x1 (stays compact)
    * 3-4 columns (desktop): maxAutoSize 2x1 (can expand)

BEHAVIOR:
- Auto-layout resets widgets to defaultSize (1x1)
- Expansion pass grows widgets up to maxAutoSize based on available space
- Mobile: userInfo stays 1x1, mood can fit beside it (row 0: [userInfo][mood])
- Desktop: userInfo can expand to 2x1 if space available

AFFECTED:
- gridEngine.js: getWidgetMaxSize() now calls maxAutoSize(columns) if function
- userInfoWidget.js: Column-aware maxAutoSize, compact 1x1 defaultSize
2025-10-24 15:50:55 +11:00
Lucas 'Paperboy' Rose-Winters 0d179d22fc fix(mood): reduce font sizes to fit emoji and conditions in 1x1 widget
Problem: Mood widget at 1x1 was cutting off subtext, only showing emoji
and main text (e.g., "🧘 Focused") but hiding conditions below.

Changes:
- Reduced emoji from 1.2rem → 1rem at 1x1 size
- Reduced conditions text from 0.55rem → 0.45rem
- Tightened spacing (gap: 0.1rem, padding: 0.25rem)
- Set line-height: 1 to minimize vertical space usage
- Allow up to 3 lines of conditions text with -webkit-line-clamp
- Added responsive scaling: larger sizes (2x2+) use bigger fonts

Now fits emoji, main text, and subtext comfortably in 1x1 grid cell.
2025-10-24 11:52:35 +11:00
Lucas 'Paperboy' Rose-Winters eb4ac57dae fix(avatars): use proper getThumbnailUrl API to eliminate 404 errors
Root cause: Widgets were using getUserAvatar() which returns bare
filenames like 'user-default.png'. These were being used directly as
image src URLs, causing 404 errors like /user-default.png.

Solution: Use getAvatarUrl() dependency which calls getThumbnailUrl()
to convert filenames to proper URLs like /thumbnail?type=persona&file=...

Changes:
- userInfoWidget.js: Use getAvatarUrl('persona', rawAvatar) instead of
  raw avatar validation
- sillytavern.js: Simplify updatePersonaAvatar() to trust
  getSafeThumbnailUrl() which already calls getThumbnailUrl()

This eliminates 404 errors on initial render and when switching tabs.
2025-10-24 00:26:51 +11:00
Lucas 'Paperboy' Rose-Winters f0f04297f7 fix(userInfo): fix avatar 404 errors and improve layout/scaling
**Avatar 404 Fix:**
- Add fallback to getUserAvatar() call to use FALLBACK_AVATAR_DATA_URI when user avatar is missing
- Prevents 404 errors on app startup or when no character is selected

**Layout & Space Utilization Improvements:**
- Implement flexible hybrid layout system:
  - 1 column (1x1): Centered large avatar (3rem) with text below
  - 2+ columns (2x1+): Side-by-side (avatar 2.5rem left, text right)
- Replace rigid horizontal layout with adaptive container
- Add layout classes: rpg-layout-vertical, rpg-layout-horizontal
- Trigger onResize on initial render for correct layout

**Better Styling:**
- Increase avatar size: 2.5rem-3rem (was 1.2rem)
- Increase font sizes: 0.9rem name, 0.85rem level (was 0.75rem)
- Improve text hierarchy with proper containers
- Add proper spacing and alignment for both layouts
- Remove awkward vertical stacking of "Name | LVL 1"
- Text now stacks cleanly: "Name" on one line, "LVL X" on another

The widget now uses space efficiently, displays a prominent avatar,
and adapts intelligently to different widget sizes.
2025-10-23 22:18:02 +11:00
Lucas 'Paperboy' Rose-Winters 3dd7b017a6 feat(dashboard): implement smart widget scaling and improved auto-layout
- Add resetWidgetSizesToDefault() to reset all widgets to default sizes before auto-arrange/reset
- Implement continuous expansion algorithm that fills available space up to maxAutoSize limits
- Add visible height detection to prevent widgets expanding beyond viewport (no forced scroll)
- Update all widget defaultSize and maxAutoSize for optimal 1x1 compact layouts
  - Info widgets (calendar, weather, temp, clock): 1x1 default, 1x2 max
  - Location: 2x2 max (was 3x3)
  - Characters: 3x5 max, moved to 'scene' category (eliminates Social tab)
  - User Info: 2x1 max (prevents expansion)
  - User Mood: 1x1 default and max (compact top-right placement)
  - User Attributes: 3x5 max (fills bottom space)
  - User Stats: 3x3 max
- Fix CSS scaling for 1x1 widgets
  - Replace viewport-based units with fixed rem values
  - Reduce icon/graphic sizes to fit with visible text
  - Add explicit gaps and padding for consistent spacing
  - Set line-height: 1 to prevent text overflow
- Reorganize default layout
  - Status tab: User Info (2x1) + Mood (1x1 top right) + Stats + Attributes
  - Scene tab: Info widgets (1x1) + Location + Characters (all on one tab)
  - Inventory tab: Full inventory widget

Auto-arrange and reset now properly size widgets to defaults and expand to fill
available space without exceeding visible area.
2025-10-23 22:08:04 +11:00
Lucas 'Paperboy' Rose-Winters 380d717b30 feat(dashboard): implement smart auto-layout with expansion and better defaults
This commit implements 5 major improvements to the dashboard layout system:

**1. Improved Default Layout (defaultLayout.js)**
- Changed from 2 tabs to 3 tabs for better organization:
  - Tab 1 (Status): User widgets only (userInfo, userStats, userMood, userAttributes)
  - Tab 2 (Scene): Scene widgets + characters (calendar, weather, temp, clock, location, presentCharacters)
  - Tab 3 (Inventory): Full inventory widget
- Cleaner separation prevents cramming all widgets on one tab

**2. Widget Max Size Limits (widget definition files)**
- Added maxAutoSize property to all widgets (enforced only during auto-arrange):
  - Info widgets (calendar, weather, temp, clock): { w: 2, h: 3 }
  - Location: { w: 3, h: 3 }
  - presentCharacters: { w: 3, h: 6 } (can expand significantly)
  - Inventory: { w: 3, h: 8 } (full tab)
- Prevents blind expansion while allowing intelligent space filling

**3. Smart Expansion Algorithm (gridEngine.js)**
- Added expansion pass after compaction in autoLayout():
  - Sorts widgets top-to-bottom, left-to-right
  - Tries to expand height first (fills vertical gaps)
  - Then tries to expand width (fills horizontal gaps)
  - Respects maxAutoSize limits from widget definitions
  - Only expands if no collision with other widgets
- Widgets now fill available space instead of staying at default sizes
- Example: presentCharacters expands from 2x3 to 3x6 when space available

**4. Auto-Reflow on Column Change (dashboardManager.js)**
- Modified onColumnsChange callback to auto-layout after column count changes
- When grid transitions (2→3 or 3→2), automatically reflo ws widgets
- Prevents overlap and optimizes for new column count
- User experience: seamless adaptation when console opens/closes

**5. Fixed Grid Height/Scrollbar CSS (style.css)**
- Added flex: 1, overflow-y: auto, min-height: 0 to .rpg-dashboard-grid
- Grid now properly fills available space in dashboard container
- Accounts for bottom buttons (manual update, settings)
- Prevents "fingernail of extra height" that caused scrollbars

**Technical Changes:**
- Passed widget registry to GridEngine for maxAutoSize lookups
- getWidgetMaxSize() helper looks up definitions from registry
- Moved registry initialization before GridEngine construction
- Grid now uses flexbox to fill available vertical space

**User-Facing Improvements:**
- Reset layout creates logical 3-tab structure from the start
- Auto-arrange expands widgets to fill available space intelligently
- Resizing window/console automatically reflows layout
- No more unwanted scrollbars from slight overflow

Fixes cramped layouts, underutilized space, and scrollbar issues.
2025-10-23 20:03:19 +11:00
Lucas 'Paperboy' Rose-Winters 5dd7dcb27b feat(dashboard): improve widget scaling and fix attribute scrollbar
Implement responsive scaling for info widgets and fix sizing issues:

**1. Container-Responsive Info Widgets (style.css)**

**Calendar Widget:**
- Add flexbox layout (height: 100%, flex-direction: column)
- Change font sizes from vw to rem for better scaling
- Calendar day now uses clamp(1.5rem, 2.5rem, 3.5rem) to fill space
- Add flex-shrink: 0 to top/year, flex: 1 to day

**Weather Widget:**
- Add container wrapper (height: 100%, justify-content: space-around)
- Weather icon scales with container: clamp(2rem, 8vh, 4rem)
- Forecast text uses rem instead of vw
- Both elements marked flex-shrink: 0

**Temperature Widget:**
- Container fills height with flexbox centering
- Thermometer scales: clamp(4rem, 60%, 8rem) height
- Tube/bulb use percentages (40% width, 70% height)
- Text value uses rem units

**Clock Widget:**
- Container with space-around layout
- Clock scales with container: clamp(3rem, 60%, 6rem)
- Clock hands use percentages of clock size
- Time text uses rem units

**Location Widget:**
- Container flexbox with column layout
- Map background uses flex: 1 (was fixed 1.875rem)
- Map marker scales: clamp(1.5rem, 4vh, 3rem)
- Location text uses rem units

**2. Fix Attributes Widget Scrollbar (style.css)**
- Line 966: Change grid-auto-rows: 1fr to grid-auto-rows: minmax(0, 1fr)
- Allows rows to shrink below natural size to fit container
- Prevents overflow when widget manually positioned after auto-arrange

**3. Widget Size Constraints (widget files)**
- userAttributesWidget.js: Change minSize from {w:1, h:2} to {w:2, h:2}
  - Enforces 2x2 minimum as requested
  - Prevents cramped 1-column layout
- infoBoxWidgets.js: Change location minSize from {w:2, h:2} to {w:1, h:2}
  - Allows narrow 1x2 layout for space-constrained dashboards
  - Only widget that didn't fit on desktop screen

**Technical Details:**
- All info widgets now use rem units instead of vw for text
- Flexbox scaling ensures widgets fill their containers beautifully
- Percentage-based sizing for thermometer/clock internal elements
- clamp() used for min/preferred/max sizing across resolutions
- minmax(0, 1fr) fixes classic CSS grid overflow issue

**User-Reported Issues Fixed:**
 Info widgets scale to fill containers instead of fixed sizes
 Attributes widget no longer shows scrollbar in 2x2 (manual or auto-arranged)
 Location widget works in both 1x2 and 2x2 layouts
 All widgets maintain readability across different panel widths

Related: Dashboard v2, Epic 2, Phase 3.2
2025-10-23 18:33:01 +11:00
Lucas 'Paperboy' Rose-Winters b3a86d4609 feat(dashboard): implement smart widget collision and category-aware layout
Complete dashboard v2 improvements for better UX and visual consistency:

**1. Push-Aside Drag/Drop (dragDrop.js)**
- Replace swap/revert logic with intelligent reflow algorithm
- When widgets collide on drag, automatically push overlapping widgets down
- All affected widgets repositioned after reflow completes
- Eliminates widget overlap issues

**2. Unified Widget Styling (style.css)**
- Add consistent .rpg-widget container styling for all widgets
- Background: rgba(0,0,0,0.2) for visual separation
- Border-left: 3px highlight for category identification
- Box-shadow and border-radius for depth and polish
- Maintain individual widget decorative styles

**3. Logical Default Layout (defaultLayout.js)**
- Reorganize widgets into semantic clusters with clear comments:
  - USER CLUSTER (top): userInfo → userStats → userMood + userAttributes
  - SCENE CLUSTER (middle): calendar + weather → temp + clock → location
  - SOCIAL CLUSTER (bottom): presentCharacters
- userInfo widget now at top (y=0) as expected
- All positions use rem units for responsive scaling

**4. Category-Aware Auto-Layout (dashboardManager.js)**
- Implement sortWidgetsByCategory() with priority ordering:
  user → scene → social → inventory
- Within user category, specific ordering:
  userInfo → userStats → userMood → userAttributes
- Add preserveOrder option to gridEngine.autoLayout()
- Auto-arrange now uses logical grouping instead of random bin-packing

**5. Multi-Tab Auto-Distribution (dashboardManager.js)**
- Add estimateLayoutHeight() to detect when content exceeds threshold
- Implement distributeWidgetsByCategory() for automatic tab creation:
  - "Status" tab: user + scene widgets
  - "Social" tab: social widgets (if any)
  - "Inventory" tab: inventory widgets (if any)
- Each tab gets category-aware auto-layout
- 80rem height threshold for single-tab limit

**6. Widget Category Metadata (widgets/)**
- Add category field to all widget definitions:
  - userInfo, userStats, userMood, userAttributes: 'user'
  - calendar, weather, temperature, clock, location: 'scene'
  - presentCharacters: 'social'
  - inventory: 'inventory'

**7. Integration Improvements (dashboardIntegration.js)**
- Set default layout on initialization for reset functionality
- Add reset layout button to dashboard header
- Wire up reset button event handler

**8. Core State Management (index.js)**
- Add getInfoBoxData() and setInfoBoxData() to state API
- Ensure info box data persists across sessions

**Technical Details:**
- Rem units throughout for 1080p→4K→mobile responsive scaling
- Reflow algorithm leverages existing gridEngine collision detection
- Category-aware sorting preserves logical relationships
- Multi-tab distribution prevents single-page scroll fatigue
- All changes maintain backwards compatibility with existing layouts

Fixes dashboard issues after rem unit conversion introduced massive positioning bugs.
Users reported widgets overlapping on drag, visual inconsistency, and random auto-arrange behavior.

Related: Epic 2 (Dashboard v2), Phase 3.2
2025-10-23 18:06:44 +11:00
Lucas 'Paperboy' Rose-Winters aeb3ad1b9b feat(dashboard): split user
Stats widget into 4 modular widgets

- Create userInfoWidget (avatar, name, level)
- Refactor userStatsWidget (stats bars only with smart sizing)
- Create userMoodWidget (mood emoji, conditions)
- Create userAttributesWidget (STR/DEX/CON/INT/WIS/CHA)
- Add category field to widgets for auto-layout grouping
- Register all new modular widgets in dashboardIntegration.js

All widgets include getOptimalSize() for smart content-aware auto-layout.
Part of Phase 1 & 3.1 of dashboard modularization plan.
2025-10-23 15:48:02 +11:00
Lucas 'Paperboy' Rose-Winters 122bb3194a feat(dashboard): add auto-layout button with smart widget packing
Implements intelligent auto-layout system that efficiently arranges widgets to maximize space usage while respecting panel width constraints.

**Key Features:**
- Smart packing algorithm that sorts by widget area and finds optimal positions
- Respects responsive column count (2-4 columns based on panel width)
- Prefers full-width widgets when possible to eliminate gaps
- Fallback to narrower widths for better vertical packing
- Maintains minimum widget sizes

**Implementation:**
- GridEngine.autoLayout() - Core packing algorithm with collision detection
- DashboardManager.autoLayoutWidgets() - High-level API that re-renders after layout
- Auto-Arrange button in dashboard header (uses fa-table-cells-large icon)
- Event handler wired to call autoLayoutWidgets with preferFullWidth=true

**Algorithm Strategy:**
1. Sort widgets by area (largest first) for efficient packing
2. For each widget, try full-width placement first
3. Find first available position using row-by-row scan
4. If position is too far down, try narrower widths
5. Mark cells as occupied to prevent overlaps

**Testing Notes:**
- Works with current responsive column system (2-4 columns)
- Respects minimum sizes and column constraints
- Re-renders all widgets after repositioning
- Auto-saves layout changes

Part of Epic 2: Dashboard Widget Library
2025-10-23 14:00:00 +11:00
Lucas 'Paperboy' Rose-Winters 1f4bebc7ad feat(dashboard): implement Inventory Widget (Task 2.4)
- Comprehensive inventory management with 3 sub-tabs (On Person/Stored/Assets)
- List/Grid view modes per sub-tab with toggle buttons
- Storage locations with add/remove/collapse functionality
- Full CRUD operations for items (add/edit/remove)
- Inline forms for adding items and locations with Enter/Escape support
- Per-widget instance state management for tabs and view modes
- Import parseItems/serializeItems utilities for data handling
- Import sanitizeItemName/sanitizeLocationName for security
- Vanilla JS implementation, no jQuery dependencies
- All 4 core widgets now complete
2025-10-23 11:08:05 +11:00
Lucas 'Paperboy' Rose-Winters e9371ef46b feat(dashboard): implement Present Characters Widget (Task 2.3)
- Create character cards with avatars, traits, and relationships
- Fuzzy name matching for avatar lookup (handles parentheticals, titles)
- Editable emoji, name, traits, and relationship badges
- Relationship badges: Enemy ⚔️, Neutral ⚖️, Friend , Lover ❤️
- Configurable card layout (grid/list/compact)
- Placeholder card shown when no data available
- Vanilla JS implementation, no jQuery dependencies
2025-10-23 11:02:23 +11:00
Lucas 'Paperboy' Rose-Winters 2b5c214451 feat: Task 2.2 complete - 5 modular Info Box widgets
Created modular, independently draggable Info Box widgets:

1. Calendar Widget (2x2):
   - Date/weekday/month/year display
   - Abbreviated display with full edit
   - Editable date components

2. Weather Widget (3x2):
   - Weather emoji + forecast text
   - Fully editable emoji and text

3. Temperature Widget (2x2):
   - Animated thermometer visualization
   - Color-coded (blue < 10°C, green < 25°C, red ≥ 25°C)
   - Editable temperature value

4. Clock Widget (2x2):
   - Analog clock with hour/minute hands
   - Real-time hand positioning based on time
   - Editable time display

5. Location Widget (6x2):
   - Map background with marker
   - Editable location text
   - Responsive width

All widgets:
- Share common infoBox data source
- Parse mixed emoji/text formats
- Handle missing data gracefully
- Update shared data on edit
- Vanilla JS (no jQuery)
- Mobile-friendly editable fields

Epic 2 progress: 2/4 core widget groups complete
Total widgets created: 6 (1 User Stats + 5 Info Box widgets)
2025-10-23 10:52:02 +11:00
Lucas 'Paperboy' Rose-Winters f9c483d848 feat: Phase 1 complete + Task 2.1 User Stats Widget
Phase 1 Foundation:
- DashboardManager: Complete orchestrator for all Epic 1 systems (572 lines)
- WidgetBase: Common utilities for widget development (498 lines)

Task 2.1 User Stats Widget:
- Extracted and refactored from renderUserStats()
- Clean vanilla JS implementation (408 lines)
- Editable stat values with live updates
- Progress bars with configurable colors
- User portrait, name, and level display
- Classic D&D stats (STR/DEX/CON/INT/WIS/CHA) with +/- buttons
- Fully configurable (show/hide sections, visible stats)
- Mobile-responsive with layout adjustments
- No jQuery dependencies

Dashboard Manager features:
- Widget lifecycle management (add/remove/update)
- Tab coordination with TabManager
- Drag/drop and resize integration
- Edit mode management
- Layout persistence (save/load/export/import)
- Auto-save with debouncing
- Event-driven architecture

Epic 2 progress: 1/4 core widgets complete
2025-10-23 10:47:39 +11:00