Preview URLs now carry a cache-busting `&v=<mtime_ns>` suffix, so the media
type could no longer be read from the end of the string. Model cards,
duplicates, recipe cards and modals, the showcase thumbnail and the ComfyUI
preview tooltip all fell into the image branch and rendered `<img>` for video
previews, which browsers cannot decode.
Move the query-aware video detection that already lived in the versions tab
into a shared mediaTypes helper and use it everywhere a server-provided
preview URL is inspected. The web UI and the ComfyUI widget bundle each keep a
copy because they are served from different mounts. Video previews that turn
out to be webm now also get the right `<source type>`.
Add regression coverage for versioned mp4/webm/image URLs.
Fixes#1168
Deleting a duplicate could remove the file from disk while leaving the
entry in the cache, so the duplicate kept showing after a refresh and
only Rebuild Cache cleared it (issue #1154). Three paths produced that
state:
* ModelHashIndex.remove_by_path() deleted _hash_to_path[hash_val] with no
guard. The delete flow passes the cache row's sha256 as a hint; once
the row and the index had drifted apart (a hash corrected in place, a
partially applied cache update) the hint was not in the index and the
KeyError aborted _batch_update_cache_for_deleted_models(), so every
deleted model stayed in memory and in SQLite.
* The same cache update was skipped outright when the scanner's
cancellation flag was set, turning files staged before the cancellation
into ghost entries.
* A file that was already gone from disk could never be cleaned up:
staging found no artifacts, the hard delete reported nothing, and the
row survived as a permanent "No files deleted" failure.
Make the hash hint advisory and guard the index deletions; drop the
path-keyed entries (filename duplicates, autov2/autov3) even when no hash
mapping exists. Always apply the cache update after a delete, purge stale
index paths that never reached the cache, and treat a missing file under
a reachable folder as deleted while still keeping unreachable roots
offline. bulk_delete_models() reports success: false when nothing was
removed instead of presenting a no-op as a completed delete.
The duplicates UI now surfaces what it used to hide: per-file failures
from `results`, and a cache-update failure that needs Rebuild Cache.
Width pressure on the controls bar is real (see the max-width: 1500px
tightening in layout.css), and the icons on text-labeled action buttons
are redundant encoding. Remove them from Refresh / Fetch / Download /
Bulk / Duplicates / Doctor and the recipes-page Import / Batch Import.
Kept: state-carrying icons (favorites star, updates exclamation,
exit-duplicates fa-times, badges) and structural icons (carets, layout
toggle, dropdown menu items). ModelDuplicatesManager rebuilds the
duplicates button on mode exit, so its restore string is updated too.
- Remove delete_undo_enabled setting (backend default, frontend state,
settings modal UI, 10 locales); staged deletes with 30s undo are now
the only delete path and stale settings keys are silently ignored
- Remove the 1500ms delete-button arm delay (armDeleteButton) from all
delete modals; misclicks are recoverable via the undo toast
- Delete modal always shows the recoverable warning
- Log the first staged file path in staging log lines for easier support
When no duplicate groups are detected, the duplicate manager now checks if it is currently in duplicate mode and calls `exitDuplicateMode()` to clear the display. This prevents the UI from showing stale duplicate information when no duplicates exist.
- Updated all relevant routes in `stats_routes.py` and `update_routes.py` to include the new '/api/lm/' prefix for consistency.
- Modified API endpoint configurations in `apiConfig.js` to reflect the new structure, ensuring all CRUD and bulk operations are correctly routed.
- Adjusted fetch calls in various components and managers to utilize the updated API paths, including recipe, model, and example image operations.
- Ensured all instances of the old API paths were replaced with the new '/api/lm/' prefix across the codebase for uniformity and to prevent broken links.
refactor: consolidate model API client creation into a factory function for better maintainability
feat: implement move operations for LoRAs and handle unsupported operations for Checkpoints and Embeddings
- Added PresetTags.js to handle LoRA model preset parameter tags.
- Introduced RecipeTab.js for managing recipes associated with LoRA models.
- Created TriggerWords.js to manage trigger word functionality for LoRA models.
- Implemented utility functions in utils.js for general model modal operations.
- Implemented `/api/loras/verify-duplicates` and `/api/checkpoints/verify-duplicates` endpoints.
- Added `handle_verify_duplicates` method in `ModelRouteUtils` to process duplicate verification requests.
- Enhanced `ModelDuplicatesManager` to manage verification state and display results.
- Updated CSS for verification badges and hash mismatch indicators. Fixes#221
- Introduced a new API endpoint for bulk deleting loras.
- Added ModelDuplicatesManager to handle duplicate models for loras and checkpoints.
- Implemented UI components for displaying duplicates and managing selections.
- Enhanced controls with a button for finding duplicates.
- Updated templates to include a duplicates banner and associated actions.