feat: resource progress store (#244)

This commit is contained in:
RainbowBird
2025-06-28 18:16:44 +08:00
committed by GitHub
parent ec555bad5d
commit 53ba898267
4 changed files with 54 additions and 68 deletions
@@ -1,70 +1,16 @@
<script setup lang="ts">
import type { Ref } from 'vue'
import type { ProgressInfo } from '../../../stores/resources'
import { onMounted, ref } from 'vue'
import { computed } from 'vue'
interface ProgressInfoItem {
filename: string
progress: number
currentSize: number
totalSize: number
}
const props = defineProps<{
progressInfo: ProgressInfo
}>()
interface ProgressInfo {
files: Ref<ProgressInfoItem>[]
totalProgress: number
}
const progressInfo = ref<ProgressInfo>({
files: [],
totalProgress: 0,
})
const simulatingProgressFiles = [
{ filename: 'model.safetensors', totalSize: 1000000 },
{ filename: 'config.json', totalSize: 500000 },
{ filename: 'metadata.json', totalSize: 200000 },
]
function simulateProgressForItem(totalSize: number, item: Ref<ProgressInfoItem>) {
const interval = setInterval(() => {
if (item.value.progress >= 100) {
item.value.progress = 100
clearInterval(interval)
return
}
item.value.currentSize += 8192
item.value.progress = (item.value.currentSize / totalSize) * 100
}, 100)
}
function simulateProgress() {
for (const file of simulatingProgressFiles) {
const item = ref<ProgressInfoItem>({
filename: file.filename,
progress: 0,
currentSize: 0,
totalSize: file.totalSize,
})
progressInfo.value.files.push(item)
simulateProgressForItem(file.totalSize, item)
const interval = setInterval(() => {
const totalProgress = progressInfo.value.files.reduce((acc, file) => acc + file.value.progress, 0) / progressInfo.value.files.length
progressInfo.value.totalProgress = totalProgress
if (totalProgress >= 100) {
clearInterval(interval)
}
}, 100)
}
}
onMounted(() => {
// Simulate progress for demonstration purposes
simulateProgress()
const totalProgress = computed(() => {
return Array.from(
props.progressInfo.values(),
).reduce((acc, file) => acc + file.value.progress, 0) / props.progressInfo.size
})
</script>
@@ -76,7 +22,7 @@ onMounted(() => {
w="[calc(100%-1.5rem)]"
>
<div mb-3 flex items-center gap-2>
<div v-if="progressInfo.totalProgress < 100" i-svg-spinners:pulse-ring />
<div v-if="totalProgress < 100" i-svg-spinners:pulse-ring />
<div v-else i-solar:check-circle-bold />
<div>
Preparing external resources...
@@ -84,7 +30,7 @@ onMounted(() => {
</div>
<div w-full flex flex-col gap-2>
<div
v-for="file in progressInfo.files"
v-for="file in Array.from(progressInfo.values())"
:key="file.value.filename"
max-w-full flex flex-col gap="1 sm:2"
>
@@ -1,7 +1,12 @@
<script setup lang="ts">
import { storeToRefs } from 'pinia'
import { useResourcesStore } from '../../../stores/resources'
import LoadingProgress from './LoadingProgress.vue'
const { resources } = storeToRefs(useResourcesStore())
</script>
<template>
<LoadingProgress />
<LoadingProgress :progress-info="resources" />
</template>
+4 -2
View File
@@ -10,6 +10,7 @@ import { computed, onMounted, onUnmounted, ref } from 'vue'
import ResourceStatusIsland from '../components/Widgets/ResourceStatusIsland/index.vue'
import { useAppRuntime } from '../composables/runtime'
import { useWindowShortcuts } from '../composables/window-shortcuts'
import { useResourcesStore } from '../stores/resources'
import { useWindowControlStore } from '../stores/window-controls'
import { WindowControlMode } from '../types/window-controls'
import { startClickThrough, stopClickThrough } from '../utils/windows'
@@ -97,9 +98,10 @@ function onTauriPositionCursorAndWindowFrameEvent(event: { payload: [Point, Wind
onMounted(async () => {
// Listen for click-through state changes
unListenFuncs.push(await listen('tauri-app:window-click-through:position-cursor-and-window-frame', onTauriPositionCursorAndWindowFrameEvent))
// Load models
invoke('load_models')
// eslint-disable-next-line no-console
unListenFuncs.push(await listen('tauri-app:model-load-progress', console.log))
unListenFuncs.push(await listen('tauri-app:model-load-progress', useResourcesStore().appendResource))
if (connected.value)
return
@@ -0,0 +1,33 @@
import type { Ref } from 'vue'
import { defineStore } from 'pinia'
import { ref } from 'vue'
export interface ProgressInfoItem {
filename: string
progress: number
currentSize: number
totalSize: number
}
export type ProgressInfo = Map<string, Ref<ProgressInfoItem>>
export const useResourcesStore = defineStore('resources', () => {
const resources = ref<ProgressInfo>(new Map())
const appendResource = (event: { payload: [string, number] }) => {
const [filename, progress] = event.payload
const fileRef = ref<ProgressInfoItem>({
filename,
progress,
currentSize: 0,
totalSize: 100,
})
resources.value.set(filename, fileRef)
}
return {
resources,
appendResource,
}
})