From a9ed0c180c5fba8aa20537b4b3b47bd01448f6b6 Mon Sep 17 00:00:00 2001 From: Neko Ayaka Date: Tue, 5 May 2026 04:17:17 +0800 Subject: [PATCH] fix(stage-ui): rollback to previous implementation of model selector --- .../live2d-report-modal.story.vue | 197 +++++++ .../dialogs/model-selector/model-selector.vue | 500 ++++-------------- 2 files changed, 308 insertions(+), 389 deletions(-) create mode 100644 packages/stage-ui/src/components/scenarios/dialogs/model-selector/live2d-report-modal.story.vue diff --git a/packages/stage-ui/src/components/scenarios/dialogs/model-selector/live2d-report-modal.story.vue b/packages/stage-ui/src/components/scenarios/dialogs/model-selector/live2d-report-modal.story.vue new file mode 100644 index 000000000..e6aea65eb --- /dev/null +++ b/packages/stage-ui/src/components/scenarios/dialogs/model-selector/live2d-report-modal.story.vue @@ -0,0 +1,197 @@ + + + diff --git a/packages/stage-ui/src/components/scenarios/dialogs/model-selector/model-selector.vue b/packages/stage-ui/src/components/scenarios/dialogs/model-selector/model-selector.vue index d8d8d9acb..7f51aec6b 100644 --- a/packages/stage-ui/src/components/scenarios/dialogs/model-selector/model-selector.vue +++ b/packages/stage-ui/src/components/scenarios/dialogs/model-selector/model-selector.vue @@ -3,13 +3,12 @@ import type { Live2DValidationReport } from '@proj-airi/stage-ui-live2d' import type { DisplayModel } from '../../../../stores/display-models' -import { vAutoAnimate } from '@formkit/auto-animate/vue' import { validateLive2DZip } from '@proj-airi/stage-ui-live2d' import { Button } from '@proj-airi/ui' import { useFileDialog } from '@vueuse/core' import { storeToRefs } from 'pinia' -import { DialogContent, DialogOverlay, DialogPortal, DialogRoot, DialogTitle, DropdownMenuContent, DropdownMenuItem, DropdownMenuPortal, DropdownMenuRoot, DropdownMenuTrigger } from 'reka-ui' -import { computed, ref, watch } from 'vue' +import { DropdownMenuContent, DropdownMenuItem, DropdownMenuPortal, DropdownMenuRoot, DropdownMenuTrigger, EditableArea, EditableEditTrigger, EditableInput, EditablePreview, EditableRoot, EditableSubmitTrigger } from 'reka-ui' +import { ref, watch } from 'vue' import Live2DReportModal from './Live2DReportModal.vue' @@ -26,91 +25,19 @@ const emits = defineEmits<{ const displayModelStore = useDisplayModelsStore() const { displayModelsFromIndexedDBLoading, displayModels } = storeToRefs(displayModelStore) -// Redesign State -const viewMode = ref<'grid' | 'compact'>('compact') -const searchQuery = ref('') -const formatFilter = ref<'all' | 'live2d' | 'vrm'>('all') -const sortBy = ref<'name' | 'date'>('date') - -const showRenameDialog = ref(false) -const modelToRename = ref(null) -const tempRenameValue = ref('') +function handleRemoveModel(model: DisplayModel) { + displayModelStore.removeDisplayModel(model.id) +} const highlightDisplayModelCard = ref(props.selectedModel?.id) const showReportModal = ref(false) const pendingFile = ref(null) const validationReport = ref(null) -const currentTab = ref<'library' | 'explore'>('library') - -const marketplaces = [ - { name: 'Booth', vrm: true, live2d: true, languages: ['jp', 'us'], origin: 'Japan', url: 'https://booth.pm/en/browse/VTuber' }, - { name: 'VGen', vrm: true, live2d: true, languages: ['us'], origin: 'USA', url: 'https://vgen.co' }, - { name: 'itch.io', vrm: true, live2d: true, languages: ['us'], origin: 'USA', url: 'https://itch.io/game-assets' }, - { name: 'Gumroad', vrm: true, live2d: true, languages: ['us'], origin: 'USA', url: 'https://gumroad.com' }, - { name: 'Ko-fi', vrm: true, live2d: true, languages: ['us'], origin: 'USA', url: 'https://ko-fi.com/shop' }, - { name: 'VRoid Hub', vrm: true, live2d: false, languages: ['jp', 'us'], origin: 'Japan', url: 'https://hub.vroid.com' }, - { name: 'Sketchfab', vrm: true, live2d: false, languages: ['us'], origin: 'USA', url: 'https://sketchfab.com' }, - { name: 'CGTrader', vrm: true, live2d: false, languages: ['us'], origin: 'USA', url: 'https://cgtrader.com' }, - { name: 'Nizima', vrm: false, live2d: true, languages: ['jp', 'us'], origin: 'Japan', url: 'https://nizima.com' }, - { name: 'Avatar Atelier', vrm: false, live2d: true, languages: ['us'], origin: 'USA', url: 'https://avataratelier.com' }, - { name: 'VTuberAvatars', vrm: false, live2d: true, languages: ['us'], origin: 'USA', url: 'https://vtuberavatars.com' }, -] - -// Filtering Logic -const filteredModels = computed(() => { - let result = [...displayModels.value] - - // Search - if (searchQuery.value.trim()) { - const q = searchQuery.value.toLowerCase() - result = result.filter(m => m.name.toLowerCase().includes(q)) - } - - // Format Filter - if (formatFilter.value !== 'all') { - result = result.filter((m) => { - if (formatFilter.value === 'live2d') - return m.format === DisplayModelFormat.Live2dZip || m.format === DisplayModelFormat.Live2dDirectory - if (formatFilter.value === 'vrm') - return m.format === DisplayModelFormat.VRM - return true - }) - } - - // Sort - result.sort((a, b) => { - if (sortBy.value === 'name') - return a.name.localeCompare(b.name) - if (sortBy.value === 'date') - return b.importedAt - a.importedAt - return 0 - }) - - return result -}) - -function handleRemoveModel(model: DisplayModel) { - displayModelStore.removeDisplayModel(model.id) -} - watch(() => props.selectedModel?.id, (modelId) => { highlightDisplayModelCard.value = modelId }, { immediate: true }) -function openRenameDialog(model: DisplayModel) { - modelToRename.value = model - tempRenameValue.value = model.name - showRenameDialog.value = true -} - -function confirmRename() { - if (modelToRename.value && tempRenameValue.value.trim()) { - displayModelStore.renameDisplayModel(modelToRename.value.id, tempRenameValue.value.trim()) - showRenameDialog.value = false - } -} - async function handleAddLive2DModel(file: FileList | null) { if (file === null || file.length === 0) return @@ -123,17 +50,22 @@ async function handleAddLive2DModel(file: FileList | null) { if (report.status === 'VALID' && report.errors.length === 0) { confirmImport() + return } - else { - showReportModal.value = true - } + + showReportModal.value = true } function confirmImport() { - if (pendingFile.value) { - displayModelStore.addDisplayModel(DisplayModelFormat.Live2dZip, pendingFile.value) - pendingFile.value = null - } + if (pendingFile.value === null) + return + + displayModelStore.addDisplayModel(DisplayModelFormat.Live2dZip, pendingFile.value) + pendingFile.value = null +} + +function handleFixError(error: string) { + void error } function handlePick(m: DisplayModel) { @@ -143,8 +75,7 @@ function handlePick(m: DisplayModel) { } function handleMobilePick() { - const model = displayModels.value.find(model => model.id === highlightDisplayModelCard.value) - emits('pick', model) + emits('pick', displayModels.value.find(model => model.id === highlightDisplayModelCard.value)) emits('close', undefined) } @@ -171,127 +102,38 @@ const vrmDialog = useFileDialog({ accept: '.vrm', multiple: false, reset: true } live2dDialog.onChange(handleAddLive2DModel) vrmDialog.onChange(handleAddVRMModel) - -function handleFixError(err: string) { - // eslint-disable-next-line no-console - console.log('[Model Selector] Fixing error:', err) - // Logic to fix common errors (e.g. missing preview) - // For now, we provide guidance or mark as ignorable in the future - if (err.toLowerCase().includes('preview') || err.toLowerCase().includes('thumbnail') || err.toLowerCase().includes('icon')) { - // If it's a missing preview, we could generate a placeholder - // For this PR feedback, we just acknowledged the "Quick Fix" button existence - } -}