feat(stage-tamagotchi): resource island & loading progress
This commit is contained in:
@@ -78,6 +78,7 @@
|
||||
"@iconify-json/eos-icons": "^1.2.2",
|
||||
"@iconify-json/lucide": "^1.2.52",
|
||||
"@iconify-json/mingcute": "^1.2.3",
|
||||
"@iconify-json/ph": "^1.2.2",
|
||||
"@iconify-json/simple-icons": "^1.2.40",
|
||||
"@iconify-json/solar": "^1.2.2",
|
||||
"@iconify-json/svg-spinners": "^1.2.2",
|
||||
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
<script setup lang="ts">
|
||||
import type { Ref } from 'vue'
|
||||
|
||||
import { onMounted, ref } from 'vue'
|
||||
|
||||
interface ProgressInfoItem {
|
||||
filename: string
|
||||
progress: number
|
||||
currentSize: number
|
||||
totalSize: number
|
||||
}
|
||||
|
||||
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()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
left="0" fixed top-0 m-3 rounded-xl p-3
|
||||
shadow-md bg="white/80 dark:neutral-900/80"
|
||||
backdrop-blur="md"
|
||||
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-else i-solar:check-circle-bold />
|
||||
<div>
|
||||
Preparing external resources...
|
||||
</div>
|
||||
</div>
|
||||
<div w-full flex flex-col gap-2>
|
||||
<div
|
||||
v-for="file in progressInfo.files"
|
||||
:key="file.value.filename"
|
||||
max-w-full flex flex-col gap="1 sm:2"
|
||||
>
|
||||
<div flex justify-between text="xs sm:sm neutral-500 dark:neutral-400">
|
||||
<div flex items-center gap-1>
|
||||
<div v-if="file.value.progress < 100" i-svg-spinners:pulse-ring />
|
||||
<div v-else i-solar:check-circle-bold text="green-600 dark:green-400" />
|
||||
<div>
|
||||
{{ file.value.filename }}
|
||||
</div>
|
||||
<div>
|
||||
<div :style="{ width: `${file.value.progress}%` }" />
|
||||
</div>
|
||||
</div>
|
||||
<div>{{ file.value.progress.toFixed(2) }}%</div>
|
||||
</div>
|
||||
<div relative>
|
||||
<div
|
||||
bg="primary-300 dark:primary-400"
|
||||
absolute h-4 rounded-md will-change-width
|
||||
:style="{ width: `${file.value.progress}%` }"
|
||||
transition="width duration-500 ease-in-out"
|
||||
/>
|
||||
<div
|
||||
bg="neutral-100 dark:neutral-900" h-4 w-full rounded-md
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import LoadingProgress from './LoadingProgress.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<LoadingProgress />
|
||||
</template>
|
||||
@@ -7,6 +7,7 @@ import { listen } from '@tauri-apps/api/event'
|
||||
import { storeToRefs } from 'pinia'
|
||||
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 { useWindowControlStore } from '../stores/window-controls'
|
||||
@@ -146,6 +147,7 @@ if (import.meta.hot) { // For better DX
|
||||
>
|
||||
<div relative h-full w-full items-end gap-2 class="view">
|
||||
<WidgetStage h-full w-full flex-1 :focus-at="live2dFocusAt" mb="<md:18" />
|
||||
<ResourceStatusIsland />
|
||||
<div
|
||||
absolute bottom-4 left-4 flex gap-1 op-0 transition="opacity duration-500"
|
||||
:class="{
|
||||
|
||||
@@ -160,6 +160,7 @@ words:
|
||||
- rushstack
|
||||
- Saccade
|
||||
- saccades
|
||||
- safetensors
|
||||
- SAVEPOINT
|
||||
- sensenova
|
||||
- serde
|
||||
|
||||
Generated
+10
@@ -445,6 +445,9 @@ importers:
|
||||
'@iconify-json/mingcute':
|
||||
specifier: ^1.2.3
|
||||
version: 1.2.3
|
||||
'@iconify-json/ph':
|
||||
specifier: ^1.2.2
|
||||
version: 1.2.2
|
||||
'@iconify-json/simple-icons':
|
||||
specifier: ^1.2.40
|
||||
version: 1.2.40
|
||||
@@ -3084,6 +3087,9 @@ packages:
|
||||
'@iconify-json/mingcute@1.2.3':
|
||||
resolution: {integrity: sha512-yiEQfLBF5iwyOdxuY0kEU06+8Mp6Mrp14KVXTb+5jjSVuD71C9EQrzM/mm1Efd8Nu2amJalTPisl3loC8pHBqQ==}
|
||||
|
||||
'@iconify-json/ph@1.2.2':
|
||||
resolution: {integrity: sha512-PgkEZNtqa8hBGjHXQa4pMwZa93hmfu8FUSjs/nv4oUU6yLsgv+gh9nu28Kqi8Fz9CCVu4hj1MZs9/60J57IzFw==}
|
||||
|
||||
'@iconify-json/simple-icons@1.2.40':
|
||||
resolution: {integrity: sha512-sr2fbrS8rRhJNap41ucTStctxTcWQ3lcsHkY3loc4Yt1KNOne6D+l1JTOQCDj9f/VrUktVIEdaRQoYTvqfuSSw==}
|
||||
|
||||
@@ -13707,6 +13713,10 @@ snapshots:
|
||||
dependencies:
|
||||
'@iconify/types': 2.0.0
|
||||
|
||||
'@iconify-json/ph@1.2.2':
|
||||
dependencies:
|
||||
'@iconify/types': 2.0.0
|
||||
|
||||
'@iconify-json/simple-icons@1.2.40':
|
||||
dependencies:
|
||||
'@iconify/types': 2.0.0
|
||||
|
||||
Reference in New Issue
Block a user