update
This commit is contained in:
@@ -37,7 +37,6 @@ const themeParseError = ref<string | null>(null); // 用于显示 JSON 解析错
|
|||||||
// 终端主题管理相关状态
|
// 终端主题管理相关状态
|
||||||
const isEditingTheme = ref(false); // 是否正在编辑某个主题
|
const isEditingTheme = ref(false); // 是否正在编辑某个主题
|
||||||
const themeSearchTerm = ref(''); // 主题搜索词
|
const themeSearchTerm = ref(''); // 主题搜索词
|
||||||
const themeSortOrder = ref<'nameAsc' | 'nameDesc'>('nameAsc'); // 主题排序方式
|
|
||||||
// 使用 reactive 确保嵌套对象 themeData 的响应性
|
// 使用 reactive 确保嵌套对象 themeData 的响应性
|
||||||
// 修正:editingTheme 应该是一个 ref 包含 TerminalTheme 或 null
|
// 修正:editingTheme 应该是一个 ref 包含 TerminalTheme 或 null
|
||||||
const editingTheme = ref<TerminalTheme | null>(null); // 正在编辑的主题数据副本 (完整结构)
|
const editingTheme = ref<TerminalTheme | null>(null); // 正在编辑的主题数据副本 (完整结构)
|
||||||
@@ -131,16 +130,13 @@ watch([
|
|||||||
const emit = defineEmits(['close']);
|
const emit = defineEmits(['close']);
|
||||||
|
|
||||||
const closeCustomizer = () => {
|
const closeCustomizer = () => {
|
||||||
// 如果正在编辑主题,提示用户是否放弃更改
|
// 如果正在编辑主题,直接关闭并重置状态
|
||||||
if (isEditingTheme.value) {
|
if (isEditingTheme.value) {
|
||||||
if (confirm(t('styleCustomizer.confirmCloseEditing'))) {
|
isEditingTheme.value = false; // 退出编辑状态
|
||||||
isEditingTheme.value = false; // 退出编辑状态
|
editingTheme.value = null;
|
||||||
editingTheme.value = null;
|
saveThemeError.value = null; // 同时清除可能存在的保存错误
|
||||||
emit('close');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
emit('close');
|
|
||||||
}
|
}
|
||||||
|
emit('close'); // 总是触发关闭事件
|
||||||
};
|
};
|
||||||
|
|
||||||
// 当前活动的标签页
|
// 当前活动的标签页
|
||||||
@@ -161,15 +157,13 @@ const handleSaveUiTheme = async () => {
|
|||||||
|
|
||||||
// 重置 UI 主题
|
// 重置 UI 主题
|
||||||
const handleResetUiTheme = async () => {
|
const handleResetUiTheme = async () => {
|
||||||
if (confirm(t('styleCustomizer.confirmResetUi'))) {
|
try {
|
||||||
try {
|
await appearanceStore.resetCustomUiTheme();
|
||||||
await appearanceStore.resetCustomUiTheme();
|
// watch 会自动更新 editableUiTheme.value
|
||||||
// watch 会自动更新 editableUiTheme.value
|
alert(t('styleCustomizer.uiThemeReset'));
|
||||||
alert(t('styleCustomizer.uiThemeReset'));
|
} catch (error: any) {
|
||||||
} catch (error: any) {
|
console.error("重置 UI 主题失败:", error);
|
||||||
console.error("重置 UI 主题失败:", error);
|
alert(t('styleCustomizer.uiThemeResetFailed', { message: error.message }));
|
||||||
alert(t('styleCustomizer.uiThemeResetFailed', { message: error.message }));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -353,7 +347,7 @@ const handleApplyTheme = async (theme: TerminalTheme) => {
|
|||||||
try {
|
try {
|
||||||
await appearanceStore.setActiveTerminalTheme(themeIdToApply);
|
await appearanceStore.setActiveTerminalTheme(themeIdToApply);
|
||||||
// 成功后 activeTerminalThemeId 会自动更新
|
// 成功后 activeTerminalThemeId 会自动更新
|
||||||
alert(t('styleCustomizer.themeAppliedSuccess', { name: theme.name })); // 需要添加翻译
|
// alert(`Theme '${theme.name}' applied successfully`); // 移除成功提示
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error("应用终端主题失败:", error);
|
console.error("应用终端主题失败:", error);
|
||||||
alert(t('styleCustomizer.setActiveThemeFailed', { message: error.message }));
|
alert(t('styleCustomizer.setActiveThemeFailed', { message: error.message }));
|
||||||
@@ -382,7 +376,7 @@ const handleEditTheme = (theme: TerminalTheme) => {
|
|||||||
// 基于预设创建副本
|
// 基于预设创建副本
|
||||||
const themeCopy = JSON.parse(JSON.stringify(theme));
|
const themeCopy = JSON.parse(JSON.stringify(theme));
|
||||||
themeCopy._id = undefined; // 清除 ID,表示是新建
|
themeCopy._id = undefined; // 清除 ID,表示是新建
|
||||||
themeCopy.name = `${theme.name} (${t('styleCustomizer.copySuffix', '副本')})`; // 添加后缀,需要添加翻译 '副本'
|
themeCopy.name = `${theme.name} (Copy)`;
|
||||||
themeCopy.isPreset = false; // 副本不再是预设
|
themeCopy.isPreset = false; // 副本不再是预设
|
||||||
editingTheme.value = themeCopy;
|
editingTheme.value = themeCopy;
|
||||||
console.log('创建预设主题副本进行编辑:', editingTheme.value);
|
console.log('创建预设主题副本进行编辑:', editingTheme.value);
|
||||||
@@ -438,14 +432,12 @@ const handleCancelEditingTheme = () => {
|
|||||||
// 删除主题
|
// 删除主题
|
||||||
const handleDeleteTheme = async (theme: TerminalTheme) => {
|
const handleDeleteTheme = async (theme: TerminalTheme) => {
|
||||||
if (theme.isPreset) return;
|
if (theme.isPreset) return;
|
||||||
if (confirm(t('styleCustomizer.confirmDeleteTheme', { name: theme.name }))) {
|
try {
|
||||||
try {
|
await appearanceStore.deleteTerminalTheme(theme._id!);
|
||||||
await appearanceStore.deleteTerminalTheme(theme._id!);
|
alert(t('styleCustomizer.themeDeletedSuccess'));
|
||||||
alert(t('styleCustomizer.themeDeletedSuccess'));
|
} catch (error: any) {
|
||||||
} catch (error: any) {
|
console.error("删除终端主题失败:", error);
|
||||||
console.error("删除终端主题失败:", error);
|
alert(t('styleCustomizer.themeDeleteFailed', { message: error.message }));
|
||||||
alert(t('styleCustomizer.themeDeleteFailed', { message: error.message }));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -531,26 +523,22 @@ const handleTerminalBgUpload = async (event: Event) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleRemovePageBg = async () => {
|
const handleRemovePageBg = async () => {
|
||||||
if (confirm(t('styleCustomizer.confirmRemovePageBg'))) {
|
try {
|
||||||
try {
|
await appearanceStore.removePageBackground();
|
||||||
await appearanceStore.removePageBackground();
|
alert(t('styleCustomizer.pageBgRemoved'));
|
||||||
alert(t('styleCustomizer.pageBgRemoved'));
|
} catch (error: any) {
|
||||||
} catch (error: any) {
|
console.error("移除页面背景失败:", error);
|
||||||
console.error("移除页面背景失败:", error);
|
alert(t('styleCustomizer.removeBgFailed', { message: error.message }));
|
||||||
alert(t('styleCustomizer.removeBgFailed', { message: error.message }));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRemoveTerminalBg = async () => {
|
const handleRemoveTerminalBg = async () => {
|
||||||
if (confirm(t('styleCustomizer.confirmRemoveTerminalBg'))) {
|
try {
|
||||||
try {
|
await appearanceStore.removeTerminalBackground();
|
||||||
await appearanceStore.removeTerminalBackground();
|
alert(t('styleCustomizer.terminalBgRemoved'));
|
||||||
alert(t('styleCustomizer.terminalBgRemoved'));
|
} catch (error: any) {
|
||||||
} catch (error: any) {
|
console.error("移除终端背景失败:", error);
|
||||||
console.error("移除终端背景失败:", error);
|
alert(t('styleCustomizer.removeBgFailed', { message: error.message }));
|
||||||
alert(t('styleCustomizer.removeBgFailed', { message: error.message }));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -579,7 +567,7 @@ const formatXtermLabel = (key: keyof ITheme): string => {
|
|||||||
const activeThemeName = computed(() => {
|
const activeThemeName = computed(() => {
|
||||||
const theme = availableTerminalThemes.value.find(t => t._id === activeTerminalThemeId.value);
|
const theme = availableTerminalThemes.value.find(t => t._id === activeTerminalThemeId.value);
|
||||||
// 如果找不到主题 (例如 ID 无效或列表为空),则显示提示
|
// 如果找不到主题 (例如 ID 无效或列表为空),则显示提示
|
||||||
return theme ? theme.name : t('styleCustomizer.noActiveThemeSelected', '无激活主题'); // 需要添加翻译
|
return theme ? theme.name : 'No active theme selected';
|
||||||
});
|
});
|
||||||
|
|
||||||
// 过滤和排序主题列表
|
// 过滤和排序主题列表
|
||||||
@@ -592,25 +580,14 @@ const filteredAndSortedThemes = computed(() => {
|
|||||||
themes = themes.filter(theme => theme.name.toLowerCase().includes(searchTerm));
|
themes = themes.filter(theme => theme.name.toLowerCase().includes(searchTerm));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 排序
|
// 排序逻辑已移除
|
||||||
themes.sort((a, b) => {
|
// 默认按名称升序排序
|
||||||
const nameA = a.name.toLowerCase();
|
themes.sort((a, b) => a.name.localeCompare(b.name));
|
||||||
const nameB = b.name.toLowerCase();
|
|
||||||
if (themeSortOrder.value === 'nameAsc') {
|
|
||||||
return nameA.localeCompare(nameB);
|
|
||||||
} else { // nameDesc
|
|
||||||
return nameB.localeCompare(nameA);
|
|
||||||
}
|
|
||||||
// 未来可扩展日期排序,需要后端提供 createdAt/updatedAt
|
|
||||||
});
|
|
||||||
|
|
||||||
return themes;
|
return themes;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 切换排序顺序
|
// 排序切换函数已移除
|
||||||
const handleSortThemes = () => {
|
|
||||||
themeSortOrder.value = themeSortOrder.value === 'nameAsc' ? 'nameDesc' : 'nameAsc';
|
|
||||||
};
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -699,60 +676,59 @@ const handleSortThemes = () => {
|
|||||||
<!-- 终端主题选择与管理 -->
|
<!-- 终端主题选择与管理 -->
|
||||||
<h4>{{ t('styleCustomizer.terminalThemeSelection') }}</h4>
|
<h4>{{ t('styleCustomizer.terminalThemeSelection') }}</h4>
|
||||||
<!-- 显示当前激活主题 -->
|
<!-- 显示当前激活主题 -->
|
||||||
<div class="active-theme-display">
|
<div class="active-theme-display">
|
||||||
<span>{{ t('styleCustomizer.activeTheme') }}:</span>
|
<span>{{ t('styleCustomizer.activeTheme') }}:</span>
|
||||||
<strong>{{ activeThemeName }}</strong>
|
<strong>{{ activeThemeName }}</strong>
|
||||||
<button @click="handleExportActiveTheme" :disabled="!activeTerminalThemeId" class="button-inline button-small" :title="t('styleCustomizer.exportActiveThemeTooltip', '导出当前激活的主题为 JSON 文件')">{{ t('styleCustomizer.exportActiveTheme', '导出当前主题') }}</button> <!-- 添加 tooltip -->
|
<!-- 导出按钮移到管理按钮区域 -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 主题管理按钮 -->
|
<!-- 主题管理按钮 -->
|
||||||
<div class="theme-management-buttons">
|
<div class="theme-management-buttons">
|
||||||
<button @click="handleAddNewTheme">{{ t('styleCustomizer.addNewTheme') }}</button>
|
<button @click="handleAddNewTheme">{{ t('styleCustomizer.addNewTheme') }}</button>
|
||||||
<button @click="handleTriggerImport">{{ t('styleCustomizer.importTheme') }}</button>
|
<button @click="handleTriggerImport">{{ t('styleCustomizer.importTheme') }}</button>
|
||||||
<input type="file" ref="themeImportInput" @change="handleImportThemeFile" accept=".json" style="display: none;" />
|
<button @click="handleExportActiveTheme" :disabled="!activeTerminalThemeId" class="button-inline button-small" :title="t('styleCustomizer.exportActiveThemeTooltip', 'Export the currently active theme as a JSON file')">{{ t('styleCustomizer.exportActiveTheme', 'Export Active Theme') }}</button>
|
||||||
|
<input type="file" ref="themeImportInput" @change="handleImportThemeFile" accept=".json" style="display: none;" />
|
||||||
<p v-if="importError" class="error-message">{{ importError }}</p>
|
<p v-if="importError" class="error-message">{{ importError }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 搜索和排序 -->
|
|
||||||
<div class="theme-filter-sort">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
v-model="themeSearchTerm"
|
|
||||||
:placeholder="t('styleCustomizer.searchThemePlaceholder', '搜索主题名称...')"
|
|
||||||
class="text-input"
|
|
||||||
/>
|
|
||||||
<button @click="handleSortThemes" class="button-inline button-small">
|
|
||||||
{{ t('styleCustomizer.sortBy', '排序:') }} {{ themeSortOrder === 'nameAsc' ? t('styleCustomizer.sortAsc', '名称升序') : t('styleCustomizer.sortDesc', '名称降序') }} <!-- 需要添加翻译 -->
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 主题列表 -->
|
<!-- 搜索框移到列表上方 -->
|
||||||
<ul class="theme-list">
|
<div class="theme-search-bar">
|
||||||
<!-- 添加空状态提示 -->
|
<input
|
||||||
<li v-if="filteredAndSortedThemes.length === 0" class="empty-list-item">
|
type="text"
|
||||||
{{ t('styleCustomizer.noThemesFound', '未找到匹配的主题') }} <!-- 需要添加翻译 -->
|
v-model="themeSearchTerm"
|
||||||
</li>
|
:placeholder="t('styleCustomizer.searchThemePlaceholder', '搜索主题名称...')"
|
||||||
<li v-else v-for="theme in filteredAndSortedThemes" :key="theme._id" :class="{ 'preset-theme': theme.isPreset, 'active': theme._id === activeTerminalThemeId }">
|
class="text-input"
|
||||||
<button
|
/>
|
||||||
@click="handleApplyTheme(theme)"
|
</div>
|
||||||
class="button-apply"
|
|
||||||
:disabled="theme._id === activeTerminalThemeId"
|
|
||||||
:title="t('styleCustomizer.applyThemeTooltip', '应用此主题')"
|
|
||||||
>
|
|
||||||
{{ t('styleCustomizer.applyButton', '应用') }} <!-- 需要添加翻译 -->
|
|
||||||
</button>
|
|
||||||
<span class="theme-name" :title="theme.name">{{ theme.name }}</span> <!-- 添加 title 属性显示完整名称 -->
|
|
||||||
<div class="theme-actions">
|
|
||||||
<button @click="handleEditTheme(theme)" :title="theme.isPreset ? t('styleCustomizer.editAsCopyTooltip', '编辑此预设主题的副本') : t('common.edit')">{{ t('common.edit') }}</button> <!-- 添加 tooltip -->
|
|
||||||
<button @click="handleDeleteTheme(theme)" :disabled="theme.isPreset" class="button-danger" :title="theme.isPreset ? t('styleCustomizer.cannotDeletePresetTooltip', '无法删除预设主题') : t('common.delete')">{{ t('common.delete') }}</button> <!-- 添加 tooltip -->
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</section>
|
<!-- 主题列表 -->
|
||||||
|
<ul class="theme-list">
|
||||||
|
<!-- 添加空状态提示 -->
|
||||||
|
<li v-if="filteredAndSortedThemes.length === 0" class="empty-list-item">
|
||||||
|
{{ t('styleCustomizer.noThemesFound', 'No matching themes found') }}
|
||||||
|
</li>
|
||||||
|
<li v-else v-for="theme in filteredAndSortedThemes" :key="theme._id" :class="{ 'preset-theme': theme.isPreset, 'active': theme._id === activeTerminalThemeId }">
|
||||||
|
<!-- 应用按钮移到 theme-actions -->
|
||||||
|
<span class="theme-name" :title="theme.name">{{ theme.name }}</span>
|
||||||
|
<div class="theme-actions">
|
||||||
|
<button
|
||||||
|
@click="handleApplyTheme(theme)"
|
||||||
|
:disabled="theme._id === activeTerminalThemeId"
|
||||||
|
:title="t('styleCustomizer.applyThemeTooltip', 'Apply this theme')"
|
||||||
|
>
|
||||||
|
{{ t('styleCustomizer.applyButton', 'Apply') }}
|
||||||
|
</button>
|
||||||
|
<button @click="handleEditTheme(theme)" :title="theme.isPreset ? t('styleCustomizer.editAsCopy', 'Edit as Copy') : t('common.edit')">{{ t('common.edit') }}</button>
|
||||||
|
<button @click="handleDeleteTheme(theme)" :disabled="theme.isPreset" class="button-danger" :title="theme.isPreset ? t('styleCustomizer.cannotDeletePreset', 'Cannot delete preset theme') : t('common.delete')">{{ t('common.delete') }}</button>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
<!-- 主题编辑器 -->
|
<!-- 主题编辑器 -->
|
||||||
<section v-if="isEditingTheme && editingTheme">
|
<section v-if="isEditingTheme && editingTheme">
|
||||||
<h3>{{ editingTheme._id ? t('styleCustomizer.editThemeTitle') : t('styleCustomizer.newThemeTitle') }}</h3>
|
<h3>{{ editingTheme._id ? t('styleCustomizer.editThemeTitle') : t('styleCustomizer.newThemeTitle') }}</h3>
|
||||||
<p v-if="saveThemeError" class="error-message">{{ saveThemeError }}</p>
|
<p v-if="saveThemeError" class="error-message">{{ saveThemeError }}</p>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -1165,6 +1141,7 @@ hr {
|
|||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--base-margin);
|
gap: var(--base-margin);
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
align-items: center; /* 垂直居中按钮和错误消息 */
|
||||||
padding-bottom: var(--base-padding);
|
padding-bottom: var(--base-padding);
|
||||||
border-bottom: 1px dashed var(--border-color);
|
border-bottom: 1px dashed var(--border-color);
|
||||||
}
|
}
|
||||||
@@ -1188,14 +1165,19 @@ hr {
|
|||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
.theme-management-buttons .error-message {
|
||||||
|
margin: 0; /* 移除错误消息的默认外边距 */
|
||||||
|
flex-grow: 1; /* 让错误消息填充剩余空间 */
|
||||||
|
text-align: left; /* 错误消息左对齐 */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.theme-list {
|
.theme-list {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin-top: 0;
|
margin-top: var(--base-padding); /* 列表与上方元素间距 */
|
||||||
max-height: 280px;
|
max-height: 280px; /* 限制高度 */
|
||||||
overflow-y: auto;
|
overflow-y: auto; /* 允许滚动 */
|
||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background-color: var(--app-bg-color);
|
background-color: var(--app-bg-color);
|
||||||
@@ -1203,8 +1185,8 @@ hr {
|
|||||||
|
|
||||||
.theme-list li {
|
.theme-list li {
|
||||||
display: grid; /* 使用 Grid 布局列表项 */
|
display: grid; /* 使用 Grid 布局列表项 */
|
||||||
/* 新增列: 应用按钮 | 名称 | 操作按钮 */
|
/* 列: 名称 | 操作按钮组 */
|
||||||
grid-template-columns: auto 1fr auto;
|
grid-template-columns: 1fr auto; /* 名称占据剩余空间,按钮组自适应 */
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0.6rem 0.8rem; /* 调整内边距 */
|
padding: 0.6rem 0.8rem; /* 调整内边距 */
|
||||||
border-bottom: 1px solid var(--border-color);
|
border-bottom: 1px solid var(--border-color);
|
||||||
@@ -1223,14 +1205,26 @@ hr {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: var(--button-text-color); /* 确保激活项文本颜色正确 */
|
color: var(--button-text-color); /* 确保激活项文本颜色正确 */
|
||||||
}
|
}
|
||||||
.theme-list li.active .button-apply {
|
/* 激活项内按钮样式调整 */
|
||||||
/* 可以选择隐藏或禁用已激活项的应用按钮 */
|
.theme-list li.active .theme-actions button {
|
||||||
opacity: 0.5;
|
|
||||||
cursor: default;
|
|
||||||
background-color: transparent; /* 激活项的应用按钮背景透明 */
|
|
||||||
border-color: transparent;
|
|
||||||
color: var(--button-text-color); /* 继承激活项文本颜色 */
|
color: var(--button-text-color); /* 继承激活项文本颜色 */
|
||||||
|
border-color: rgba(255, 255, 255, 0.3); /* 边框稍微可见 */
|
||||||
|
background-color: rgba(255, 255, 255, 0.1); /* 轻微背景 */
|
||||||
}
|
}
|
||||||
|
.theme-list li.active .theme-actions button:hover:not(:disabled) {
|
||||||
|
background-color: rgba(255, 255, 255, 0.2);
|
||||||
|
border-color: rgba(255, 255, 255, 0.5);
|
||||||
|
}
|
||||||
|
/* 激活项的应用按钮禁用样式 - 注意: :disabled 选择器优先级可能需要调整 */
|
||||||
|
.theme-list li.active .theme-actions button:disabled {
|
||||||
|
opacity: 0.5 !important; /* 增加优先级确保生效 */
|
||||||
|
cursor: default !important;
|
||||||
|
background-color: transparent !important;
|
||||||
|
border-color: transparent !important;
|
||||||
|
color: var(--button-text-color) !important; /* 确保禁用时颜色也正确 */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.theme-list li:last-child {
|
.theme-list li:last-child {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
@@ -1243,44 +1237,24 @@ hr {
|
|||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-apply { /* 应用按钮样式 */
|
/* 移除独立的 .button-apply 样式 */
|
||||||
grid-column: 1 / 2;
|
|
||||||
padding: 0.3rem 0.6rem;
|
|
||||||
font-size: 0.85rem;
|
|
||||||
border: 1px solid var(--border-color);
|
|
||||||
border-radius: 4px;
|
|
||||||
background-color: var(--header-bg-color);
|
|
||||||
color: var(--text-color);
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.2s ease, border-color 0.2s ease;
|
|
||||||
white-space: nowrap;
|
|
||||||
margin-right: var(--base-margin); /* 与名称间距 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-apply:hover:not(:disabled) {
|
|
||||||
background-color: var(--border-color);
|
|
||||||
border-color: var(--text-color-secondary);
|
|
||||||
}
|
|
||||||
.button-apply:disabled {
|
|
||||||
opacity: 0.5;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
.theme-name { /* 主题名称样式 */
|
.theme-name { /* 主题名称样式 */
|
||||||
grid-column: 2 / 3;
|
grid-column: 1 / 2; /* 名称在第一列 */
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
color: var(--text-color); /* 确保非激活项文本颜色 */
|
color: var(--text-color); /* 确保非激活项文本颜色 */
|
||||||
}
|
}
|
||||||
.theme-list li.preset-theme .theme-name {
|
.theme-list li.preset-theme .theme-name {
|
||||||
/* font-style: italic; */ /* 移除斜体,通过按钮区分 */
|
/* 可以添加特定样式 */
|
||||||
/* color: var(--text-color-secondary); */
|
|
||||||
}
|
}
|
||||||
.theme-actions {
|
.theme-actions {
|
||||||
grid-column: 3 / 4; /* 按钮组在第三列 */
|
grid-column: 2 / 3; /* 按钮组在第二列 */
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem; /* 按钮间距 */
|
||||||
|
justify-content: flex-end; /* 按钮靠右对齐 */
|
||||||
}
|
}
|
||||||
/* 统一操作按钮样式 */
|
/* 统一操作按钮样式 */
|
||||||
.theme-actions button {
|
.theme-actions button {
|
||||||
@@ -1401,30 +1375,42 @@ hr {
|
|||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 搜索和排序区域 */
|
/* 搜索框样式 */
|
||||||
.theme-filter-sort {
|
.theme-search-bar {
|
||||||
display: flex;
|
margin-bottom: var(--base-padding); /* 与下方列表的间距 */
|
||||||
gap: var(--base-margin);
|
|
||||||
margin-bottom: var(--base-padding);
|
|
||||||
align-items: center;
|
|
||||||
}
|
}
|
||||||
.theme-filter-sort input.text-input {
|
.theme-search-bar input.text-input {
|
||||||
flex-grow: 1; /* 让搜索框占据更多空间 */
|
/* flex-grow: 1; /* 不再需要 flex */
|
||||||
grid-column: auto; /* 重置 grid 影响 */
|
/* 移除 grid-column 相关的样式,因为它不再是 grid item */
|
||||||
|
/* grid-column: auto; */
|
||||||
|
/* 确保输入框样式正确 */
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
padding: 0.5rem 0.7rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
background-color: var(--app-bg-color);
|
||||||
|
color: var(--text-color);
|
||||||
|
/* width: auto; /* 覆盖 form-group 的 width: 100% */
|
||||||
|
width: 100%; /* 让搜索框占满宽度 */
|
||||||
|
box-sizing: border-box;
|
||||||
|
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
||||||
}
|
}
|
||||||
.theme-filter-sort button {
|
.theme-search-bar input.text-input:focus {
|
||||||
flex-shrink: 0; /* 防止按钮被压缩 */
|
border-color: var(--link-active-color);
|
||||||
|
outline: 0;
|
||||||
|
box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.15);
|
||||||
}
|
}
|
||||||
|
/* 排序按钮样式已移除 */
|
||||||
|
|
||||||
/* 当前激活主题显示 */
|
/* 当前激活主题显示 */
|
||||||
.active-theme-display {
|
.active-theme-display {
|
||||||
margin-bottom: var(--base-padding);
|
margin-bottom: var(--base-padding); /* 与下方搜索框的间距 */
|
||||||
padding: 0.6rem 0;
|
padding: 0.6rem 0;
|
||||||
font-size: 0.95rem;
|
font-size: 0.95rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.8rem;
|
gap: 0.8rem;
|
||||||
border-bottom: 1px solid var(--border-color);
|
/* border-bottom: 1px solid var(--border-color); */ /* 移除底部边框 */
|
||||||
}
|
}
|
||||||
.active-theme-display span {
|
.active-theme-display span {
|
||||||
color: var(--text-color-secondary);
|
color: var(--text-color-secondary);
|
||||||
|
|||||||
@@ -88,7 +88,16 @@
|
|||||||
"errorInvalidJsonObject": "Invalid input. Please provide a valid JSON object.",
|
"errorInvalidJsonObject": "Invalid input. Please provide a valid JSON object.",
|
||||||
"errorInvalidJsonConfig": "Invalid JSON configuration",
|
"errorInvalidJsonConfig": "Invalid JSON configuration",
|
||||||
"editAsCopy": "Edit as Copy",
|
"editAsCopy": "Edit as Copy",
|
||||||
"copySuffix": "Copy"
|
"copySuffix": "Copy",
|
||||||
|
"cannotDeletePreset": "Cannot delete preset theme",
|
||||||
|
"applyThemeTooltip": "Apply this theme",
|
||||||
|
"applyButton": "Apply",
|
||||||
|
"searchThemePlaceholder": "Search theme name...",
|
||||||
|
"sortBy": "Sort by:",
|
||||||
|
"sortAsc": "Name Asc",
|
||||||
|
"sortDesc": "Name Desc",
|
||||||
|
"exportActiveThemeTooltip": "Export the currently active theme as a JSON file",
|
||||||
|
"exportActiveTheme": "Export Active Theme"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "User Login",
|
"title": "User Login",
|
||||||
|
|||||||
@@ -88,7 +88,16 @@
|
|||||||
"errorInvalidJsonObject": "输入无效。请输入一个有效的 JSON 对象。",
|
"errorInvalidJsonObject": "输入无效。请输入一个有效的 JSON 对象。",
|
||||||
"errorInvalidJsonConfig": "无效的 JSON 配置",
|
"errorInvalidJsonConfig": "无效的 JSON 配置",
|
||||||
"editAsCopy": "编辑副本",
|
"editAsCopy": "编辑副本",
|
||||||
"copySuffix": "副本"
|
"copySuffix": "副本",
|
||||||
|
"cannotDeletePreset": "无法删除预设主题",
|
||||||
|
"applyThemeTooltip": "应用此主题",
|
||||||
|
"applyButton": "应用",
|
||||||
|
"searchThemePlaceholder": "搜索主题名称...",
|
||||||
|
"sortBy": "排序:",
|
||||||
|
"sortAsc": "名称升序",
|
||||||
|
"sortDesc": "名称降序",
|
||||||
|
"exportActiveThemeTooltip": "将当前激活的主题导出为 JSON 文件",
|
||||||
|
"exportActiveTheme": "导出当前主题"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "用户登录",
|
"title": "用户登录",
|
||||||
|
|||||||
Reference in New Issue
Block a user