feat: update theme and skin settings with new colors and icons

- Updated Chinese translations for color names in translation.json.
- Refactored SettingDialog component to enhance theme and appearance settings UI.
- Improved CSS styles for theme and skin setting items for better user experience.
- Added SVG icons for skin options in settingList.tsx.
- Cleaned up themeList.tsx by removing unnecessary lines.
This commit is contained in:
troyeguo
2026-03-16 16:08:57 +08:00
parent 89dfeabffb
commit bffc4a167a
6 changed files with 133 additions and 61 deletions

View File

File diff suppressed because one or more lines are too long

View File

@@ -608,10 +608,10 @@
"Not supported yet": "暂不支持",
"Update to": "更新至",
"Date": "更新日期:",
"Blue": "蓝",
"Red": "红",
"Green": "绿",
"Purple": "紫",
"Blue": "蓝",
"Red": "红",
"Green": "绿",
"Purple": "紫罗兰",
"Unauthorize": "取消授权",
"Remember window's size": "记忆阅读器窗口大小",
"Letter spacing": "字间距",

View File

@@ -63,7 +63,7 @@ class SettingDialog extends React.Component<
isDisablePDFCover:
ConfigService.getReaderConfig("isDisablePDFCover") === "yes",
currentThemeIndex: _.findLastIndex(themeList, {
name: ConfigService.getReaderConfig("themeColor"),
name: ConfigService.getReaderConfig("themeColor") || "default",
}),
storageLocation: getStorageLocation() || "",
isAddNew: false,
@@ -366,51 +366,6 @@ class SettingDialog extends React.Component<
) : this.props.settingMode === "appearance" ? (
<>
{this.renderSwitchOption(appearanceSettingList)}
<div className="setting-dialog-new-title">
<Trans>Theme color</Trans>
<ul className="theme-setting-container">
{themeList.map((item, index) => (
<li
className={
index === this.state.currentThemeIndex
? "active-color theme-setting-item"
: "theme-setting-item"
}
key={item.name}
onClick={() => {
this.handleTheme(item.name, index);
}}
style={{ backgroundColor: item.color }}
></li>
))}
</ul>
</div>
<div className="setting-dialog-new-title">
<Trans>Appearance</Trans>
<select
name=""
className="lang-setting-dropdown"
onChange={(event) => {
this.changeSkin(event.target.value);
}}
>
{skinList.map((item) => (
<option
value={item.value}
key={item.value}
className="lang-setting-option"
selected={
item.value ===
(ConfigService.getReaderConfig("appSkin") || "system")
? true
: false
}
>
{this.props.t(item.label)}
</option>
))}
</select>
</div>
<div className="setting-dialog-new-title">
<Trans>System font</Trans>
<select
@@ -437,6 +392,56 @@ class SettingDialog extends React.Component<
))}
</select>
</div>
<div className="setting-dialog-new-title">
<Trans>Theme color</Trans>
</div>
<ul className="theme-setting-container">
{themeList.map((item, index) => (
<li
className={
index === this.state.currentThemeIndex
? "theme-setting-item active-theme-item"
: "theme-setting-item"
}
key={item.name}
onClick={() => {
this.handleTheme(item.name, index);
}}
style={{ color: item.color }}
>
<span
className="theme-setting-dot"
style={{ backgroundColor: item.color }}
></span>
<Trans>{item.title}</Trans>
</li>
))}
</ul>
<div className="setting-dialog-new-title">
<Trans>Appearance</Trans>
</div>
<ul className="skin-setting-container">
{skinList.map((item) => (
<li
key={item.value}
className={
item.value ===
(ConfigService.getReaderConfig("appSkin") || "system")
? "skin-setting-item active-skin-item"
: "skin-setting-item"
}
onClick={() => {
this.changeSkin(item.value);
}}
>
<span
className="skin-setting-icon"
dangerouslySetInnerHTML={{ __html: item.icon }}
/>
<Trans>{item.label}</Trans>
</li>
))}
</ul>
</>
) : this.props.settingMode === "sync" ? (
<SyncSetting />

View File

@@ -172,18 +172,74 @@
line-height: 1;
}
.theme-setting-item {
width: 25px;
height: 25px;
border-radius: 50%;
display: flex;
align-items: center;
gap: 6px;
padding: 4px 12px 4px 8px;
border-radius: 20px;
border: 2px solid transparent;
cursor: pointer;
font-size: 13px;
font-weight: 500;
white-space: nowrap;
box-sizing: border-box;
transition: border-color 0.15s;
}
.theme-setting-item.active-theme-item {
border-color: currentColor;
}
.theme-setting-dot {
width: 16px;
height: 16px;
border-radius: 50%;
flex-shrink: 0;
}
.theme-setting-container {
width: 150px;
height: 25px;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
gap: 8px;
align-items: center;
width: auto;
height: auto;
margin-left: 25px;
margin-right: 25px;
margin-top: 6px;
}
.skin-setting-container {
display: flex;
flex-wrap: wrap;
gap: 8px;
align-items: center;
margin-left: 25px;
margin-right: 25px;
margin-top: 6px;
margin-bottom: 5px;
}
.skin-setting-item {
display: flex;
align-items: center;
gap: 6px;
padding: 4px 12px 4px 8px;
border-radius: 20px;
border: 2px solid transparent;
cursor: pointer;
font-size: 13px;
font-weight: 500;
white-space: nowrap;
box-sizing: border-box;
opacity: 0.6;
transition:
border-color 0.15s,
opacity 0.15s;
}
.skin-setting-item.active-skin-item {
border-color: currentColor;
opacity: 1;
}
.skin-setting-icon {
display: flex;
align-items: center;
flex-shrink: 0;
}
.setting-option-subtitle {
font-size: 12px;

View File

@@ -264,9 +264,21 @@ export const searchList = [
{ label: "Wikipedia", value: "wiki" },
];
export const skinList = [
{ label: "Follow OS", value: "system" },
{ label: "Light mode", value: "light" },
{ label: "Night mode", value: "night" },
{
label: "Follow OS",
value: "system",
icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="16" height="16"><path d="M12 3a9 9 0 1 0 0 18A9 9 0 0 0 12 3zm0 2v14A7 7 0 0 1 12 5zm0 0"/></svg>`,
},
{
label: "Light mode",
value: "light",
icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="16" height="16"><path d="M12 17a5 5 0 1 0 0-10 5 5 0 0 0 0 10zm0-13a1 1 0 0 0 1-1V2a1 1 0 0 0-2 0v1a1 1 0 0 0 1 1zm0 14a1 1 0 0 0-1 1v1a1 1 0 0 0 2 0v-1a1 1 0 0 0-1-1zm9-8h-1a1 1 0 0 0 0 2h1a1 1 0 0 0 0-2zm-17 1a1 1 0 0 0-1-1H2a1 1 0 0 0 0 2h1a1 1 0 0 0 1-1zm13.66-6.07-.71.71a1 1 0 1 0 1.41 1.41l.71-.71a1 1 0 0 0-1.41-1.41zM6.34 17.66l-.71.71a1 1 0 1 0 1.41 1.41l.71-.71a1 1 0 0 0-1.41-1.41zm12.73.71-.71-.71a1 1 0 0 0-1.41 1.41l.71.71a1 1 0 0 0 1.41-1.41zM5.64 6.35l-.71-.71a1 1 0 0 0-1.41 1.41l.71.71A1 1 0 0 0 5.64 6.35z"/></svg>`,
},
{
label: "Night mode",
value: "night",
icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="16" height="16"><path d="M21.64 13a1 1 0 0 0-1.05-.14 8.05 8.05 0 0 1-3.37.73 8.15 8.15 0 0 1-8.14-8.1 8.59 8.59 0 0 1 .25-2A1 1 0 0 0 8 2.36a10.14 10.14 0 1 0 13.75 13.75 1 1 0 0 0-.11-1.11z"/></svg>`,
},
];
export const readerSettingList = [

View File

@@ -29,7 +29,6 @@ export const themeList = [
name: "green",
title: "Green",
},
{
id: 3,
color: "rgba(241, 100, 100, 1)",