mirror of
https://github.com/Megghy/vtsuru.live.git
synced 2025-12-08 11:26:56 +08:00
feat: Enhance message content handling and improve UI components
- Updated `getShowContentParts` function to handle message content more robustly, ensuring proper display of content parts. - Refactored `GamepadViewer.vue` to use async component loading for `GamepadDisplay`, added a toggle for real-time preview. - Implemented debounced search functionality in `PointGoodsView.vue` for improved performance during keyword searches. - Enhanced `PointOrderView.vue` with order filtering capabilities and added statistics display for better user insights. - Improved `PointUserHistoryView.vue` by adding export functionality for history data and enhanced filtering options. - Updated `PointUserLayout.vue` to improve card styling and tab navigation experience. - Refined `PointUserSettings.vue` layout for better user interaction and added responsive design adjustments. - Adjusted `vite.config.mts` for better dependency management and build optimization.
This commit is contained in:
@@ -1,66 +1,121 @@
|
||||
<script setup lang="ts">
|
||||
import { editor } from 'monaco-editor' // 全部导入
|
||||
import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
import { onMounted, onBeforeUnmount, ref, watch } from 'vue'
|
||||
import * as monaco from 'monaco-editor'
|
||||
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
|
||||
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'
|
||||
import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker'
|
||||
import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker'
|
||||
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'
|
||||
|
||||
const { language, height = 400 } = defineProps<{
|
||||
|
||||
const { language, height = 400, theme = 'vs-dark', options, path } = defineProps<{
|
||||
language: string
|
||||
height?: number
|
||||
theme?: string
|
||||
options?: Record<string, any>
|
||||
path?: string
|
||||
}>()
|
||||
|
||||
const value = defineModel<string>('value')
|
||||
|
||||
const editorContainer = ref<HTMLElement>()
|
||||
let editorInstance: editor.IStandaloneCodeEditor | null = null
|
||||
// 在创建编辑器前确保容器存在
|
||||
const ready = ref(false)
|
||||
const initError = ref<string | null>(null)
|
||||
const containerRef = ref<HTMLElement | null>(null)
|
||||
let editor: monaco.editor.IStandaloneCodeEditor | null = null
|
||||
let model: monaco.editor.ITextModel | null = null
|
||||
let createdModel = false
|
||||
|
||||
onMounted(() => {
|
||||
if (!editorContainer.value) return
|
||||
|
||||
editorInstance = editor.create(editorContainer.value, {
|
||||
value: value.value,
|
||||
language,
|
||||
minimap: {
|
||||
enabled: true,
|
||||
},
|
||||
colorDecorators: true,
|
||||
automaticLayout: true,
|
||||
})
|
||||
|
||||
editorInstance.onDidChangeModelContent(() => {
|
||||
if (editorInstance) {
|
||||
const currentValue = editorInstance.getValue()
|
||||
if (currentValue !== value.value) {
|
||||
value.value = currentValue
|
||||
}
|
||||
// 配置 Monaco Environment
|
||||
;(self as any).MonacoEnvironment = {
|
||||
getWorker(_: string, label: string) {
|
||||
if (label === 'json') {
|
||||
return new jsonWorker()
|
||||
}
|
||||
})
|
||||
if (label === 'css' || label === 'scss' || label === 'less') {
|
||||
return new cssWorker()
|
||||
}
|
||||
if (label === 'html' || label === 'handlebars' || label === 'razor') {
|
||||
return new htmlWorker()
|
||||
}
|
||||
if (label === 'typescript' || label === 'javascript') {
|
||||
return new tsWorker()
|
||||
}
|
||||
return new editorWorker()
|
||||
},
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const uri = monaco.Uri.parse(
|
||||
path ?? `inmemory://model/${crypto?.randomUUID?.() ?? Math.random().toString(36).slice(2)}.${language ?? 'txt'}`,
|
||||
)
|
||||
model = monaco.editor.getModel(uri)
|
||||
if (!model) {
|
||||
model = monaco.editor.createModel(value?.value ?? '', language, uri)
|
||||
createdModel = true
|
||||
}
|
||||
|
||||
editor = monaco.editor.create(containerRef.value!, {
|
||||
model,
|
||||
theme,
|
||||
automaticLayout: true,
|
||||
...(options ?? {}),
|
||||
})
|
||||
|
||||
// 同步 model -> v-model
|
||||
editor.onDidChangeModelContent(() => {
|
||||
const current = model!.getValue()
|
||||
if (current !== value.value) value.value = current
|
||||
})
|
||||
|
||||
ready.value = true
|
||||
} catch (err) {
|
||||
console.error('Monaco 初始化失败:', err)
|
||||
initError.value = (err as Error)?.message ?? String(err)
|
||||
}
|
||||
})
|
||||
|
||||
// v-model 变更 -> model
|
||||
watch(value, (nv) => {
|
||||
if (model && typeof nv === 'string' && nv !== model.getValue()) {
|
||||
model.setValue(nv)
|
||||
}
|
||||
})
|
||||
|
||||
// 语言切换
|
||||
watch(() => language, (lang) => {
|
||||
if (model && lang) {
|
||||
monaco.editor.setModelLanguage(model, lang)
|
||||
}
|
||||
})
|
||||
|
||||
// 主题切换
|
||||
watch(() => theme, (t) => {
|
||||
if (editor && t) {
|
||||
editor.updateOptions({ theme: t })
|
||||
}
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (editorInstance) {
|
||||
editorInstance.dispose()
|
||||
editorInstance = null
|
||||
}
|
||||
})
|
||||
|
||||
watch(value, (newValue) => {
|
||||
if (editorInstance && newValue !== editorInstance.getValue()) {
|
||||
editorInstance.setValue(newValue ?? '')
|
||||
}
|
||||
})
|
||||
|
||||
watch(() => language, (newLang) => {
|
||||
if (editorInstance) {
|
||||
const model = editorInstance.getModel()
|
||||
if (model) {
|
||||
editor.setModelLanguage(model, newLang)
|
||||
try {
|
||||
editor?.dispose()
|
||||
// 仅销毁我们创建的临时 model,避免复用路径时把共享 model 误删
|
||||
if (createdModel && model) {
|
||||
model.dispose()
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
ref="editorContainer"
|
||||
:style="`height: ${height}px;`"
|
||||
/>
|
||||
<div :style="`height: ${height}px; width: 100%; position: relative;`">
|
||||
<div v-if="!ready" :style="`position:absolute; inset:0; display:flex; align-items:center; justify-content:center; color: var(--text-color, #888); text-align:center; padding:8px;`">
|
||||
<div>
|
||||
<div>正在加载编辑器…</div>
|
||||
<div v-if="initError" style="margin-top:6px; color:#d9534f; font-size:12px;">{{ initError }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ref="containerRef" :style="`height: ${height}px; width: 100%;`"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user