126 lines
3.1 KiB
Vue
126 lines
3.1 KiB
Vue
<template>
|
|||
|
|
<div class="app" :data-theme="theme">
|
||
|
|
<Header
|
||
|
|
:currentView="currentView"
|
||
|
|
:theme="theme"
|
||
|
|
@navigate="navigate"
|
||
|
|
@toggleTheme="toggleTheme"
|
||
|
|
/>
|
||
|
|
|
||
|
|
<div class="main-area">
|
||
|
|
<Sidebar :currentView="currentView" @navigate="navigate" />
|
||
|
|
|
||
|
|
<div class="workspace-column">
|
||
|
|
<main class="workspace">
|
||
|
|
<EncodePage v-if="currentView === 'encode'" @taskAdded="onTaskAdded" />
|
||
|
|
<RemuxPage v-if="currentView === 'remux'" @taskAdded="onTaskAdded" />
|
||
|
|
<BurnPage v-if="currentView === 'burn'" @taskAdded="onTaskAdded" />
|
||
|
|
<SettingsPage v-if="currentView === 'settings'" />
|
||
|
|
<LogPage v-show="currentView === 'logs'" ref="logPageRef" />
|
||
|
|
</main>
|
||
|
|
<TaskDrawer :tasks="tasks" @cancel="handleCancel" />
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script setup lang="ts">
|
||
|
|
import { ref, onMounted } from 'vue'
|
||
|
|
import Header from './components/Header.vue'
|
||
|
|
import Sidebar from './components/Sidebar.vue'
|
||
|
|
import TaskDrawer from './components/TaskDrawer.vue'
|
||
|
|
import EncodePage from './views/EncodePage.vue'
|
||
|
|
import RemuxPage from './views/RemuxPage.vue'
|
||
|
|
import BurnPage from './views/BurnPage.vue'
|
||
|
|
import SettingsPage from './views/SettingsPage.vue'
|
||
|
|
import LogPage from './views/LogPage.vue'
|
||
|
|
import { api, onTaskUpdated, onTaskProgress, onTaskLog } from './api/wails'
|
||
|
|
import type { Task, Progress } from './types'
|
||
|
|
|
||
|
|
const currentView = ref('encode')
|
||
|
|
const theme = ref<'dark'|'light'>('light')
|
||
|
|
const tasks = ref<Task[]>([])
|
||
|
|
|
||
|
|
const logPageRef = ref<InstanceType<typeof LogPage> | null>(null)
|
||
|
|
|
||
|
|
onMounted(() => {
|
||
|
|
document.documentElement.setAttribute('data-theme', theme.value)
|
||
|
|
loadTasks()
|
||
|
|
|
||
|
|
onTaskUpdated((task: Task) => {
|
||
|
|
const found = tasks.value.find(t => t.id === task.id)
|
||
|
|
if (found) {
|
||
|
|
Object.assign(found, task)
|
||
|
|
} else {
|
||
|
|
tasks.value.push(task)
|
||
|
|
}
|
||
|
|
logPageRef.value?.upsertTask({
|
||
|
|
id: task.id,
|
||
|
|
inputFile: task.inputFile,
|
||
|
|
type: task.type,
|
||
|
|
status: task.status,
|
||
|
|
args: task.args,
|
||
|
|
logs: task.logs,
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
onTaskProgress((data: { taskId: string; progress: Progress }) => {
|
||
|
|
const found = tasks.value.find(t => t.id === data.taskId)
|
||
|
|
if (found) {
|
||
|
|
Object.assign(found.progress, data.progress)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
onTaskLog((data: { taskId: string; line: string }) => {
|
||
|
|
logPageRef.value?.appendLog(data.taskId, data.line)
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
function navigate(view: string) {
|
||
|
|
currentView.value = view
|
||
|
|
}
|
||
|
|
|
||
|
|
function toggleTheme() {
|
||
|
|
theme.value = theme.value === 'dark' ? 'light' : 'dark'
|
||
|
|
document.documentElement.setAttribute('data-theme', theme.value)
|
||
|
|
}
|
||
|
|
|
||
|
|
async function loadTasks() {
|
||
|
|
try { tasks.value = await api.getTasks() } catch { /* not connected */ }
|
||
|
|
}
|
||
|
|
|
||
|
|
function onTaskAdded() { loadTasks() }
|
||
|
|
|
||
|
|
async function handleCancel(id: string) {
|
||
|
|
try { await api.cancelTask(id); await loadTasks() } catch {}
|
||
|
|
}
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<style scoped>
|
||
|
|
.app {
|
||
|
|
height: 100vh;
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
}
|
||
|
|
|
||
|
|
.main-area {
|
||
|
|
flex: 1;
|
||
|
|
display: flex;
|
||
|
|
overflow: hidden;
|
||
|
|
}
|
||
|
|
|
||
|
|
.workspace-column {
|
||
|
|
flex: 1;
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
overflow: hidden;
|
||
|
|
}
|
||
|
|
|
||
|
|
.workspace {
|
||
|
|
flex: 1;
|
||
|
|
overflow-y: auto;
|
||
|
|
padding: 28px 36px;
|
||
|
|
}
|
||
|
|
</style>
|