feat: implement custom Jinja2 syntax highlighting for rename templates and notification templates using VAceEditor

This commit is contained in:
jxxghp
2026-04-25 11:20:15 +08:00
parent f9e74cf436
commit bdbaf503ca
3 changed files with 577 additions and 20 deletions

View File

@@ -10,9 +10,11 @@ import StorageCard from '@/components/cards/StorageCard.vue'
import ProgressDialog from '@/components/dialog/ProgressDialog.vue'
import CategoryEditDialog from '@/components/dialog/CategoryEditDialog.vue'
import { useI18n } from 'vue-i18n'
import { useTheme } from 'vuetify'
import { storageAttributes } from '@/api/constants'
const { t } = useI18n()
const { global: globalTheme } = useTheme()
// 所有下载目录
const directories = ref<TransferDirectoryConf[]>([])
@@ -58,6 +60,30 @@ const SystemSettings = ref<any>({
},
})
// 编辑器主题
const editorTheme = computed(() => (globalTheme.name.value === 'light' ? 'github' : 'monokai'))
const renameEditorOptions = {
fontSize: 14,
tabSize: 2,
showLineNumbers: true,
showGutter: true,
}
const movieRenameFormat = computed({
get: () => SystemSettings.value.Basic.MOVIE_RENAME_FORMAT ?? '',
set: (value: string) => {
SystemSettings.value.Basic.MOVIE_RENAME_FORMAT = value || null
},
})
const tvRenameFormat = computed({
get: () => SystemSettings.value.Basic.TV_RENAME_FORMAT ?? '',
set: (value: string) => {
SystemSettings.value.Basic.TV_RENAME_FORMAT = value || null
},
})
// 加载系统设置
async function loadSystemSettings() {
try {
@@ -346,26 +372,48 @@ onMounted(() => {
/>
</VCol>
<VCol cols="12">
<VTextarea
v-model="SystemSettings.Basic.MOVIE_RENAME_FORMAT"
:label="t('setting.directory.movieRenameFormat')"
:hint="t('setting.directory.movieRenameFormatHint')"
persistent-hint
clearable
active
prepend-inner-icon="mdi-movie-open"
/>
<div class="rename-format-editor">
<div class="rename-format-editor__label">
<VIcon icon="mdi-movie-open" size="20" class="me-2" />
<span>{{ t('setting.directory.movieRenameFormat') }}</span>
</div>
<VAceEditor
v-model:value="movieRenameFormat"
lang="jinja2"
:theme="editorTheme"
:options="renameEditorOptions"
:print-margin="false"
:min-lines="4"
:max-lines="12"
wrap
class="rename-format-editor__ace rounded"
/>
<div class="rename-format-editor__hint">
{{ t('setting.directory.movieRenameFormatHint') }}
</div>
</div>
</VCol>
<VCol cols="12">
<VTextarea
v-model="SystemSettings.Basic.TV_RENAME_FORMAT"
:label="t('setting.directory.tvRenameFormat')"
:hint="t('setting.directory.tvRenameFormatHint')"
persistent-hint
clearable
active
prepend-inner-icon="mdi-television"
/>
<div class="rename-format-editor">
<div class="rename-format-editor__label">
<VIcon icon="mdi-television" size="20" class="me-2" />
<span>{{ t('setting.directory.tvRenameFormat') }}</span>
</div>
<VAceEditor
v-model:value="tvRenameFormat"
lang="jinja2"
:theme="editorTheme"
:options="renameEditorOptions"
:print-margin="false"
:min-lines="4"
:max-lines="12"
wrap
class="rename-format-editor__ace rounded"
/>
<div class="rename-format-editor__hint">
{{ t('setting.directory.tvRenameFormatHint') }}
</div>
</div>
</VCol>
</VRow>
</VCardText>
@@ -392,3 +440,28 @@ onMounted(() => {
@done="loadMediaCategories"
/>
</template>
<style scoped>
.rename-format-editor__label {
display: flex;
align-items: center;
color: rgba(var(--v-theme-on-surface), 0.78);
font-size: 0.875rem;
font-weight: 500;
line-height: 1.375rem;
margin-block-end: 0.5rem;
}
.rename-format-editor__ace {
overflow: hidden;
border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
min-block-size: 8rem;
}
.rename-format-editor__hint {
color: rgba(var(--v-theme-on-surface), 0.6);
font-size: 0.75rem;
line-height: 1.25rem;
margin-block-start: 0.375rem;
}
</style>

View File

@@ -480,8 +480,9 @@ onMounted(() => {
</VCardItem>
<VCardText class="py-0">
<VAceEditor
:key="`${currentTemplate}-jinja2-json`"
v-model:value="editorContent"
lang="json"
lang="jinja2_json"
:theme="editorTheme"
class="w-full h-full min-h-[30rem] rounded"
/>