Skip to content

Commit a089474

Browse files
committed
Optimize startup flow and refresh terminal UX
1 parent 1026818 commit a089474

28 files changed

Lines changed: 1020 additions & 490 deletions

frontend/package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@
2929
"devDependencies": {
3030
"@hey-api/openapi-ts": "^0.53.3",
3131
"@rushstack/eslint-patch": "^1.3.3",
32-
"@tsconfig/node20": "^20.1.2",
33-
"@types/node": "^20.11.10",
32+
"@tsconfig/node22": "^22.0.5",
33+
"@types/node": "^22.19.17",
3434
"@types/uuid": "^10.0.0",
35-
"@vitejs/plugin-vue": "^5.0.3",
35+
"@vitejs/plugin-vue": "^5.2.4",
3636
"@vue/eslint-config-prettier": "^8.0.0",
3737
"@vue/eslint-config-typescript": "^12.0.0",
3838
"@vue/tsconfig": "^0.5.1",
@@ -45,9 +45,9 @@
4545
"postcss-nesting": "^13.0.0",
4646
"prettier": "^3.0.3",
4747
"tailwindcss": "^3.4.1",
48-
"typescript": "~5.3.0",
48+
"typescript": "^5.9.3",
4949
"uuid": "^10.0.0",
50-
"vite": "^5.0.11",
51-
"vue-tsc": "^1.8.27"
50+
"vite": "^5.4.19",
51+
"vue-tsc": "^3.2.7"
5252
}
5353
}

frontend/src/assets/main.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@import 'material-symbols';
1+
@import 'material-symbols/outlined.css';
22

33
@tailwind base;
44
@tailwind components;

frontend/src/client/api/schemas.gen.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,16 @@ export const NoneBotProjectMetaSchema = {
703703
type: 'boolean',
704704
default: false
705705
},
706+
runtime_state: {
707+
title: 'Runtime State',
708+
type: 'string',
709+
default: 'stopped'
710+
},
711+
startup_duration_seconds: {
712+
title: 'Startup Duration Seconds',
713+
type: 'number',
714+
default: 0
715+
},
706716
use_env: {
707717
title: 'Use Env',
708718
type: 'string',

frontend/src/client/api/services.gen.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
// This file is auto-generated by @hey-api/openapi-ts
22

3-
import { createClient, createConfig, type Options } from '@hey-api/client-fetch'
3+
import {
4+
createClient,
5+
createConfig,
6+
type Options
7+
} from '@hey-api/client-fetch'
48
import type {
59
AuthTokenV1AuthLoginPostData,
610
AuthTokenV1AuthLoginPostError,
@@ -102,7 +106,7 @@ import type {
102106
GetDriversV1ProjectDriversGetResponse
103107
} from './types.gen'
104108

105-
export const client = createClient(createConfig())
109+
export const client: ReturnType<typeof createClient> = createClient(createConfig())
106110

107111
export class AuthService {
108112
/**

frontend/src/client/api/types.gen.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ export type NoneBotProjectMeta = {
187187
discovered_plugin_dirs?: Array<string>
188188
builtin_plugins: Array<string>
189189
is_running?: boolean
190+
runtime_state?: string
191+
startup_duration_seconds?: number
190192
use_env?: string
191193
use_run_script?: boolean
192194
run_script_name?: string

frontend/src/client/init.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@ import { clearAuthToken, getAuthToken } from './auth'
77
import { getErrorMessage } from './utils'
88
import { useNoneBotStore, useToastStore } from '@/stores'
99
import App from '@/App.vue'
10-
import './useMonacoWorker'
10+
11+
type ClientRequest = Parameters<typeof client.interceptors.request.use>[0] extends (
12+
request: infer T,
13+
...args: any[]
14+
) => any
15+
? T
16+
: Request
1117

1218
const installVuePlugins = (app: VueAPP) => {
1319
app.use(createPinia())
@@ -34,7 +40,7 @@ export const initWebUI = async () => {
3440
return
3541
}
3642

37-
client.interceptors.request.use((request) => {
43+
client.interceptors.request.use((request: ClientRequest) => {
3844
request.headers.set('Authorization', `Bearer ${getAuthToken()}`)
3945
return request
4046
})
Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,24 @@
1-
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js'
1+
let monacoReady: Promise<void> | null = null
22

3-
self.MonacoEnvironment = {
4-
getWorkerUrl: () => {
5-
return './editor.worker.bundle.js'
3+
export const ensureMonacoWorker = async () => {
4+
if (!monacoReady) {
5+
monacoReady = (async () => {
6+
const monaco = await import('monaco-editor/esm/vs/editor/editor.api.js')
7+
const target = globalThis as typeof globalThis & {
8+
MonacoEnvironment?: {
9+
getWorkerUrl: () => string
10+
}
11+
}
12+
13+
if (!target.MonacoEnvironment) {
14+
target.MonacoEnvironment = {
15+
getWorkerUrl: () => './editor.worker.bundle.js'
16+
}
17+
}
18+
19+
void monaco
20+
})()
621
}
22+
23+
return monacoReady
724
}

frontend/src/components/EditorItem.vue

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
11
<script setup lang="ts">
2-
import { editor as monacoEditor } from 'monaco-editor/esm/vs/editor/editor.api.js'
2+
import { ensureMonacoWorker } from '@/client/useMonacoWorker'
33
import { onMounted, ref, watch } from 'vue'
4+
import type { editor as MonacoEditorNamespace } from 'monaco-editor/esm/vs/editor/editor.api.js'
45
56
const props = defineProps<{
67
modelValue: string
7-
editorOptional: Partial<monacoEditor.IStandaloneEditorConstructionOptions>
8+
editorOptional: Partial<MonacoEditorNamespace.IStandaloneEditorConstructionOptions>
89
}>()
910
1011
const emit = defineEmits<{
11-
editor: [value: monacoEditor.IStandaloneCodeEditor]
12+
editor: [value: MonacoEditorNamespace.IStandaloneCodeEditor]
1213
updateValue: [value: string]
1314
}>()
1415
1516
const editorContainer = ref<HTMLDivElement>()
16-
let editor: monacoEditor.IStandaloneCodeEditor
17+
let editor: MonacoEditorNamespace.IStandaloneCodeEditor
18+
19+
onMounted(async () => {
20+
await ensureMonacoWorker()
21+
const { editor: monacoEditor } = await import('monaco-editor/esm/vs/editor/editor.api.js')
1722
18-
onMounted(() => {
1923
editor = monacoEditor.create(editorContainer.value!, {
2024
value: props.modelValue,
2125
...props.editorOptional

frontend/src/components/header/BotChoose.vue

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script setup lang="ts">
22
import { ref } from 'vue'
33
import { useNoneBotStore } from '@/stores'
4+
import { getRuntimeState } from '@/utils/runtimeState'
45
import DrawerItem from '@/components/DrawerItem.vue'
56
import CreateBotIndex from '@/components/Modals/CreateBot/CreateBotIndex.vue'
67
@@ -62,7 +63,24 @@ const drawerRef = ref<InstanceType<typeof DrawerItem> | null>(null)
6263
>
6364
选择中
6465
</div>
65-
<div v-if="bot.is_running" class="badge badge-success text-base-100">运行中</div>
66+
<div
67+
class="badge"
68+
:class="
69+
getRuntimeState(bot) === 'running'
70+
? 'badge-success text-base-100'
71+
: getRuntimeState(bot) === 'starting'
72+
? 'badge-warning'
73+
: 'badge-ghost'
74+
"
75+
>
76+
{{
77+
getRuntimeState(bot) === 'running'
78+
? '运行中'
79+
: getRuntimeState(bot) === 'starting'
80+
? '启动中'
81+
: '未运行'
82+
}}
83+
</div>
6684
</div>
6785
</div>
6886
</div>

frontend/src/composables/useInstanceMessageCount.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { computed, onMounted, onUnmounted, ref, watch, type Ref } from 'vue'
22
import { getAuthToken } from '@/client/auth'
33
import { generateURLForWebUI } from '@/client/utils'
44
import type { NoneBotProjectMeta, ProcessLog } from '@/client/api'
5+
import { getRuntimeState } from '@/utils/runtimeState'
56

67
const INSTANCE_MESSAGE_PATTERNS = [
78
/"post_type"\s*:\s*"message"/i,
@@ -53,7 +54,7 @@ export const useInstanceMessageCount = (
5354

5455
const syncMessageCount = async () => {
5556
const projectId = selectedBot.value?.project_id || ''
56-
if (!projectId || !selectedBot.value?.is_running) {
57+
if (!projectId || getRuntimeState(selectedBot.value) !== 'running') {
5758
messageCount.value = 0
5859
return
5960
}
@@ -77,7 +78,7 @@ export const useInstanceMessageCount = (
7778
clearMessagePollTimer()
7879
void syncMessageCount()
7980

80-
if (!selectedBot.value?.project_id || !selectedBot.value?.is_running) {
81+
if (!selectedBot.value?.project_id || getRuntimeState(selectedBot.value) !== 'running') {
8182
return
8283
}
8384

@@ -95,7 +96,7 @@ export const useInstanceMessageCount = (
9596
})
9697

9798
watch(
98-
computed(() => `${selectedBot.value?.project_id ?? ''}:${selectedBot.value?.is_running ? '1' : '0'}`),
99+
computed(() => `${selectedBot.value?.project_id ?? ''}:${getRuntimeState(selectedBot.value)}`),
99100
() => {
100101
restartMessagePolling()
101102
}

0 commit comments

Comments
 (0)