feat: 修改终端配置.
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package com.orion.ops.module.infra.handler.preference.model;
|
package com.orion.ops.module.infra.handler.preference.model;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
@@ -24,9 +25,50 @@ public class TerminalPreferenceModel implements PreferenceModel {
|
|||||||
private String darkTheme;
|
private String darkTheme;
|
||||||
|
|
||||||
@Schema(description = "终端主题")
|
@Schema(description = "终端主题")
|
||||||
private JSONObject terminalTheme;
|
private JSONObject themeSchema;
|
||||||
|
|
||||||
@Schema(description = "显示设置")
|
@Schema(description = "显示设置")
|
||||||
private JSONObject viewSetting;
|
private JSONObject displaySetting;
|
||||||
|
|
||||||
|
@Schema(description = "背景设置")
|
||||||
|
private JSONObject backgroundSetting;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class DisplaySettingModel {
|
||||||
|
|
||||||
|
@Schema(description = "字体样式")
|
||||||
|
private String fontFamily;
|
||||||
|
|
||||||
|
@Schema(description = "字体大小")
|
||||||
|
private Integer fontSize;
|
||||||
|
|
||||||
|
@Schema(description = "行高")
|
||||||
|
private Double lineHeight;
|
||||||
|
|
||||||
|
@Schema(description = "文本字重")
|
||||||
|
private String fontWeight;
|
||||||
|
|
||||||
|
@Schema(description = "加粗字重")
|
||||||
|
private String fontWeightBold;
|
||||||
|
|
||||||
|
@Schema(description = "光标样式")
|
||||||
|
private String cursorStyle;
|
||||||
|
|
||||||
|
@Schema(description = "光标闪烁")
|
||||||
|
private Boolean cursorBlink;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转为 json
|
||||||
|
*
|
||||||
|
* @return json
|
||||||
|
*/
|
||||||
|
public JSONObject toJson() {
|
||||||
|
return JSON.parseObject(JSON.toJSONString(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,19 @@ public class TerminalPreferenceStrategy implements IPreferenceStrategy<TerminalP
|
|||||||
public TerminalPreferenceModel getDefault() {
|
public TerminalPreferenceModel getDefault() {
|
||||||
return TerminalPreferenceModel.builder()
|
return TerminalPreferenceModel.builder()
|
||||||
.darkTheme("dark")
|
.darkTheme("dark")
|
||||||
.terminalTheme(new JSONObject())
|
.themeSchema(new JSONObject())
|
||||||
.viewSetting(new JSONObject())
|
.displaySetting(TerminalPreferenceModel.DisplaySettingModel.builder()
|
||||||
|
.fontFamily("_")
|
||||||
|
.fontSize(15)
|
||||||
|
.lineHeight(1.00)
|
||||||
|
.fontWeight("normal")
|
||||||
|
.fontWeightBold("bold")
|
||||||
|
.cursorStyle("bar")
|
||||||
|
.cursorBlink(true)
|
||||||
|
.build()
|
||||||
|
.toJson()
|
||||||
|
)
|
||||||
|
.backgroundSetting(new JSONObject())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { TerminalPreference, TerminalState, TerminalTheme } from './types';
|
import type { TerminalDisplaySetting, TerminalPreference, TerminalState, TerminalThemeSchema } from './types';
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { getPreference, updatePreferencePartial } from '@/api/user/preference';
|
import { getPreference, updatePreferencePartial } from '@/api/user/preference';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { Message } from '@arco-design/web-vue';
|
||||||
@@ -24,8 +24,9 @@ export default defineStore('terminal', {
|
|||||||
}),
|
}),
|
||||||
preference: {
|
preference: {
|
||||||
darkTheme: 'auto',
|
darkTheme: 'auto',
|
||||||
terminalTheme: {} as TerminalTheme,
|
themeSchema: {} as TerminalThemeSchema,
|
||||||
}
|
displaySetting: {} as TerminalDisplaySetting
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
@@ -39,14 +40,14 @@ export default defineStore('terminal', {
|
|||||||
try {
|
try {
|
||||||
const { data } = await getPreference<TerminalPreference>('TERMINAL');
|
const { data } = await getPreference<TerminalPreference>('TERMINAL');
|
||||||
// 设置默认终端主题
|
// 设置默认终端主题
|
||||||
if (!data.config.terminalTheme?.name) {
|
if (!data.config.themeSchema?.name) {
|
||||||
data.config.terminalTheme = DEFAULT_SCHEMA;
|
data.config.themeSchema = DEFAULT_SCHEMA;
|
||||||
}
|
}
|
||||||
this.preference = data.config;
|
this.preference = data.config;
|
||||||
// 设置暗色主题
|
// 设置暗色主题
|
||||||
const userDarkTheme = data.config.darkTheme;
|
const userDarkTheme = data.config.darkTheme;
|
||||||
if (userDarkTheme === DarkTheme.AUTO) {
|
if (userDarkTheme === DarkTheme.AUTO) {
|
||||||
this.isDarkTheme = data.config.terminalTheme?.dark === true;
|
this.isDarkTheme = data.config.themeSchema?.dark === true;
|
||||||
} else {
|
} else {
|
||||||
this.isDarkTheme = userDarkTheme === DarkTheme.DARK;
|
this.isDarkTheme = userDarkTheme === DarkTheme.DARK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,12 @@ export interface TerminalState {
|
|||||||
// 终端配置
|
// 终端配置
|
||||||
export interface TerminalPreference {
|
export interface TerminalPreference {
|
||||||
darkTheme: string,
|
darkTheme: string,
|
||||||
terminalTheme: TerminalTheme,
|
themeSchema: TerminalThemeSchema,
|
||||||
|
displaySetting: TerminalDisplaySetting,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 终端主题
|
// 终端主题
|
||||||
export interface TerminalTheme {
|
export interface TerminalThemeSchema {
|
||||||
name: string;
|
name: string;
|
||||||
dark: boolean;
|
dark: boolean;
|
||||||
background: string;
|
background: string;
|
||||||
@@ -41,3 +42,14 @@ export interface TerminalTheme {
|
|||||||
|
|
||||||
[key: string]: unknown;
|
[key: string]: unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 显示设置
|
||||||
|
export interface TerminalDisplaySetting {
|
||||||
|
fontFamily?: string;
|
||||||
|
fontSize?: number;
|
||||||
|
lineHeight?: number;
|
||||||
|
fontWeight?: string | number;
|
||||||
|
fontWeightBold?: string | number;
|
||||||
|
cursorStyle?: string;
|
||||||
|
cursorBlink?: boolean;
|
||||||
|
}
|
||||||
|
|||||||
@@ -204,16 +204,16 @@ body[terminal-theme='dark'] .host-layout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 终端设置容器
|
// 终端设置容器
|
||||||
@setting-container-width: 1180px;
|
|
||||||
.terminal-setting-container {
|
.terminal-setting-container {
|
||||||
padding: 32px 16px;
|
padding: 32px 16px;
|
||||||
width: @setting-container-width;
|
width: max-content;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
.terminal-setting-title {
|
.terminal-setting-title {
|
||||||
margin: 0 0 24px 0;
|
margin: 0 0 24px 0;
|
||||||
|
user-select: none;
|
||||||
color: var(--color-content-text-3);
|
color: var(--color-content-text-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,6 +230,7 @@ body[terminal-theme='dark'] .host-layout {
|
|||||||
|
|
||||||
.terminal-setting-subtitle {
|
.terminal-setting-subtitle {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
user-select: none;
|
||||||
color: var(--color-content-text-3);
|
color: var(--color-content-text-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
import type { TabItem } from '../../types/terminal.const';
|
import type { TabItem } from '../../types/terminal.const';
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import { TabType, InnerTabs } from '../../types/terminal.const';
|
import { TabType, InnerTabs } from '../../types/terminal.const';
|
||||||
import TerminalViewSetting from '../theme-setting/terminal-view-setting.vue';
|
import TerminalViewSetting from '../view-setting/terminal-view-setting.vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
|
|||||||
@@ -1,74 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="terminal-setting-block">
|
|
||||||
<!-- 顶部 -->
|
|
||||||
<div class="terminal-setting-subtitle-wrapper">
|
|
||||||
<h3 class="terminal-setting-subtitle">
|
|
||||||
字体设置
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
<!-- 内容区域 -->
|
|
||||||
<div class="terminal-setting-body">
|
|
||||||
<div class="terminal-setting-form">
|
|
||||||
123
|
|
||||||
</div>
|
|
||||||
<!-- 预览区域 -->
|
|
||||||
<div class="terminal-example">
|
|
||||||
<div class="terminal-example-wrapper"
|
|
||||||
:style="{ background: terminalStore.preference.terminalTheme.background }">
|
|
||||||
<terminal-example :theme="terminalStore.preference.terminalTheme"
|
|
||||||
ref="previewTerminal" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
export default {
|
|
||||||
name: 'TerminalFontBlock'
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ref, watch } from 'vue';
|
|
||||||
import TerminalExample from '../theme-setting/terminal-example.vue';
|
|
||||||
import { useTerminalStore } from '@/store';
|
|
||||||
|
|
||||||
const terminalStore = useTerminalStore();
|
|
||||||
|
|
||||||
const previewTerminal = ref();
|
|
||||||
|
|
||||||
watch(() => terminalStore.preference.terminalTheme, (v) => {
|
|
||||||
if (!v) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const options = previewTerminal.value?.term?.options;
|
|
||||||
options && (options.theme = v);
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="less" scoped>
|
|
||||||
@terminal-width: 458px;
|
|
||||||
@terminal-height: 138px;
|
|
||||||
|
|
||||||
.terminal-setting-body {
|
|
||||||
height: 248px;
|
|
||||||
width: 100%;
|
|
||||||
border: 1px solid var(--color-border-2);
|
|
||||||
border-radius: 4px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.terminal-example {
|
|
||||||
margin: auto 16px 16px 0;
|
|
||||||
|
|
||||||
&-wrapper {
|
|
||||||
border-radius: 4px;
|
|
||||||
width: calc(@terminal-width - 16px);
|
|
||||||
height: @terminal-height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
@@ -0,0 +1,224 @@
|
|||||||
|
<template>
|
||||||
|
<div class="terminal-setting-block">
|
||||||
|
<!-- 顶部 -->
|
||||||
|
<div class="terminal-setting-subtitle-wrapper">
|
||||||
|
<h3 class="terminal-setting-subtitle">
|
||||||
|
显示设置
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<!-- 内容区域 -->
|
||||||
|
<div class="terminal-setting-body">
|
||||||
|
<div class="terminal-setting-form">
|
||||||
|
<a-form :model="formModel" layout="vertical">
|
||||||
|
<a-space>
|
||||||
|
<!-- 字体样式 -->
|
||||||
|
<a-form-item field="fontFamily" label="字体样式">
|
||||||
|
<a-select v-model="formModel.fontFamily"
|
||||||
|
class="form-item form-item-font-family"
|
||||||
|
placeholder="请选择字体样式"
|
||||||
|
:options="toOptions(fontFamilyKey)"
|
||||||
|
:allow-create="true"
|
||||||
|
:filter-option="labelFilter">
|
||||||
|
<template #option="{ data }">
|
||||||
|
<span :style="{ fontFamily: data.value }">{{ data.label }}</span>
|
||||||
|
</template>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
<!-- 字体大小 -->
|
||||||
|
<a-form-item field="fontSize" label="字体大小">
|
||||||
|
<a-select v-model="formModel.fontSize"
|
||||||
|
class="form-item form-item-font-size"
|
||||||
|
placeholder="请选择字体大小"
|
||||||
|
:options="toOptions(fontSizeKey)" />
|
||||||
|
</a-form-item>
|
||||||
|
<!-- 行高 -->
|
||||||
|
<a-form-item field="lineHeight" label="行高">
|
||||||
|
<a-input-number v-model="formModel.lineHeight"
|
||||||
|
class="form-item form-item-line-height"
|
||||||
|
placeholder="请输入行高"
|
||||||
|
:precision="2"
|
||||||
|
:min="1"
|
||||||
|
:max="2"
|
||||||
|
hide-button />
|
||||||
|
</a-form-item>
|
||||||
|
</a-space>
|
||||||
|
<a-space>
|
||||||
|
<!-- 普通文本字重 -->
|
||||||
|
<a-form-item field="fontWeight" label="普通文本字重">
|
||||||
|
<a-select v-model="formModel.fontWeight"
|
||||||
|
class="form-item form-item-font-weight"
|
||||||
|
placeholder="请选择字重"
|
||||||
|
:options="toOptions(fontWeightKey)" />
|
||||||
|
</a-form-item>
|
||||||
|
<!-- 加粗文本字重 -->
|
||||||
|
<a-form-item field="fontWeightBold" label="加粗文本字重">
|
||||||
|
<a-select v-model="formModel.fontWeightBold"
|
||||||
|
class="form-item form-item-font-bold-weight"
|
||||||
|
placeholder="请选择字重"
|
||||||
|
:options="toOptions(fontWeightKey)" />
|
||||||
|
</a-form-item>
|
||||||
|
</a-space>
|
||||||
|
<a-space>
|
||||||
|
<!-- 光标样式 -->
|
||||||
|
<a-form-item field="cursorStyle" label="光标样式">
|
||||||
|
<a-radio-group type="button"
|
||||||
|
v-model="formModel.cursorStyle"
|
||||||
|
class="form-item form-item-cursor-style usn"
|
||||||
|
:options="toOptions(cursorStyleKey)" />
|
||||||
|
</a-form-item>
|
||||||
|
<!-- 光标闪烁 -->
|
||||||
|
<a-form-item field="cursorBlink" label="光标是否闪烁">
|
||||||
|
<a-switch v-model="formModel.cursorBlink"
|
||||||
|
type="round"
|
||||||
|
class="form-item form-item-cursor-blink" />
|
||||||
|
</a-form-item>
|
||||||
|
</a-space>
|
||||||
|
</a-form>
|
||||||
|
</div>
|
||||||
|
<!-- 预览区域 -->
|
||||||
|
<div class="terminal-example">
|
||||||
|
<span class="terminal-example-label">预览效果</span>
|
||||||
|
<div class="terminal-example-wrapper"
|
||||||
|
:style="{ background: preference.themeSchema.background }">
|
||||||
|
<terminal-example :theme="preference.themeSchema"
|
||||||
|
ref="previewTerminal" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'TerminalFontBlock'
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { TerminalDisplaySetting } from '@/store/modules/terminal/types';
|
||||||
|
import { onMounted, ref, watch } from 'vue';
|
||||||
|
import { useDictStore, useTerminalStore } from '@/store';
|
||||||
|
import { fontFamilyKey, fontSizeKey, fontWeightKey, fontFamilySuffix, cursorStyleKey } from '../../types/terminal.const';
|
||||||
|
import { labelFilter } from '@/types/form';
|
||||||
|
import { useDebounceFn } from '@vueuse/core';
|
||||||
|
import TerminalExample from '../view-setting/terminal-example.vue';
|
||||||
|
|
||||||
|
const { toOptions } = useDictStore();
|
||||||
|
const { preference, updatePreference } = useTerminalStore();
|
||||||
|
|
||||||
|
// 同步用户偏好 - 防抖函数
|
||||||
|
const sync = useDebounceFn(updatePreference, 1500);
|
||||||
|
const previewTerminal = ref();
|
||||||
|
const formModel = ref<TerminalDisplaySetting>({});
|
||||||
|
|
||||||
|
// 监听主题变化
|
||||||
|
watch(() => preference.themeSchema, (v) => {
|
||||||
|
if (!v) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const options = previewTerminal.value?.term?.options;
|
||||||
|
options && (options.theme = v);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 监听内容变化
|
||||||
|
watch(formModel, (v) => {
|
||||||
|
if (!v) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const options = previewTerminal.value?.term?.options;
|
||||||
|
if (!options) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 修改配置
|
||||||
|
Object.keys(v).forEach(key => {
|
||||||
|
if (key === 'fontFamily') {
|
||||||
|
options[key] = (formModel.value as any)[key] + fontFamilySuffix;
|
||||||
|
} else {
|
||||||
|
options[key] = (formModel.value as any)[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
preference.displaySetting = formModel.value;
|
||||||
|
// 同步
|
||||||
|
sync();
|
||||||
|
// 聚焦
|
||||||
|
previewTerminal.value.term.focus();
|
||||||
|
}, { deep: true });
|
||||||
|
|
||||||
|
// 设置默认配置
|
||||||
|
onMounted(() => {
|
||||||
|
// 触发 watch 函数
|
||||||
|
formModel.value = { ...preference.displaySetting };
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
@terminal-width: 458px;
|
||||||
|
|
||||||
|
.terminal-setting-body {
|
||||||
|
height: 248px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 16px;
|
||||||
|
border: 1px solid var(--color-fill-4);
|
||||||
|
border-radius: 4px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.arco-form) {
|
||||||
|
.arco-form-item-label {
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-form-item {
|
||||||
|
margin-bottom: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item-font-family {
|
||||||
|
width: 158px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item-font-size {
|
||||||
|
width: 148px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item-line-height {
|
||||||
|
width: 114px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item-font-weight, .form-item-font-bold-weight {
|
||||||
|
width: 178px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item-font-weight {
|
||||||
|
margin-right: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item-cursor-style {
|
||||||
|
margin-right: 90px;
|
||||||
|
|
||||||
|
.arco-radio-button-content {
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-example {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
&-label {
|
||||||
|
color: var(--color-text-2);
|
||||||
|
display: block;
|
||||||
|
height: 16px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-wrapper {
|
||||||
|
border-radius: 4px;
|
||||||
|
width: calc(@terminal-width - 16px);
|
||||||
|
height: calc(100% - 16px - 12px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -9,12 +9,12 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { TerminalTheme } from '@/store/modules/terminal/types';
|
import type { TerminalThemeSchema } from '@/store/modules/terminal/types';
|
||||||
import { Terminal } from '@xterm/xterm';
|
import { Terminal } from '@xterm/xterm';
|
||||||
import { onMounted, onUnmounted, ref } from 'vue';
|
import { onMounted, onUnmounted, ref } from 'vue';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
theme: TerminalTheme | Record<string, any>
|
theme: TerminalThemeSchema | Record<string, any>
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const terminal = ref();
|
const terminal = ref();
|
||||||
@@ -22,22 +22,19 @@
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
term.value = new Terminal({
|
term.value = new Terminal({
|
||||||
theme: { ...props.theme, cursor: props.theme.background },
|
theme: props.theme,
|
||||||
cols: 47,
|
cols: 47,
|
||||||
rows: 6,
|
rows: 6,
|
||||||
fontSize: 15,
|
fontSize: 15,
|
||||||
convertEol: true,
|
|
||||||
cursorBlink: false,
|
|
||||||
cursorInactiveStyle: 'none',
|
cursorInactiveStyle: 'none',
|
||||||
});
|
});
|
||||||
term.value.open(terminal.value);
|
term.value.open(terminal.value);
|
||||||
|
|
||||||
term.value.write(
|
term.value.write(
|
||||||
'[94m[root[0m@[96mOrionServer usr]#[0m\n' +
|
'[1;94m[root[0m@[1;96mOrionServer usr]#[0m\r\n' +
|
||||||
'[92mdr-xr-xr-x.[0m 2 root root [96mbin[0m\n' +
|
'[92mdr-xr-xr-x.[0m 2 root root [96mbin[0m\r\n' +
|
||||||
'[92mdr-xr-xr-x.[0m 2 root root [96msbin[0m\n' +
|
'[92mdr-xr-xr-x.[0m 2 root root [96msbin[0m\r\n' +
|
||||||
'[92mdr-xr-xr-x.[0m 43 root root [96mlib[0m\n' +
|
'[92mdr-xr-xr-x.[0m 43 root root [96mlib[0m\r\n' +
|
||||||
'[92mdr-xr-xr-x.[0m 62 root root [96mlib64[0m\n' +
|
'[92mdr-xr-xr-x.[0m 62 root root [96mlib64[0m\r\n' +
|
||||||
'[92mlrwxrwxrwx.[0m 1 root root [90;42mtmp[0m'
|
'[92mlrwxrwxrwx.[0m 1 root root [90;42mtmp[0m'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
</h3>
|
</h3>
|
||||||
<!-- 暗色选择 -->
|
<!-- 暗色选择 -->
|
||||||
<a-radio-group :default-value="preference.darkTheme"
|
<a-radio-group :default-value="preference.darkTheme"
|
||||||
|
class="usn"
|
||||||
size="mini"
|
size="mini"
|
||||||
type="button"
|
type="button"
|
||||||
@change="checkDarkTheme"
|
@change="checkDarkTheme"
|
||||||
@@ -22,7 +23,7 @@
|
|||||||
:key="theme.name"
|
:key="theme.name"
|
||||||
class="terminal-theme-card simple-card"
|
class="terminal-theme-card simple-card"
|
||||||
:class="{
|
:class="{
|
||||||
'terminal-theme-card-check': theme.name === preference.terminalTheme.name
|
'terminal-theme-card-check': theme.name === preference.themeSchema.name
|
||||||
}"
|
}"
|
||||||
:title="theme.name"
|
:title="theme.name"
|
||||||
:style="{
|
:style="{
|
||||||
@@ -30,14 +31,15 @@
|
|||||||
marginRight: index === 0 ? '16px' : 0
|
marginRight: index === 0 ? '16px' : 0
|
||||||
}"
|
}"
|
||||||
:header-style="{
|
:header-style="{
|
||||||
color: theme.dark ? 'rgba(255, 255, 255, .8)' : 'rgba(0, 0, 0, .8)'
|
color: theme.dark ? 'rgba(255, 255, 255, .8)' : 'rgba(0, 0, 0, .8)',
|
||||||
|
userSelect: 'none'
|
||||||
}"
|
}"
|
||||||
@click="checkTheme(theme)">
|
@click="checkTheme(theme)">
|
||||||
<!-- 样例 -->
|
<!-- 样例 -->
|
||||||
<terminal-example :theme="theme" />
|
<terminal-example :theme="{ ...theme, cursor: theme.background }" />
|
||||||
<!-- 选中按钮 -->
|
<!-- 选中按钮 -->
|
||||||
<icon-check class="theme-check-icon"
|
<icon-check class="theme-check-icon"
|
||||||
v-show="theme.name === preference.terminalTheme.name" />
|
v-show="theme.name === preference.themeSchema.name" />
|
||||||
</a-card>
|
</a-card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -51,7 +53,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { TerminalTheme } from '@/store/modules/terminal/types';
|
import type { TerminalThemeSchema } from '@/store/modules/terminal/types';
|
||||||
import { darkThemeKey } from '../../types/terminal.const';
|
import { darkThemeKey } from '../../types/terminal.const';
|
||||||
import ThemeSchema from '../../types/terminal.theme';
|
import ThemeSchema from '../../types/terminal.theme';
|
||||||
import { useDebounceFn } from '@vueuse/core';
|
import { useDebounceFn } from '@vueuse/core';
|
||||||
@@ -76,15 +78,15 @@
|
|||||||
changeDarkTheme(false);
|
changeDarkTheme(false);
|
||||||
} else if (value === DarkTheme.AUTO) {
|
} else if (value === DarkTheme.AUTO) {
|
||||||
// 自动配色
|
// 自动配色
|
||||||
changeDarkTheme(preference.terminalTheme.dark);
|
changeDarkTheme(preference.themeSchema.dark);
|
||||||
}
|
}
|
||||||
// 同步用户偏好
|
// 同步用户偏好
|
||||||
sync();
|
sync();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 选择终端主题
|
// 选择终端主题
|
||||||
const checkTheme = (theme: TerminalTheme) => {
|
const checkTheme = (theme: TerminalThemeSchema) => {
|
||||||
preference.terminalTheme = theme;
|
preference.themeSchema = theme;
|
||||||
// 切换主题配色
|
// 切换主题配色
|
||||||
if (preference.darkTheme === DarkTheme.AUTO) {
|
if (preference.darkTheme === DarkTheme.AUTO) {
|
||||||
changeDarkTheme(theme.dark);
|
changeDarkTheme(theme.dark);
|
||||||
@@ -3,8 +3,8 @@
|
|||||||
<div class="view-setting-wrapper">
|
<div class="view-setting-wrapper">
|
||||||
<!-- 主标题 -->
|
<!-- 主标题 -->
|
||||||
<h2 class="terminal-setting-title">外观设置</h2>
|
<h2 class="terminal-setting-title">外观设置</h2>
|
||||||
<!-- 字体设置 -->
|
<!-- 显示设置 -->
|
||||||
<terminal-font-block />
|
<terminal-display-block />
|
||||||
<!-- 主题设置 -->
|
<!-- 主题设置 -->
|
||||||
<terminal-theme-block />
|
<terminal-theme-block />
|
||||||
</div>
|
</div>
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import TerminalFontBlock from './terminal-font-block.vue';
|
import TerminalDisplayBlock from './terminal-display-block.vue';
|
||||||
import TerminalThemeBlock from './terminal-theme-block.vue';
|
import TerminalThemeBlock from './terminal-theme-block.vue';
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@@ -26,7 +26,6 @@
|
|||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.view-setting-wrapper {
|
.view-setting-wrapper {
|
||||||
width: 932px;
|
width: 932px;
|
||||||
user-select: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -43,8 +43,23 @@ export interface TabItem {
|
|||||||
[key: string]: unknown;
|
[key: string]: unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 字体后缀 兜底
|
||||||
|
export const fontFamilySuffix = ',courier-new, courier, monospace';
|
||||||
|
|
||||||
// 终端暗色模式 字典项
|
// 终端暗色模式 字典项
|
||||||
export const darkThemeKey = 'terminalDarkTheme';
|
export const darkThemeKey = 'terminalDarkTheme';
|
||||||
|
|
||||||
|
// 终端字体样式
|
||||||
|
export const fontFamilyKey = 'terminalFontFamily';
|
||||||
|
|
||||||
|
// 终端字体大小
|
||||||
|
export const fontSizeKey = 'terminalFontSize';
|
||||||
|
|
||||||
|
// 终端字体字重
|
||||||
|
export const fontWeightKey = 'terminalFontWeight';
|
||||||
|
|
||||||
|
// 终端光标样式
|
||||||
|
export const cursorStyleKey = 'terminalCursorStyle';
|
||||||
|
|
||||||
// 加载的字典值
|
// 加载的字典值
|
||||||
export const dictKeys = [darkThemeKey];
|
export const dictKeys = [darkThemeKey, fontFamilyKey, fontSizeKey, fontWeightKey, cursorStyleKey];
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { TerminalTheme } from '@/store/modules/terminal/types';
|
import type { TerminalThemeSchema } from '@/store/modules/terminal/types';
|
||||||
|
|
||||||
// 默认配色
|
// 默认配色
|
||||||
export const DEFAULT_SCHEMA = {
|
export const DEFAULT_SCHEMA = {
|
||||||
@@ -248,4 +248,4 @@ export default [
|
|||||||
brightCyan: '#2488FF',
|
brightCyan: '#2488FF',
|
||||||
brightWhite: '#EAE5FF'
|
brightWhite: '#EAE5FF'
|
||||||
}
|
}
|
||||||
] as Array<TerminalTheme>;
|
] as Array<TerminalThemeSchema>;
|
||||||
|
|||||||
Reference in New Issue
Block a user