mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-19 02:12:46 +08:00
- Add 100+ new test files covering provider sources, platform adapters, agent runners, star/plugin system, knowledge base, core utils, pipeline, computer tools, builtin commands, and dashboard routes - Fix Python type errors in sqlite.py (col() wrappers for SQLModel), astr_agent_tool_exec, core_lifecycle, star context/manager - Fix TypeScript strict mode errors across 30+ dashboard Vue files - Add import smoke tests, auth roundtrip, startup tests - Add compile-all check and CLI entry test for AUR compatibility - Restore BotMessageAccumulator and helpers lost in merge
89 lines
2.2 KiB
Vue
89 lines
2.2 KiB
Vue
<template>
|
|
<RouterView />
|
|
<WaitingForRestart ref="globalWaitingRef" />
|
|
|
|
<!-- 全局唯一 snackbar -->
|
|
<v-snackbar
|
|
v-if="toastStore.current"
|
|
v-model="snackbarShow"
|
|
:color="toastStore.current.color"
|
|
:timeout="toastStore.current.timeout"
|
|
:multi-line="toastStore.current.multiLine"
|
|
:location="snackbarLocation"
|
|
close-on-back
|
|
>
|
|
{{ toastStore.current.message }}
|
|
<template v-if="toastStore.current.closable" #actions>
|
|
<v-btn variant="text" @click="snackbarShow = false"> 关闭 </v-btn>
|
|
</template>
|
|
</v-snackbar>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { RouterView } from "vue-router";
|
|
import { computed, onBeforeUnmount, onMounted, ref, watch } from "vue";
|
|
import { useToastStore } from "@/stores/toast";
|
|
import { useCustomizerStore } from "@/stores/customizer";
|
|
import WaitingForRestart from "@/components/shared/WaitingForRestart.vue";
|
|
|
|
type SnackAnchor =
|
|
| "top"
|
|
| "bottom"
|
|
| "start"
|
|
| "end"
|
|
| "center"
|
|
| "center center"
|
|
| "top center"
|
|
| "top start"
|
|
| "top end"
|
|
| "bottom center"
|
|
| "bottom start"
|
|
| "bottom end";
|
|
|
|
const toastStore = useToastStore();
|
|
const customizer = useCustomizerStore();
|
|
const globalWaitingRef = ref<InstanceType<typeof WaitingForRestart> | null>(null);
|
|
let disposeTrayRestartListener: (() => void) | null = null;
|
|
|
|
const snackbarShow = computed({
|
|
get: () => !!toastStore.current,
|
|
set: (val) => {
|
|
if (!val) toastStore.shift();
|
|
},
|
|
});
|
|
|
|
const snackbarLocation = computed<SnackAnchor | undefined>(() => toastStore.current?.location as SnackAnchor | undefined);
|
|
|
|
// 统一监听 uiTheme 变化并同步到 Vuetify
|
|
watch(
|
|
() => customizer.uiTheme,
|
|
(newTheme) => {
|
|
if (newTheme) {
|
|
}
|
|
},
|
|
{ immediate: true },
|
|
);
|
|
|
|
onMounted(() => {
|
|
const desktopBridge = window.astrbotDesktop;
|
|
if (!desktopBridge?.onTrayRestartBackend) {
|
|
return;
|
|
}
|
|
disposeTrayRestartListener = desktopBridge.onTrayRestartBackend(async () => {
|
|
try {
|
|
await globalWaitingRef.value?.check?.();
|
|
} catch (error) {
|
|
globalWaitingRef.value?.stop?.();
|
|
console.error("Tray restart backend failed:", error);
|
|
}
|
|
});
|
|
});
|
|
|
|
onBeforeUnmount(() => {
|
|
if (disposeTrayRestartListener) {
|
|
disposeTrayRestartListener();
|
|
disposeTrayRestartListener = null;
|
|
}
|
|
});
|
|
</script>
|