refactor: 配置头部工具栏颜色.

This commit is contained in:
lijiahang
2024-01-11 11:25:32 +08:00
parent 34ebad0b5f
commit 8e03368e85
14 changed files with 122 additions and 116 deletions

View File

@@ -2,6 +2,7 @@
{
"name": "catppuccin-macchiato",
"dark": true,
"headerBackgroundColor": "#181B2E",
"schema": {
"background": "#24273A",
"foreground": "#CAD3F5",
@@ -26,6 +27,7 @@
{
"name": "catppuccin-mocha",
"dark": true,
"headerBackgroundColor": "#121222",
"schema": {
"background": "#1E1E2E",
"foreground": "#CDD6F4",
@@ -50,6 +52,7 @@
{
"name": "OneHalfDark",
"dark": true,
"headerBackgroundColor": "#1C2028",
"schema": {
"background": "#282C34",
"foreground": "#DCDFE4",
@@ -74,6 +77,7 @@
{
"name": "MaterialDesignColors",
"dark": true,
"headerBackgroundColor": "#111A1E",
"schema": {
"background": "#1D262A",
"foreground": "#E7EBED",
@@ -98,6 +102,7 @@
{
"name": "Dracula",
"dark": true,
"headerBackgroundColor": "#12131D",
"schema": {
"background": "#1E1F29",
"foreground": "#F8F8F2",
@@ -120,32 +125,34 @@
}
},
{
"name": "Dracula+",
"name": "Atom",
"dark": true,
"headerBackgroundColor": "#0A0B0D",
"schema": {
"background": "#212121",
"foreground": "#F8F8F2",
"cursor": "#ECEFF4",
"selectionBackground": "#44475A",
"black": "#21222C",
"red": "#FF5555",
"green": "#50FA7B",
"yellow": "#FFCB6B",
"blue": "#82AAFF",
"cyan": "#8BE9FD",
"white": "#F8F8F2",
"brightBlack": "#545454",
"brightRed": "#FF6E6E",
"brightGreen": "#69FF94",
"brightYellow": "#FFCB6B",
"brightBlue": "#D6ACFF",
"brightCyan": "#A4FFFF",
"brightWhite": "#F8F8F2"
"background": "#161719",
"foreground": "#C5C8C6",
"cursor": "#D0D0D0",
"selectionBackground": "#444444",
"black": "#000000",
"red": "#FD5FF1",
"green": "#87C38A",
"yellow": "#FFD7B1",
"blue": "#85BEFD",
"cyan": "#85BEFD",
"white": "#E0E0E0",
"brightBlack": "#000000",
"brightRed": "#FD5FF1",
"brightGreen": "#94FA36",
"brightYellow": "#F5FFA8",
"brightBlue": "#96CBFE",
"brightCyan": "#85BEFD",
"brightWhite": "#E0E0E0"
}
},
{
"name": "Apple System Colors",
"dark": true,
"headerBackgroundColor": "#121212",
"schema": {
"background": "#1E1E1E",
"foreground": "#FFFFFF",
@@ -170,6 +177,7 @@
{
"name": "Builtin Tango Light",
"dark": false,
"headerBackgroundColor": "#F3F3F3",
"schema": {
"background": "#FFFFFF",
"foreground": "#000000",
@@ -194,6 +202,7 @@
{
"name": "Duotone Dark",
"dark": true,
"headerBackgroundColor": "#13111B",
"schema": {
"background": "#1F1D27",
"foreground": "#B7A1FF",
@@ -218,6 +227,7 @@
{
"name": "BlulocoLight",
"dark": false,
"headerBackgroundColor": "#EDEDED",
"schema": {
"background": "#F9F9F9",
"foreground": "#373A41",
@@ -242,6 +252,7 @@
{
"name": "Chester",
"dark": true,
"headerBackgroundColor": "#202A37",
"schema": {
"background": "#2C3643",
"foreground": "#FFFFFF",
@@ -266,6 +277,7 @@
{
"name": "CLRS",
"dark": false,
"headerBackgroundColor": "#F3F3F3",
"schema": {
"background": "#FFFFFF",
"foreground": "#262626",
@@ -290,6 +302,7 @@
{
"name": "Calamity",
"dark": true,
"headerBackgroundColor": "#231C27",
"schema": {
"background": "#2F2833",
"foreground": "#D5CED9",
@@ -314,6 +327,7 @@
{
"name": "Tomorrow",
"dark": false,
"headerBackgroundColor": "#F3F3F3",
"schema": {
"background": "#FFFFFF",
"foreground": "#4D4D4C",
@@ -335,4 +349,4 @@
"brightWhite": "#FFFFFF"
}
}
]
]

View File

@@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.serializer.ValueFilter;
import com.orion.lang.utils.Colors;
import com.orion.lang.utils.Strings;
import com.orion.lang.utils.collect.Lists;
import com.orion.lang.utils.io.FileReaders;
import com.orion.lang.utils.io.Files1;
@@ -30,7 +31,7 @@ public class TerminalThemeGenerator {
List<String> schemaFilter = Lists.of(
"catppuccin-macchiato", "catppuccin-mocha",
"OneHalfDark", "MaterialDesignColors",
"Dracula", "Dracula+",
"Dracula", "Atom",
"Apple System Colors", "Builtin Tango Light",
"Duotone Dark", "BlulocoLight",
"Chester", "CLRS",
@@ -51,10 +52,15 @@ public class TerminalThemeGenerator {
.anyMatch(s -> f.getName().equalsIgnoreCase(s)))
.map(f -> {
JSONObject schema = JSONObject.parseObject(new String(FileReaders.readAllBytes(f)));
// 设置选中背景色
schema.put("selectionBackground", schema.getString("selection"));
// 设置主题色
String background = schema.getString("background");
TerminalTheme theme = new TerminalTheme();
theme.setName(schema.getString("name"));
theme.setDark(Colors.isDarkColor(schema.getString("background")));
theme.setDark(Colors.isDarkColor(background));
// header 颜色为深 12
theme.setHeaderBackgroundColor(adjustColor(background, -12));
theme.setSchema(JSON.parseObject(JSON.toJSONString(schema), TerminalThemeSchema.class));
return theme;
}).collect(Collectors.toList());
@@ -107,6 +113,8 @@ public class TerminalThemeGenerator {
@JSONField(ordinal = 1)
private Boolean dark;
@JSONField(ordinal = 2)
private String headerBackgroundColor;
@JSONField(ordinal = 3)
private TerminalThemeSchema schema;
}
@@ -154,4 +162,26 @@ public class TerminalThemeGenerator {
private String brightWhite;
}
/**
* 调整颜色
*
* @param color color
* @param range 正数越浅 负数越深
* @return color
*/
private static String adjustColor(String color, int range) {
StringBuilder newColor = new StringBuilder("#");
for (int i = 0; i < 3; i++) {
int c = Integer.parseInt(color.substring(i * 2 + 1, i * 2 + 3), 16);
c += range;
if (c < 0) {
c = 0;
} else if (c > 255) {
c = 255;
}
newColor.append(Strings.leftPad(Integer.toString(c, 16), 2, "0"));
}
return newColor.toString();
}
}

View File

@@ -4,6 +4,7 @@ import axios from 'axios';
export interface TerminalTheme {
name: string;
dark: boolean;
headerBackgroundColor: string;
schema: TerminalThemeSchema;
}

View File

@@ -203,26 +203,6 @@ export function getUUID() {
});
}
/**
* 调整颜色
* @param color color
* @param range 正数越浅 负数越深
*/
export function adjustColor(color: string, range: number) {
let newColor = '#';
for (let i = 0; i < 3; i++) {
let c = parseInt(color.substring(i * 2 + 1, i * 2 + 3), 16);
c += range;
if (c < 0) {
c = 0;
} else if (c > 255) {
c = 255;
}
newColor += c.toString(16).padStart(2, '0');
}
return newColor;
}
/**
* 清除 xss
*/

View File

@@ -25,7 +25,7 @@
</script>
<script lang="ts" setup>
import type { SidebarAction } from '../../types/terminal.const';
import type { SidebarAction } from '../../types/terminal.type';
import type { PropType } from 'vue';
defineProps({

View File

@@ -9,6 +9,8 @@
<template v-if="tab.type === TabType.SETTING">
<!-- 新建连接 -->
<new-connection-view v-if="tab.key === InnerTabs.NEW_CONNECTION.key" />
<!-- 显示设置 -->
<terminal-display-setting v-else-if="tab.key === InnerTabs.DISPLAY_SETTING.key" />
<!-- 主题设置 -->
<terminal-theme-setting v-else-if="tab.key === InnerTabs.THEME_SETTING.key" />
</template>
@@ -31,6 +33,7 @@
import { TabType, InnerTabs } from '../../types/terminal.const';
import { useTerminalStore } from '@/store';
import { watch } from 'vue';
import TerminalDisplaySetting from '../view-setting/terminal-display-setting.vue';
import TerminalThemeSetting from '../view-setting/terminal-theme-setting.vue';
import NewConnectionView from '../new-connection/new-connection-view.vue';
import TerminalView from '../xterm/terminal-view.vue';

View File

@@ -40,7 +40,7 @@
</script>
<script lang="ts" setup>
import type { SidebarAction } from '../../types/terminal.const';
import type { SidebarAction } from '../../types/terminal.type';
import { useFullscreen } from '@vueuse/core';
import { computed } from 'vue';
import { useTerminalStore } from '@/store';

View File

@@ -18,7 +18,7 @@
</script>
<script lang="ts" setup>
import type { SidebarAction } from '../../types/terminal.const';
import type { SidebarAction } from '../../types/terminal.type';
import { InnerTabs } from '../../types/terminal.const';
import { useTerminalStore } from '@/store';
import IconActions from './icon-actions.vue';
@@ -36,11 +36,6 @@
// 底部操作
const bottomActions: Array<SidebarAction> = [
{
icon: 'icon-drive-file',
content: InnerTabs.SFTP_SETTING.title,
click: () => tabManager.openTab(InnerTabs.SFTP_SETTING)
},
{
icon: 'icon-command',
content: InnerTabs.SHORTCUT_SETTING.title,

View File

@@ -18,7 +18,7 @@
</script>
<script lang="ts" setup>
import type { SidebarAction } from '../../types/terminal.const';
import type { SidebarAction } from '../../types/terminal.type';
import IconActions from './icon-actions.vue';
const emits = defineEmits(['openSnippet', 'openSftp', 'openTransfer', 'screenshot']);

View File

@@ -62,7 +62,7 @@
<script lang="ts" setup>
import type { HostQueryResponse } from '@/api/asset/host';
import type { SshExtraModel } from '../../types/terminal.const';
import type { SshExtraModel } from '../../types/terminal.type';
import { ref } from 'vue';
import useLoading from '@/hooks/loading';
import useVisible from '@/hooks/visible';

View File

@@ -15,7 +15,7 @@
<!-- 内容区域 -->
<div v-else class="terminal-setting-body terminal-theme-container">
<!-- 提示 -->
<a-alert class="mb16">选择后会立刻保存, 刷新页面生效</a-alert>
<a-alert class="mb16">选择后会立刻保存, 刷新页面生效</a-alert>
<!-- 终端主题 -->
<div class="theme-row"
v-for="rowIndex in themes.length / 2"

View File

@@ -3,7 +3,7 @@
<!-- 头部 -->
<div class="terminal-header"
:style="{
background: adjustColor(themeSchema.background, -12)
background: preference.theme.headerBackgroundColor
}">
<!-- 左侧操作 -->
<div class="terminal-header-left">
@@ -44,7 +44,7 @@
<!-- 命令编辑器 -->
<shell-editor-modal ref="modal"
:closable="false"
:body-style="{ padding: '16px 16px 16px 0' }"
:body-style="{ padding: '16px' }"
:dark="preference.theme.dark"
cancel-text="关闭"
@ok="writeCommand(modal.getValue())"
@@ -59,13 +59,12 @@
</script>
<script lang="ts" setup>
import type { SidebarAction } from '../../types/terminal.const';
import type { SidebarAction } from '../../types/terminal.type';
import type { ITerminalSession, TerminalTabItem } from '../../types/terminal.type';
import { computed, onMounted, onUnmounted, ref } from 'vue';
import { useDictStore, useTerminalStore } from '@/store';
import useCopy from '@/hooks/copy';
import { connectStatusKey } from '../../types/terminal.const';
import { adjustColor } from '@/utils';
import IconActions from '../layout/icon-actions.vue';
import ShellEditorModal from '@/components/view/shell-editor/shell-editor-modal.vue';
@@ -83,18 +82,29 @@
const session = ref<ITerminalSession>();
// FIXME
// 调教 theme
// terminal themes 改成非同步 style
// 从后端获取 theme
// (改成可配置/拆分)
// 自定义 font siderBar 颜色, 集成到主题里面, 现在的问题是切换主题字体颜色就变了
// 是否开启 link
// 是否开启 image
// search color 配置
// 右键菜单补充
// 搜索
// 搜索 search color 配置
// 截屏
// 最近连接逻辑 偏好逻辑
// 主机获取逻辑 最近连接逻辑 偏好逻辑
// TODO
// 交互设置
// 右键选中词条
// 右键粘贴
// 启用右键菜单
// 自动将选中内容复制到剪切板
// 粘贴时删除空格
// 复制时删除空格
// 分隔符 /\()"'-.,:;<>~!@#$%^&*|+=[]{}~?│ 在终端中双击文本将使用到这些符号
// 自动检测 url 并可以点击
// 支持显示图片 使用 sixel 打开图片
// 终端设置
// bell sound
// terminal emulation type: xterm 256color
// 回滚ScrollBack
// 保存在缓冲区的行数
// 发送命令
const writeCommandInput = async (e: KeyboardEvent) => {
@@ -249,11 +259,12 @@
&-left, &-right {
display: flex;
align-items: center;
width: 100%;
height: 100%;
}
&-left {
width: 34%;
.address-wrapper {
height: 100%;
display: inline-flex;
@@ -278,6 +289,7 @@
}
&-right {
width: 66%;
justify-content: flex-end;
.command-input {

View File

@@ -1,16 +1,5 @@
import type { CSSProperties } from 'vue';
import { getUUID } from '@/utils';
// sidebar 操作类型
export interface SidebarAction {
icon: string;
content: string;
visible?: boolean;
disabled?: boolean;
iconStyle?: CSSProperties;
click: () => void;
}
// tab 类型
export const TabType = {
SETTING: 'setting',
@@ -24,11 +13,6 @@ export const InnerTabs = {
title: '新建连接',
type: TabType.SETTING
},
SFTP_SETTING: {
key: 'sftpSetting',
title: 'sftp设置',
type: TabType.SETTING
},
SHORTCUT_SETTING: {
key: 'shortcutSetting',
title: '快捷键设置',
@@ -56,30 +40,6 @@ export const InnerTabs = {
},
};
// TODO
// 显示设置
// 显示基础设置
// 右侧栏
// 交互设置
// 右键选中词条
// 右键粘贴
// 启用右键菜单
// 自动将选中内容复制到剪切板
// 粘贴时删除空格
// 复制时删除空格
// 分隔符 /\()"'-.,:;<>~!@#$%^&*|+=[]{}~?│ 在终端中双击文本将使用到这些符号
// 自动检测 url 并可以点击
// 支持显示图片 使用 sixel 打开图片
// 终端设置
// bell sound
// terminal emulation type: xterm 256color
// 回滚ScrollBack
// 保存在缓冲区的行数
// 新建连接类型
export const NewConnectionType = {
GROUP: 'group',
@@ -88,14 +48,6 @@ export const NewConnectionType = {
LATEST: 'latest'
};
// ssh 额外配置
export interface SshExtraModel {
authType?: string;
username?: string;
keyId?: number;
identityId?: number;
}
// 主机额外配置 ssh 认证方式
export const ExtraSshAuthType = {
// 使用默认认证方式

View File

@@ -4,6 +4,7 @@ import type { WebglAddon } from 'xterm-addon-webgl';
import type { WebLinksAddon } from 'xterm-addon-web-links';
import type { SearchAddon } from 'xterm-addon-search';
import type { ImageAddon } from 'xterm-addon-image';
import type { CSSProperties } from 'vue';
// 终端 tab 元素
export interface TerminalTabItem {
@@ -14,6 +15,24 @@ export interface TerminalTabItem {
[key: string]: unknown;
}
// sidebar 操作类型
export interface SidebarAction {
icon: string;
content: string;
visible?: boolean;
disabled?: boolean;
iconStyle?: CSSProperties;
click: () => void;
}
// ssh 额外配置
export interface SshExtraModel {
authType?: string;
username?: string;
keyId?: number;
identityId?: number;
}
// 终端协议
export interface Protocol {
type: string;