From 8120716cd83755cc1ff298aa62a419b7f4d9ebf8 Mon Sep 17 00:00:00 2001 From: Will Miao <13051207myq@gmail.com> Date: Wed, 31 Dec 2025 10:33:22 +0800 Subject: [PATCH] feat: enhance model move functionality with cache entry updates - Return cache entry data from model move operations for immediate UI updates - Add recalculate_type parameter to update_single_model_cache for proper type adjustment - Propagate cache entry through API layer to frontend MoveManager - Enable virtual scroller to update moved items with new cache data --- py/services/model_file_service.py | 12 ++++++++---- py/services/model_scanner.py | 14 ++++++++++---- static/js/api/baseModelApi.js | 3 ++- static/js/managers/MoveManager.js | 25 +++++++++++++++++++------ 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/py/services/model_file_service.py b/py/services/model_file_service.py index 0e10c02f..2d730bde 100644 --- a/py/services/model_file_service.py +++ b/py/services/model_file_service.py @@ -496,12 +496,15 @@ class ModelMoveService: 'new_file_path': file_path } - new_file_path = await self.scanner.move_model(file_path, target_path) - if new_file_path: + move_result = await self.scanner.move_model(file_path, target_path) + if move_result: + new_file_path = move_result.get("new_path") + cache_entry = move_result.get("cache_entry") return { 'success': True, 'original_file_path': file_path, - 'new_file_path': new_file_path + 'new_file_path': new_file_path, + 'cache_entry': cache_entry } else: return { @@ -539,7 +542,8 @@ class ModelMoveService: "original_file_path": file_path, "new_file_path": result.get('new_file_path'), "success": result['success'], - "message": result.get('message', result.get('error', 'Unknown')) + "message": result.get('message', result.get('error', 'Unknown')), + "cache_entry": result.get('cache_entry') }) success_count = sum(1 for r in results if r["success"]) diff --git a/py/services/model_scanner.py b/py/services/model_scanner.py index 80c74e62..d9c09f9a 100644 --- a/py/services/model_scanner.py +++ b/py/services/model_scanner.py @@ -1216,9 +1216,12 @@ class ModelScanner: except Exception as e: logger.error(f"Error moving metadata file: {e}") - await self.update_single_model_cache(source_path, target_file, metadata) + update_result = await self.update_single_model_cache(source_path, target_file, metadata, recalculate_type=True) - return target_file + return { + "new_path": target_file, + "cache_entry": update_result if isinstance(update_result, dict) else None + } except Exception as e: logger.error(f"Error moving model: {e}", exc_info=True) @@ -1250,7 +1253,7 @@ class ModelScanner: logger.error(f"Error updating metadata paths: {e}", exc_info=True) return None - async def update_single_model_cache(self, original_path: str, new_path: str, metadata: Dict) -> bool: + async def update_single_model_cache(self, original_path: str, new_path: str, metadata: Dict, recalculate_type: bool = False) -> Union[bool, Dict]: """Update cache after a model has been moved or modified""" cache = await self.get_cached_data() @@ -1287,6 +1290,9 @@ class ModelScanner: file_path_override=normalized_new_path, ) + if recalculate_type: + cache_entry = self.adjust_cached_entry(cache_entry) + cache.raw_data.append(cache_entry) cache.add_to_version_index(cache_entry) @@ -1307,7 +1313,7 @@ class ModelScanner: if cache_modified: await self._persist_current_cache() - return True + return cache_entry if metadata else True def has_hash(self, sha256: str) -> bool: """Check if a model with given hash exists""" diff --git a/static/js/api/baseModelApi.js b/static/js/api/baseModelApi.js index 2564596e..70aca853 100644 --- a/static/js/api/baseModelApi.js +++ b/static/js/api/baseModelApi.js @@ -936,7 +936,8 @@ export class BaseModelApiClient { if (result.success) { return { original_file_path: result.original_file_path || filePath, - new_file_path: result.new_file_path + new_file_path: result.new_file_path, + cache_entry: result.cache_entry }; } return null; diff --git a/static/js/managers/MoveManager.js b/static/js/managers/MoveManager.js index f6266847..eeb55cd4 100644 --- a/static/js/managers/MoveManager.js +++ b/static/js/managers/MoveManager.js @@ -327,15 +327,22 @@ class MoveManager { if (!isVisible) { state.virtualScroller.removeItemByFilePath(result.original_file_path); - } else if (result.new_file_path !== result.original_file_path) { + } else { const newFileNameWithExt = result.new_file_path.substring(result.new_file_path.lastIndexOf('/') + 1); const baseFileName = newFileNameWithExt.substring(0, newFileNameWithExt.lastIndexOf('.')); - state.virtualScroller.updateSingleItem(result.original_file_path, { + const updateData = { file_path: result.new_file_path, file_name: baseFileName, folder: newRelativeFolder - }); + }; + + // Only update model_type if it's present in the cache_entry + if (result.cache_entry && result.cache_entry.model_type) { + updateData.model_type = result.cache_entry.model_type; + } + + state.virtualScroller.updateSingleItem(result.original_file_path, updateData); } } }); @@ -352,15 +359,21 @@ class MoveManager { if (!isVisible) { state.virtualScroller.removeItemByFilePath(this.currentFilePath); } else { - // Update the model card even if it stays visible const newFileNameWithExt = result.new_file_path.substring(result.new_file_path.lastIndexOf('/') + 1); const baseFileName = newFileNameWithExt.substring(0, newFileNameWithExt.lastIndexOf('.')); - state.virtualScroller.updateSingleItem(this.currentFilePath, { + const updateData = { file_path: result.new_file_path, file_name: baseFileName, folder: newRelativeFolder - }); + }; + + // Only update model_type if it's present in the cache_entry + if (result.cache_entry && result.cache_entry.model_type) { + updateData.model_type = result.cache_entry.model_type; + } + + state.virtualScroller.updateSingleItem(this.currentFilePath, updateData); } } }