- Fix Vue mode: text widgets (CLIPTextEncode, Prompt LM) had no
[data-testid=widget-layout-field-label], so findRowEl never matched.
Added fallback strategies: bare <label> text match and widget index match.
- Fix Vue mode: flash background pulse was never applied — @keyframes was
defined but no rule bound it to .lm-flash. Replaced with CSS transition
on .lm-flash-host class for value text color fade-in/fade-out.
- Fix Vue mode: -webkit-text-fill-color set by ComfyUI overrode
even with !important. Added -webkit-text-fill-color override to .lm-flash.
- Fix canvas mode: highlight rect was double-offset because onDrawForeground
ctx is pre-translated to node.pos. Removed background rect entirely per
design decision; kept text_color + inline color only.
- Add fade-in (250ms) / fade-out (400ms) for text color in both modes.
Canvas-drawn widgets use rAF color interpolation; DOM widgets use CSS
transition. Fixed hexToRgb to handle 3-digit hex shorthand (#DDD).
- Add hover dismissal to canvas mode via app.canvas.getWidgetAtCursor().
Vue mode already had it via mouseover listener.
- Replace 60fps rAF poll with 100ms setInterval for hover detection.
- Fix batch cleanup closure bug: isDomWidget evaluated per-widget instead
of per-call; fade rAF cancellers tracked per-widget in _lmFadeCancels map.
- Unify flash color from #66B3FF to LM brand accent #4299E0.
- Fix Vue fade-out: keep .lm-flash-host 300ms after removing .lm-flash so
CSS transition persists. Canvas DOM widgets: keep inline transition 300ms
after clearing color.
Sort by Most/Fewest versions first now works when Group by model is off.
- Backend: group items by modelId (respecting version_grouping setting),
count versions per group, sort groups by count, expand groups with
versions sorted by version id descending
- CSS: remove rule that hid the sort option in non-grouped mode
- Tests: add 3 tests covering desc, asc, and same_base variants
When viewing all versions of a model (VLM mode via 'x versions' button):
- Backend always sorts by version ID descending, ignoring current sort_by
- A temporary 'Newest version first' option is injected into the sort
dropdown (removed on exit, not a permanent option)
- The sort dropdown is disabled (greyed out) while VLM is active
- On clearing VLM, the previous sort preference is restored and the
dropdown re-enabled
- Handles stale VLM state (e.g. after page reload with leftover session)
- Covers all three model page types: loras, checkpoints, embeddings
Also fixes review nits:
- Correct i18n call pattern (defaultValue in options object)
- Shared _restoreSortAfterVlm() helper to avoid triple duplication
- group_by_model dedup now counts versions per group and attaches
version_count; respects update_flag_strategy (same_base) by
sub-grouping on base_model
- Card footer shows clickable 'x versions' link instead of version
name when grouped (hides HIGH/LOW badges); clicking triggers
View Local Versions without page reload
- Added 'Local Versions' sort option (versions_count), auto-hidden
when group_by_model is off
- Sort preference is saved/restored separately for normal and
grouped modes
- VLM flow (triggerVlmView, clearCustomFilter) uses resetAndReload()
via API instead of window.location.reload()
- Fixed cache mutation bug: version_count is now set on a shallow
copy, not the cached dict, preventing stale version_count leaking
into VLM responses
- i18n: all 9 locale files translated
Adds a 'Group by Model' toggle entry to the right-click global context
menu for quick access, complementing the existing setting in
Settings → Layout Settings. The menu item shows a checkmark indicator
reflecting the current state and immediately reloads the view on toggle.
Also fixes he.json translation that was mojibake (garbled characters).
Includes:
- Context menu HTML item with check-indicator
- JS toggle logic via settingsManager
- i18n for all 10 locales
- Hebrew translation fix
Store the originating page type alongside VLM data in sessionStorage;
validate it on every page load before applying the filter or showing
the indicator. Stale data is auto-cleaned on mismatch.
This prevents the 'View all local versions' custom filter from leaking
into the checkpoints (or embeddings) page, which caused an empty grid.
Clicking the button closes the modal, writes filter params to sessionStorage,
and reloads the page to show all local versions of the model as individual
cards (bypassing group-by-model dedup). The filter respects the update flag
strategy and the versions-filter-toggle state (same-base vs all versions).
Supporting changes:
- sessionStorage keys vlm_model_id / vlm_model_name / vlm_base_model
- BaseModelApiClient._addModelSpecificParams adds civitai_model_id param
- LoraApiClient calls super._addModelSpecificParams for VLM detection
- LorasControls / CheckpointsControls clearCustomFilter checks VLM first
- PageControls.checkVlmFilter shows customFilterIndicator with label
- Backend parses civitai_model_id, filters before group_by_model dedup
Adds a 'Group by Model' toggle in Layout Settings. When enabled, only the
latest version (highest civitai.id) of each Civitai model is shown as a
single card — older versions sharing the same modelId are hidden.
Backend dedup runs in BaseModelService.get_paginated_data() before
filtering/pagination, ensuring correct paginated results. The setting
is persisted via the existing settings pipeline and passed as a query
parameter to the listing endpoint.
Includes:
- Backend: dedup logic, route param parsing, settings default
- Frontend: API param, SettingsManager wiring, toggle UI
- i18n: translations for all 10 locales
- Tests: unit test covering dedup on/off and standalone items
- Inject #customFilterIndicator DOM in beforeEach (raw template
renderer doesn't process Jinja2 {% include %} tags)
- Fix selector from #customFilterText to .customFilterText
- Replace inline controls+breadcrumb in recipes.html with shared includes
- Add page_id conditionals in controls.html to adapt buttons per page type
- Unify customFilterText selector to class-based in recipes.js
- Add [data-action="find-duplicates"] event listener for unified button
- Fix i18n keys to use recipes-specific translations on recipes page
- save_metadata_updates now trims/lowercases/dedupes tags on write
- ModelFilterSet tag matching is now case-insensitive (both include/exclude)
- Removed redundant .lower() calls in tag_update_service.py
- Replace recipe modal's custom tag display/edit with shared
renderCompactTags/setupTagEditMode from ModelTags and utils
- Remove 300+ lines of duplicated tag display and editing code
- Parameterize setupTagEditMode with saveHandler/onSaved/showSuggestions
options for recipe-specific save flow (updateRecipeMetadata + dirty state)
- Scope all DOM queries in ModelTags.js via options.container / this.closest
to prevent cross-modal element conflicts
- Fix edit button alignment (justify-content: flex-start)
- Fix tag tooltip selector scoping in setupTagTooltip
- Add width: 100% to #recipeTagsContainer for edit container full width
Backend changes:
- Add civitai_api_key to _NO_SYNC_KEYS, return only boolean civitai_api_key_set
- Clean up known template placeholder on load to prevent false positive
Frontend changes:
- Replace type=password with type=text + CSS masking (-webkit-text-security)
- Replace pre-filled input with status display (Configured/Not configured)
- Add inline edit view with Save/Cancel buttons
- Re-add eye toggle via CSS class toggle (not type switching)
- Use CSS transitions for smooth status/edit view switching
This prevents Chromium/Vivaldi password manager from triggering
'save password' prompts when opening the settings modal.
Replace undefined --lora-accent-l/c/h and --lora-warning-l/c/h with
canonical --color-accent-l/c/h and --color-warning-l/c/h from the
design token system. Fix 5 border-color declarations missing oklch()
wrapper, fix var() space syntax error in .group-toggle-btn:hover,
and replace hardcoded green with --color-success token.
- Remove server-side value='...' from password field in settings modal template
so the API key is never baked into the DOM at page load time
- Populate the input dynamically via loadSettingsToUI() when modal opens
- Clear both API key and proxy password fields on modal close to prevent
Firefox from detecting pre-filled password fields on page navigation
- Add 5 new Tabler SVG icons (currency-dollar, brush, user, git-merge, license)
- Implement Set 2 rendering in ModelModal.js (standalone UI) with green/red
permission indicators and preview_tooltip.js (ComfyUI widget)
- Add use_new_license_icons setting (default: true) with toggle in settings UI
- ComfyUI tooltip reads setting directly from preview-url API response to
eliminate race conditions and respect standalone settings changes
- Remove the now-unused separate ComfyUI setting loramanager.license_icon_style
- Add CSS for both standalone (lora-modal.css) and widget (lm_styles.css)
- i18n: translate licenseIcons keys into all 10 supported languages
- Fix test to use classic style explicitly for continued coverage
- New GET /api/lm/downloads/queue/status handler for non-terminal status
transitions (queued -> downloading, downloading -> paused, etc.)
- Queue lifecycle auto-integration in DownloadManager._download_with_semaphore:
downloading -> SQLite update_status('downloading') on semaphore acquire
completed -> complete_download('completed') on success
canceled -> complete_download('canceled') on CancelledError
failed -> complete_download('failed') on Exception
- All queue operations wrapped in try/except to never break the download flow
- Delete static/css/components/keyboard-nav.css entirely
- Remove @import of keyboard-nav.css from style.css
- Remove keyboard-nav-hint divs from controls.html and recipes.html
- Clean up all keyboard.* translation keys from 10 locale files
The actual keyboard scrolling handlers (PageUp/PageDown in infiniteScroll.js
and VirtualScroller.js) are kept as they provide core scroll functionality.
This reverts commit 95bbc669efb1aa0c23b94be6f0a5e7a188f1c019.
The real issue was shields.io GitHub API token pool exhaustion (intermittent),
not the &logo=github parameter. All 3 badges (Discord, Release, Release Date)
were affected at various times due to the same root cause: shields.io
temporarily unable to query GitHub API.
- Remove pin/unpin and auto-hide hover mechanism (isPinned, isHovering,
hoverTimeout, showSidebar/hideSidebar, updateAutoHideState, etc.)
- Remove global show_folder_sidebar setting (SettingsManager,
PageControls, recipes, backend default)
- Simplify sidebar visibility to a single per-page toggle:
· Dedicated chevron-left button in header to hide sidebar
· Edge indicator (chevron-right) to restore when hidden
· No dropdown, no hover area, no pin button
- Add _migrateOldSettings() to convert old sidebarPinned and
show_folder_sidebar states to per-page sidebarDisabled
- Fix sidebar flicker on page load: CSS defaults to off-screen,
JS explicitly sets .visible or .hidden-by-setting
- Remove obsolete CSS classes: auto-hide, hover-active, collapsed
- Remove i18n keys: pinSidebar, unpinSidebar, moreOptions
- Update test mocks for the new initialize() interface