feat: 添加自定义终端字体描边和阴影设置项

This commit is contained in:
Baobhan Sith
2025-05-27 19:15:52 +08:00
parent 03fd91a7c0
commit c7fd6c3df7
13 changed files with 501 additions and 17 deletions
@@ -20,6 +20,14 @@ const mapRowsToAppearanceSettings = (rows: DbAppearanceSettingsRow[]): Appearanc
let latestUpdatedAt = 0;
let terminalBackgroundEnabledFound = false; // 标记是否在数据库中找到该设置
let terminalBackgroundOverlayOpacityFound = false; // 标记是否找到蒙版透明度设置
let terminalTextStrokeEnabledFound = false;
let terminalTextStrokeWidthFound = false;
let terminalTextStrokeColorFound = false;
let terminalTextShadowEnabledFound = false;
let terminalTextShadowOffsetXFound = false;
let terminalTextShadowOffsetYFound = false;
let terminalTextShadowBlurFound = false;
let terminalTextShadowColorFound = false;
for (const row of rows) {
// 更新 latestUpdatedAt
@@ -67,6 +75,38 @@ const mapRowsToAppearanceSettings = (rows: DbAppearanceSettingsRow[]): Appearanc
case 'remote_html_presets_url':
settings.remoteHtmlPresetsUrl = row.value || null; // 如果为空字符串,则视为 null
break;
case 'terminalTextStrokeEnabled':
settings.terminalTextStrokeEnabled = row.value === 'true';
terminalTextStrokeEnabledFound = true;
break;
case 'terminalTextStrokeWidth':
settings.terminalTextStrokeWidth = parseFloat(row.value);
terminalTextStrokeWidthFound = true;
break;
case 'terminalTextStrokeColor':
settings.terminalTextStrokeColor = row.value;
terminalTextStrokeColorFound = true;
break;
case 'terminalTextShadowEnabled':
settings.terminalTextShadowEnabled = row.value === 'true';
terminalTextShadowEnabledFound = true;
break;
case 'terminalTextShadowOffsetX':
settings.terminalTextShadowOffsetX = parseFloat(row.value);
terminalTextShadowOffsetXFound = true;
break;
case 'terminalTextShadowOffsetY':
settings.terminalTextShadowOffsetY = parseFloat(row.value);
terminalTextShadowOffsetYFound = true;
break;
case 'terminalTextShadowBlur':
settings.terminalTextShadowBlur = parseFloat(row.value);
terminalTextShadowBlurFound = true;
break;
case 'terminalTextShadowColor':
settings.terminalTextShadowColor = row.value;
terminalTextShadowColorFound = true;
break;
}
}
@@ -90,6 +130,30 @@ const mapRowsToAppearanceSettings = (rows: DbAppearanceSettingsRow[]): Appearanc
: defaults.terminalBackgroundOverlayOpacity, // 否则使用默认值
terminal_custom_html: settings.terminal_custom_html ?? defaults.terminal_custom_html,
remoteHtmlPresetsUrl: settings.remoteHtmlPresetsUrl ?? defaults.remoteHtmlPresetsUrl,
terminalTextStrokeEnabled: terminalTextStrokeEnabledFound
? settings.terminalTextStrokeEnabled
: defaults.terminalTextStrokeEnabled,
terminalTextStrokeWidth: terminalTextStrokeWidthFound
? settings.terminalTextStrokeWidth
: defaults.terminalTextStrokeWidth,
terminalTextStrokeColor: terminalTextStrokeColorFound
? settings.terminalTextStrokeColor
: defaults.terminalTextStrokeColor,
terminalTextShadowEnabled: terminalTextShadowEnabledFound
? settings.terminalTextShadowEnabled
: defaults.terminalTextShadowEnabled,
terminalTextShadowOffsetX: terminalTextShadowOffsetXFound
? settings.terminalTextShadowOffsetX
: defaults.terminalTextShadowOffsetX,
terminalTextShadowOffsetY: terminalTextShadowOffsetYFound
? settings.terminalTextShadowOffsetY
: defaults.terminalTextShadowOffsetY,
terminalTextShadowBlur: terminalTextShadowBlurFound
? settings.terminalTextShadowBlur
: defaults.terminalTextShadowBlur,
terminalTextShadowColor: terminalTextShadowColorFound
? settings.terminalTextShadowColor
: defaults.terminalTextShadowColor,
updatedAt: latestUpdatedAt || defaults.updatedAt, // 使用最新的更新时间,否则使用默认时间戳
};
};
@@ -110,6 +174,17 @@ const getDefaultAppearanceSettings = (): Omit<AppearanceSettings, '_id'> => {
terminalBackgroundOverlayOpacity: 0.5, // 默认蒙版透明度
terminal_custom_html: '', // 默认自定义 HTML 为空字符串
remoteHtmlPresetsUrl: null, // 默认远程 HTML 预设 URL 为 null
// 终端文本描边设置默认值
terminalTextStrokeEnabled: false,
terminalTextStrokeWidth: 1,
terminalTextStrokeColor: '#000000',
// 终端文本阴影设置默认值
terminalTextShadowEnabled: false,
terminalTextShadowOffsetX: 2,
terminalTextShadowOffsetY: 2,
terminalTextShadowBlur: 0,
terminalTextShadowColor: '#000000',
updatedAt: Date.now(), // 提供默认时间戳
};
};
@@ -139,6 +214,14 @@ export const ensureDefaultSettingsExist = async (db: sqlite3.Database): Promise<
{ key: 'terminalBackgroundOverlayOpacity', value: defaults.terminalBackgroundOverlayOpacity },
{ key: 'terminal_custom_html', value: defaults.terminal_custom_html },
{ key: 'remoteHtmlPresetsUrl', value: defaults.remoteHtmlPresetsUrl },
{ key: 'terminalTextStrokeEnabled', value: defaults.terminalTextStrokeEnabled },
{ key: 'terminalTextStrokeWidth', value: defaults.terminalTextStrokeWidth },
{ key: 'terminalTextStrokeColor', value: defaults.terminalTextStrokeColor },
{ key: 'terminalTextShadowEnabled', value: defaults.terminalTextShadowEnabled },
{ key: 'terminalTextShadowOffsetX', value: defaults.terminalTextShadowOffsetX },
{ key: 'terminalTextShadowOffsetY', value: defaults.terminalTextShadowOffsetY },
{ key: 'terminalTextShadowBlur', value: defaults.terminalTextShadowBlur },
{ key: 'terminalTextShadowColor', value: defaults.terminalTextShadowColor },
];
try {
@@ -5,12 +5,50 @@ import { NotificationService } from '../services/notification.service';
import { ipBlacklistService } from '../services/ip-blacklist.service';
import { exportConnectionsAsEncryptedZip } from '../services/import-export.service';
import { UpdateSidebarConfigDto, UpdateCaptchaSettingsDto, CaptchaSettings } from '../types/settings.types';
import { AppearanceSettings, UpdateAppearanceDto } from '../types/appearance.types';
import { getAppearanceSettings, updateAppearanceSettings as updateAppearanceSettingsInRepo } from '../repositories/appearance.repository';
import i18next from '../i18n';
const auditLogService = new AuditLogService();
const notificationService = new NotificationService();
export const settingsController = {
/**
* 获取外观设置
*/
async getAppearanceSettings(req: Request, res: Response): Promise<void> {
try {
const settings = await getAppearanceSettings();
res.json(settings);
} catch (error: any) {
console.error('获取外观设置时出错:', error);
res.status(500).json({ message: '获取外观设置失败', error: error.message });
}
},
/**
* 更新外观设置
*/
async updateAppearanceSettings(req: Request, res: Response): Promise<void> {
try {
const settingsDto: UpdateAppearanceDto = req.body;
// 可在此处添加 DTO 验证逻辑
if (typeof settingsDto !== 'object' || settingsDto === null) {
res.status(400).json({ message: '无效的请求体,应为 JSON 对象' });
return;
}
const result = await updateAppearanceSettingsInRepo(settingsDto);
if (result) {
res.status(200).json({ message: '外观设置已成功更新' });
} else {
// 如果仓库层返回 false,可能表示没有实际更改或更新失败
res.status(200).json({ message: '外观设置未发生更改或更新失败' });
}
} catch (error: any) {
console.error('更新外观设置时出错:', error);
res.status(500).json({ message: '更新外观设置失败', error: error.message });
}
},
/**
* 获取所有设置项
*/
@@ -15,6 +15,11 @@ router.use(isAuthenticated);
router.get('/', settingsController.getAllSettings); // GET /api/v1/settings
router.put('/', settingsController.updateSettings); // PUT /api/v1/settings
// +++ 外观设置路由 +++
// GET /api/v1/settings/appearance - 获取外观设置
router.get('/appearance', settingsController.getAppearanceSettings);
// PUT /api/v1/settings/appearance - 更新外观设置
router.put('/appearance', settingsController.updateAppearanceSettings);
// +++ 焦点切换顺序路由 +++
// GET /api/v1/settings/focus-switcher-sequence - 获取焦点切换顺序
router.get('/focus-switcher-sequence', settingsController.getFocusSwitcherSequence);
@@ -21,6 +21,14 @@ export interface AppearanceSettings {
terminalBackgroundOverlayOpacity?: number; // 终端背景蒙版透明度 (0-1)
terminal_custom_html?: string; // 用户自定义终端背景 HTML
remoteHtmlPresetsUrl?: string | null; // 远程 HTML 预设仓库 URL
terminalTextStrokeEnabled?: boolean;
terminalTextStrokeWidth?: number;
terminalTextStrokeColor?: string;
terminalTextShadowEnabled?: boolean;
terminalTextShadowOffsetX?: number;
terminalTextShadowOffsetY?: number;
terminalTextShadowBlur?: number;
terminalTextShadowColor?: string;
updatedAt?: number;
}