- Drop the redundant 'Settings' eyebrow from both Overlay and
Integrations cards; the h3 heading is sufficient
- Change dashboard-grid from auto-fit/minmax to repeat(2, 1fr) so the
two settings cards always split the full width evenly
- Replace large 200x200 icon tiles with compact horizontal nav cards
(icon + title + description, grid-wrapped, responsive)
- Split single Settings card into separate Overlay and Integrations
cards, each with its own Save button and status indicator
- Fix canvas save wiring bug: add missing #save-canvas-btn and
#canvas-status elements that were referenced in JS but absent from HTML
- Remove silent saveCanvasSettings() side-effect from saveScriptSettings()
- Replace window.prompt delete confirmation with inline two-step confirm
flow (Delete button → confirm panel → cancel/confirm)
- Add danger-zone collapsible section with danger-border styling
- Add responsive media queries: topbar stacks on narrow viewports,
nav cards and dashboard grid collapse to single column below 700px
- Remove dead CSS classes (dashboard-action, dashboard-tile,
dashboard-toggle-tile, large-dashboard-tiles, etc.)
- Merge near-duplicate renderAdmins/renderSuggestedAdmins into single
parameterised renderAdminList() helper
- Remove unused addVersionAttributes() call from dashboard route
Fetches NOTIFIED reports on page load and renders an amber warning panel above
the main content. Each notice shows the asset ID, optional resolution note,
date, a link to the admin console, and a dismiss button that transitions the
report to RESOLVED. Panel hides itself when all notices are cleared.
WebSocket subscription refreshes the list live on COPYRIGHT_WARNING messages.
- /report: public three-step page to find a broadcaster, pick an asset, and
submit a DMCA-style claim; uses asset.url fallback for images without previews
- Admin console: flag button opens report modal for the selected asset
- Settings page: sysadmin copyright reports section with status/broadcaster
filters, paginated table, and review modal with action radio buttons
- Footer on index.html links to /report
- Add StringNormalizer.normalize() (trim + toLowerCase ROOT) for username normalization
- Migrate SystemAdministratorService private normalize() to use StringNormalizer.normalize()
- Remove now-unused Locale import from SystemAdministratorService
- Add StringNormalizerTest coverage for new normalize() method
- Add SystemAdministratorServiceTest with 10 unit tests covering all public methods
- Replace JsonSupport inner class (AtomicReference lazy singleton) with simple static final ObjectMapper field
- Replace TODO code-smell comments in TwitchEmoteService, SevenTvEmoteService, and MarketplaceScriptSeedLoader with descriptive Javadoc
- Use normalize() consistently in ChannelDirectoryService.topicFor()
- Extract admin endpoint group (add/remove/list admins, suggestions) into dedicated ChannelAdminApiController
- ChannelApiController reduced from 665 to 520 lines; removes 3 dependency injections
- ChannelDirectoryService: extract resolveOrderForSort() helper from bulk-reorder comparator lambda
- Remove TODO comment from ChannelApiController (partially addressed by this split)
- Add AssetPatch.forOrder() and simplify AssetPatch.fromVisibility() factory
- Replace null-chain AssetPatch constructors in ChannelDirectoryService with forOrder()
- Extract OAuthTokenCipher.buildFromKeys() to deduplicate two fromEnvironment() overloads
- Replace inline upload-size guards in createAsset/createScriptAttachment with enforceUploadLimit()
- Make script attachment content endpoint public for all channels (not just hard-coded 'gasolinebased')
- Extract StringNormalizer.toLowerCaseRoot() utility and use it in ChannelDirectoryService/ChannelSettingsService