Commit Graph

2095 Commits

Author SHA1 Message Date
Will Miao
26884630d3 feat(model-modal): improve transition animations and fix navigation logic
- Add `!important` to overlay background and closing opacity for consistent styling
- Remove navigation spam prevention to allow consecutive transitions
- Implement in-place content updates during model transitions instead of reopening modal
- Add opacity transitions for showcase and metadata components
- Fetch complete Civitai metadata during transitions for updated model data
2026-02-07 10:20:05 +08:00
Will Miao
66e9d77c67 feat: implement lazy loading and image caching for thumbnails
Add lazy loading with skeleton animations and IndexedDB-based image caching to improve thumbnail loading performance. The changes include:

- CSS animations for loading states with shimmer effects
- Priority-based image loading queue with configurable concurrency
- Persistent image cache with automatic cleanup
- Error handling and cached image highlighting
- Increased concurrent loading from 3 to 6 for faster initial display

This reduces network requests and provides smoother user experience when browsing large model collections.
2026-02-07 09:53:24 +08:00
Will Miao
5ffca15172 feat(showcase): add wheel navigation, horizontal thumbnail rail scroll, and image counter
- Add horizontal scroll to thumbnail rail on wheel event
- Add wheel-based image navigation in main image area (150 threshold)
- Add image counter showing current position (e.g., "1 / 12")
- Use tabular-nums and min-width: 2ch to prevent counter layout shift
- Respect params panel scrolling when using wheel navigation
2026-02-07 00:35:29 +08:00
Will Miao
4d9115339b feat(showcase): improve remote image loading with skeleton animation and fade-in effects
- Add preloadMedia() for async image/video loading before display
- Implement renderLoadingSkeleton() with fa-circle-notch fa-spin animation
- Add fadeIn transition (opacity 0→1) for main media elements
- Remove shimmer gradient animation from thumbnails for cleaner look
- Use solid background color placeholder with subtle fade-in for thumbnails
- Fixes progressive rendering of remote images from top to bottom
- Prevents black flash during loading with proper loading states
2026-02-06 23:49:45 +08:00
Will Miao
469f7a1829 feat(showcase): add Show button to NSFW notice in main media area
- Add showcase__nsfw-notice-content wrapper for better layout
- Add showcase__nsfw-show-btn with styling matching card.css show-content-btn
- Add show-content action handler that triggers global blur toggle
- Button uses blue accent color with eye icon and hover effects
- Clicking Show button syncs with blur toggle button icon state
- Use unique class names to avoid conflicts with card.css
2026-02-06 23:06:02 +08:00
Will Miao
d27e3c8126 Phase 2: Model Modal Tabs and Edit Features
- Implement Versions Tab with version cards, badges, and actions
- Implement Recipes Tab with recipe cards grid
- Add Usage Tips editing (add/remove parameters)
- Add Trigger Words editing (add/remove/copy)
- Optimize Notes textarea with auto-save indicator
- Implement custom example upload area with drag-drop
- Add missing i18n translation keys
- Add CSS styles for versions, recipes, and upload components
- Fix async/await syntax error in RecipesTab.js
2026-02-06 20:13:07 +08:00
Will Miao
7bc63d7631 Phase 1: Model Modal Split-View Redesign
- Implement new split-view overlay layout (left showcase, right metadata)
- Add keyboard navigation (↑↓ for model, ←→ for examples, ESC to close)
- Create Thumbnail Rail for quick example navigation
- Add image controls (view params, set preview, delete)
- Implement parameter panel with prompt display
- Add metadata panel with model info, tags, licenses
- Create tabs (Description/Versions/Recipes) with accordion content
- Integrate with existing ModelCard click handlers
- Add first-use keyboard hint overlay

New files:
- static/js/components/model-modal/*.js
- static/css/components/model-modal/*.css
- docs/plan/model-modal-redesign.md
2026-02-06 19:24:49 +08:00
Will Miao
1606a3ff46 feat: add clear button to autocomplete text widget and fix external value change sync
- Add clear button inside autocomplete text widget that shows when text exists
- Support both Canvas mode and Vue DOM mode with appropriate styling
- Fix clear button visibility when value is changed externally (e.g., via 'send lora to workflow')
- Implement dual notification mechanism: CustomEvent + onSetValue callback
- Update widget interface to include onSetValue property
2026-02-06 09:15:16 +08:00
Will Miao
b313f36be9 feat(duplicates): exit duplicate mode when no duplicates found, #783
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.
2026-02-05 22:54:24 +08:00
Will Miao
fa3625ff72 feat(filter): add tag logic toggle (OR/AND) for include tags filtering
Add a segmented toggle in the Filter Panel to switch between 'Any' (OR)
and 'All' (AND) logic when filtering by multiple include tags.

Changes:
- Backend: Add tag_logic field to FilterCriteria and ModelFilterSet
- Backend: Parse tag_logic parameter in model handlers
- Frontend: Add segmented toggle UI in filter panel header
- Frontend: Add interaction logic and state management for tag logic
- Add translations for all supported languages
- Add comprehensive tests for the new feature

Closes #802
2026-02-05 22:36:30 +08:00
Will Miao
895d13dc96 feat(settings): clean up default values from settings.json
Add automatic cleanup of default values from settings.json to keep configuration files minimal and focused on user customizations. Introduces a threshold-based cleanup that only removes default values when the file contains a significant number of them (10+), preserving small template-based configurations while cleaning up legacy bloated files.

Key changes:
- Add DEFAULT_KEYS_CLEANUP_THRESHOLD constant to control cleanup aggressiveness
- Implement _cleanup_default_values_from_disk() method that removes default values from disk while keeping them available in memory
- Modify _ensure_default_settings() to only save when existing values are updated, not when defaults are inserted
- Update _serialize_settings_for_disk() to only persist settings that differ from defaults
- Add cleanup call during initialization for existing settings files

This reduces file size and noise in settings.json while maintaining full functionality at runtime.
2026-02-05 08:40:27 +08:00
Will Miao
b7e0821f66 feat(duplicates): add filter support for duplicate model finding, #783 2026-02-04 20:47:30 +08:00
Will Miao
36e3e62e70 feat: add filter presets and update version to v0.9.15
- Added filter presets feature allowing users to save and quickly switch between filter combinations
- Fixed various bugs to improve overall stability
- Updated project version from 0.9.14 to 0.9.15 in pyproject.toml
v0.9.15
2026-02-04 09:12:37 +08:00
Will Miao
7bcf4e4491 feat(config): discover deep symlinks dynamically when accessing previews 2026-02-04 00:16:59 +08:00
Will Miao
c12aefa82a fix(recipes): detect duplicates for remote imports using modelVersionId and Civitai URL, #750
- Use modelVersionId as fallback for all loras in fingerprint calculation (not just deleted)
- Add URL-based duplicate detection using source_path field
- Combine both fingerprint and URL-based duplicate detection in API response
- Fix _download_remote_media return type and unbound variable issue
2026-02-03 21:32:15 +08:00
Will Miao
990a3527e4 feat(ui): improve filter preset delete button visibility and layout
- Hide delete button by default and show on hover for inactive presets
- Show delete button on active presets only when hovering over the preset
- Add ellipsis truncation for long preset names to prevent layout breakage
- Remove checkmark icon from active preset names for cleaner visual design
2026-02-03 20:05:39 +08:00
Will Miao
655d3cab71 fix(config): prioritize checkpoints over unet when paths overlap, #799
When checkpoints and unet folders point to the same physical location
(via symlinks), prioritize checkpoints for backward compatibility.

This prevents the 'Failed to load Checkpoint root' error that users
experience when they have incorrectly configured their ComfyUI paths.

Changes:
- Detect overlapping real paths between checkpoints and unet
- Log warning to inform users of the configuration issue
- Remove overlapping paths from unet_map, keeping checkpoints

Fixes #<issue-number>
2026-02-03 18:27:42 +08:00
Will Miao
358e658459 fix(trigger_word_toggle): add trigger word normalization method
Introduce a new private method `_normalize_trigger_words` to handle consistent splitting and cleaning of trigger word strings. This method splits input by both single and double commas, strips whitespace, and filters out empty strings, returning a set of normalized words. It is now used in `process_trigger_words` to compare trigger word overrides, ensuring accurate detection of changes by comparing normalized sets instead of raw strings.
2026-02-03 15:42:09 +08:00
Will Miao
f28c32f2b1 feat(lora-cycler): increase repeat input width for better usability
The width of the repeat input field in the LoRA cycler settings view has been increased from 40px to 50px. This change improves usability by providing more space for user input, making the control easier to interact with and reducing visual crowding.
2026-02-03 09:40:55 +08:00
Will Miao
f5dbd6b8e8 fix(metadata): auto-disable archive_db setting when database file is missing 2026-02-03 08:36:27 +08:00
Will Miao
2c026a2646 fix(metadata-sync): persist db_checked flag for deleted models
When a deleted model is checked against the SQLite archive and not found, the `db_checked` flag was set in memory but never saved to disk. This occurred because the save operation was only triggered when `civitai_api_not_found` was True, which is not the case for deleted models (since the CivitAI API is not attempted). As a result, deleted models would be rechecked on every refresh instead of being skipped.

Changes:
- Introduce a `needs_save` flag to track when metadata state is updated
- Save metadata whenever `db_checked` is set to True, regardless of API status
- Ensure `last_checked_at` is set for SQLite-only attempts
- Add regression test to verify the fix
2026-02-03 07:34:41 +08:00
Will Miao
bd83f7520e chore: bump version to 0.9.14 v0.9.14 2026-02-02 23:17:35 +08:00
Will Miao
b9a4e7a09b docs(release): add v0.9.14 release notes
- Add LoRA Cycler node with iteration support
- Enhance Prompt node with tag autocomplete (Danbooru + e621)
- Add command system (/char, /artist, /ac, /noac) for tag operations
- Reference Lora Cycler and Lora Manager Basic template workflows
- Bug fixes and stability improvements
2026-02-02 23:09:06 +08:00
Will Miao
c30e57ede8 fix(recipes): add data-folder attribute to RecipeCard for correct drag-drop path calculation 2026-02-02 22:18:13 +08:00
Will Miao
0dba1b336d feat(template): update prompt node usage in basic template workflow 2026-02-02 21:58:51 +08:00
Will Miao
820afe9319 feat(recipe_scanner): ensure cache initialization and improve type safety
- Initialize RecipeCache in scan_recipes to prevent None reference errors
- Import PersistedRecipeData directly instead of using string annotation
- Remove redundant import inside _reconcile_recipe_cache method
2026-02-02 21:57:44 +08:00
Will Miao
5a97f4bc75 feat(recipe_scanner): optimize recipe lookup performance
Refactor recipe lookup logic to improve efficiency from O(n²) to O(n + m):
- Build recipe_by_id dictionary for O(1) recipe ID lookups
- Simplify persisted_by_path construction using recipe_id extraction
- Add fallback lookup by recipe_id when path lookup fails
- Maintain same functionality while reducing computational complexity
2026-02-02 19:37:06 +08:00
Will Miao
94da404cc5 fix: skip confirmed not-found models in bulk metadata refresh
When enable_metadata_archive_db=True, the previous filter logic would
repeatedly try to fetch metadata for models that were already confirmed
to not exist on CivitAI (from_civitai=False, civitai_deleted=True).

The fix adds a skip condition to exclude models that:
1. Are confirmed not from CivitAI (from_civitai=False)
2. Are marked as deleted/not found on CivitAI (civitai_deleted=True)
3. Either have no archive DB enabled, or have already been checked (db_checked=True)

This prevents unnecessary API calls to CivArchive for user-trained models
or models from non-CivitAI sources.

Fixes repeated "Error fetching version of CivArchive model by hash" logs
for models that will never be found on CivitAI/CivArchive.
2026-02-02 13:27:18 +08:00
Will Miao
1da476d858 feat(example-images): add check pending models endpoint and improve async handling
- Add /api/example-images/check-pending endpoint to quickly check models needing downloads
- Improve DownloadManager.start_download() to return immediately without blocking
- Add _handle_download_task_done callback for proper error handling and progress saving
- Add check_pending_models() method for lightweight pre-download validation
- Update frontend ExampleImagesManager to use new check-pending endpoint
- Add comprehensive tests for new functionality
2026-02-02 12:31:07 +08:00
Will Miao
1daaff6bd4 feat: add LoRa Manager E2E testing skill documentation
Introduce comprehensive documentation for the new `lora-manager-e2e` skill, which provides end-to-end testing workflows for LoRa Manager. The skill enables automated validation of standalone mode, including server management, UI interaction via Chrome DevTools MCP, and frontend-to-backend integration testing.

Key additions:
- Detailed skill description and prerequisites
- Quick start workflow for server setup and browser debugging
- Common E2E test patterns for page load verification, server restart, and API testing
- Example test flows demonstrating step-by-step validation procedures
- Scripts and MCP command examples for practical implementation

This documentation supports automated testing of LoRa Manager's web interface and backend functionality, ensuring reliable end-to-end validation of features.
2026-02-02 12:15:58 +08:00
Will Miao
e252e44403 refactor(logging): replace print statements with logger for consistency 2026-02-02 10:47:17 +08:00
Will Miao
778ad8abd2 feat(cache): add cache health monitoring and validation system, see #730
- Add cache entry validator service for data integrity checks
- Add cache health monitor service for periodic health checks
- Enhance model cache and scanner with validation support
- Update websocket manager for health status broadcasting
- Add initialization banner service for cache health alerts
- Add comprehensive test coverage for new services
- Update translations across all locales
- Refactor sync translation keys script
2026-02-02 08:30:59 +08:00
Will Miao
68cf381b50 feat(autocomplete): improve tag search to use last token for multi-word prompts
- Modify custom words search to extract last space-separated token from search term
- Add `_getLastSpaceToken` helper method for token extraction
- Update selection replacement logic to only replace last token in multi-word prompts
- Enables searching "hello 1gi" to find "1girl" and replace only "1gi" with "1girl"
- Maintains full command replacement for command mode (e.g., "/char miku")
2026-02-01 22:09:21 +08:00
Will Miao
337f73e711 fix(slider): fix floating point precision issues in SingleSlider and DualRangeSlider
JavaScript floating point arithmetic causes values like 1.1 to become
1.1000000000000014. Add precision limiting to 2 decimal places in
snapToStep function for both sliders.
2026-02-01 21:03:04 +08:00
Will Miao
04ba966a6e feat: Add LoRA selector modal to Cycler widget
- Add LoraListModal component with search and preview tooltip
- Make 'Next LoRA' name clickable to open selector modal
- Integrate PreviewTooltip with custom resolver for Vue widgets
- Disable selector when prompts are queued (consistent with pause button)
- Fix tooltip z-index to display above modal backdrop

Fixes issue: users couldn't easily identify which index corresponds
to specific LoRA in large lists
2026-02-01 20:58:30 +08:00
Will Miao
71c8cf84e0 refactor(LoraCyclerWidget): UI/UX improvements
- Replace REP badge with segmented progress bar for repeat indicator
- Reorganize Starting Index & Repeat controls into aligned groups
- Change repeat format from '× [count] times' to '[count] ×' for better alignment
- Remove unnecessary refresh button and related logic
2026-02-01 20:00:30 +08:00
Will Miao
db1aec94e5 refactor(logging): replace print statements with logger in metadata_collector 2026-02-01 15:41:41 +08:00
Will Miao
553e1868e1 perf(config): limit symlink scan to first level for faster startup
Replace recursive directory traversal with first-level-only symlink scanning
to fix severe performance issues on large model collections (220K+ files).

- Rename _scan_directory_links to _scan_first_level_symlinks
- Only scan symlinks directly under each root directory
- Skip traversal of normal subdirectories entirely
- Update tests to reflect first-level behavior
- Add test_deep_symlink_not_scanned to document intentional limitation

Startup time reduced from 15+ minutes to seconds for affected users.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 12:42:35 +08:00
Will Miao
938ceb49b2 feat(autocomplete): add toggle commands for autocomplete setting
- Add `/ac` and `/noac` commands to toggle prompt tag autocomplete on/off
- Commands only appear when relevant (e.g., `/ac` shows when autocomplete is off)
- Show toast notification when toggling setting
- Use ComfyUI's setting API with fallback to legacy API
- Clear autocomplete token after toggling to provide clean UX
2026-02-01 12:34:38 +08:00
Will Miao
c0f03b79a8 feat(settings): change model card footer action default to replace_preview 2026-02-01 07:38:04 +08:00
Will Miao
a492638133 feat(lora-cycler): disable pause button when prompts are queued
- Add `hasQueuedPrompts` reactive flag to track queued executions
- Pass `is-pause-disabled` prop to settings view to disable pause button
- Update pause button title to indicate why it's disabled
- Remove server queue clearing logic from pause toggle handler
- Clear `hasQueuedPrompts` flag when manually changing index or resetting
- Set `hasQueuedPrompts` to true when adding prompts to execution queue
- Update flag when processing queued executions to reflect current queue state
2026-02-01 01:12:39 +08:00
Will Miao
e17d6c8ebf feat(testing): enhance test configuration and add Vue component tests
- Update package.json test script to run both JS and Vue tests
- Simplify LoraCyclerLM output by removing redundant lora name fallback
- Extend Vitest config to include TypeScript test files
- Add Vue testing dependencies and setup for component testing
- Implement comprehensive test suite for BatchQueueSimulator component
- Add test setup file with global mocks for ComfyUI modules
2026-02-01 00:59:50 +08:00
Will Miao
ffcfe5ea3e fix(metadata): rename model_type to sub_type and add embedding subtype, see #797
- Change `model_type` field to `sub_type` for checkpoint models to improve naming consistency
- Add `sub_type="embedding"` for embedding models to properly categorize model subtypes
- Maintain backward compatibility with existing metadata structure
2026-01-31 22:54:53 +08:00
Will Miao
719e18adb6 feat(media): add media type hint support for file extension detection, fixes #795 and fixes #751
- Add optional `media_type_hint` parameter to `_get_file_extension_from_content_or_headers` method
- When `media_type_hint` is "video" and no extension can be determined from content/headers/URL, default to `.mp4`
- Pass image metadata type as hint in both `process_example_images` and `process_example_images_batch` methods
- Add unit tests to verify media type hint behavior and priority
2026-01-31 19:39:37 +08:00
Will Miao
92d471daf5 feat(ui): hide model sub-type in compact density mode, see #793
Add CSS rules to hide the model sub-type and separator elements when the compact-density class is applied. This change saves visual space in compact mode by removing less critical information, improving the layout for dense interfaces.
2026-01-31 11:17:49 +08:00
Will Miao
66babf9ee1 feat(lora-cycler): reset execution state on manual index change
Reset execution state when user manually changes LoRA index to ensure next execution starts from the user-set index. This prevents stale execution state from interfering with user-initiated index changes.
2026-01-31 09:04:26 +08:00
Will Miao
60df2df324 feat: add new Flux Klein models, ZImageBase, and LTXV2 to constants, see #792
- Add Flux.2 Klein 9B, 9B-base, 4B, and 4B-base models to BASE_MODELS, BASE_MODEL_ABBREVIATIONS, and Flux Models category
- Include ZImageBase model and its abbreviation
- Add LTXV2 video model to BASE_MODELS, BASE_MODEL_ABBREVIATIONS, and Video Models category
- Update model categories to reflect new additions
2026-01-31 07:57:21 +08:00
Will Miao
b86bd44c65 feat(filter): enable model types filter for checkpoints page 2026-01-30 22:32:50 +08:00
Will Miao
77bfbe1bc9 feat(header): remove no-presets placeholder from filter presets section
The no-presets placeholder element has been removed from the filter presets section in the header component. This change likely indicates that the application now handles empty presets states differently, possibly through dynamic content rendering or alternative UI patterns.
2026-01-30 11:03:23 +08:00
Will Miao
666db4cdd0 refactor(ui): simplify filter preset empty state
- Remove default presets and restore defaults functionality
- Unify preset UI: always show '+ Add' button regardless of preset count
- Remove empty state message and restore button to reduce visual clutter
- Clean up unused translation keys (restoreDefaults, noPresets)
- Fix spacing issues in filter panel
2026-01-30 10:25:22 +08:00