Merge pull request #88 from router-for-me/dev

Dev
This commit is contained in:
lzt404 authored and GitHub committed 2026-08-03 17:24:10 +08:00
commit c0c31525a3
9 files changed
+74 -45

No files matched your search

+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "cpa-gui",
"private": true,
"version": "0.2.11",
"version": "0.2.12",
"type": "module",
"packageManager": "bun@1.3.14",
"scripts": {
+1 -1
View File
@@ -582,7 +582,7 @@ checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636"
[[package]]
name = "cpa-gui"
version = "0.2.11"
version = "0.2.12"
dependencies = [
"base64 0.22.1",
"chrono",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "cpa-gui"
version = "0.2.11"
version = "0.2.12"
description = "CPA desktop management shell"
authors = ["lzt404"]
edition = "2021"
+2 -7
View File
@@ -505,20 +505,15 @@ enum WindowsCloseAction {
MinimizeToTray,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
enum WindowsCloseBehavior {
#[default]
Ask,
Exit,
MinimizeToTray,
}
impl Default for WindowsCloseBehavior {
fn default() -> Self {
Self::Ask
}
}
impl WindowsCloseBehavior {
fn as_str(self) -> &'static str {
match self {
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "EasyCLIProxyAPI",
"version": "0.2.11",
"version": "0.2.12",
"identifier": "com.cpa.gui",
"build": {
"beforeDevCommand": "bun run dev",
-1
View File
@@ -343,7 +343,6 @@ export const jaOverrides = {
'config.software.title': 'ソフトウェア設定',
'config.software.description': 'ウィンドウの閉じるボタンをクリックしたときのデフォルト動作を設定します。「毎回確認」を選ぶと確認ダイアログに戻ります。',
'config.software.closeBehavior': '終了動作',
'config.software.closeBehaviorHint': '選択を記憶すると、ウィンドウを閉じたときに選択した動作をすぐに実行します。',
'config.software.behavior.ask': '毎回確認',
'config.software.behavior.minimize': 'トレイに最小化',
'config.software.behavior.exit': 'アプリを終了',
-2
View File
@@ -290,7 +290,6 @@ export const zhCN = {
'config.software.title': '软件设置',
'config.software.description': '设置点击窗口关闭按钮时的默认行为。选择“每次询问”即可恢复关闭确认弹窗。',
'config.software.closeBehavior': '关闭行为',
'config.software.closeBehaviorHint': '记住选项后,关闭窗口将直接执行所选操作。',
'config.software.behavior.ask': '每次询问',
'config.software.behavior.minimize': '最小化到托盘',
'config.software.behavior.exit': '退出程序',
@@ -1243,7 +1242,6 @@ export const en: Record<MessageKey, string> = {
'config.software.title': 'Software Settings',
'config.software.description': 'Choose what happens by default when you click the window close button. Select “Ask every time” to restore the confirmation dialog.',
'config.software.closeBehavior': 'Close behavior',
'config.software.closeBehaviorHint': 'When a choice is remembered, closing the window performs the selected action immediately.',
'config.software.behavior.ask': 'Ask every time',
'config.software.behavior.minimize': 'Minimize to Tray',
'config.software.behavior.exit': 'Exit App',
+39 -25
View File
@@ -83,6 +83,7 @@ export function ConfigPanelPage() {
const [softwareSettings, setSoftwareSettings] = useState<GuiSettings | null>(null);
const [softwareSettingsLoading, setSoftwareSettingsLoading] = useState(true);
const [softwareCloseBehaviorDraft, setSoftwareCloseBehaviorDraft] = useState<CloseBehavior>('ask');
const [softwareSavedStatusVisible, setSoftwareSavedStatusVisible] = useState(false);
const [loading, setLoading] = useState(true);
const [loadError, setLoadError] = useState('');
const [busyAction, setBusyAction] = useState<ConfigAction>(null);
@@ -193,6 +194,7 @@ export function ConfigPanelPage() {
async function loadSoftwareSettings() {
setSoftwareSettingsLoading(true);
setSoftwareSavedStatusVisible(false);
try {
const result = await invoke<GuiSettings>('get_gui_settings');
setSoftwareSettings(result);
@@ -470,9 +472,11 @@ export function ConfigPanelPage() {
});
setSoftwareSettings(result);
setSoftwareCloseBehaviorDraft(result.closeBehavior);
setSoftwareSavedStatusVisible(true);
showNotice(t('config.notice.softwareCloseBehaviorUpdated'), 'success');
} catch (error) {
setSoftwareCloseBehaviorDraft(softwareSettings.closeBehavior);
setSoftwareSavedStatusVisible(false);
showNotice(t('config.error.saveFailed', { error: String(error) }), 'error');
} finally {
setBusyAction(null);
@@ -500,6 +504,19 @@ export function ConfigPanelPage() {
: '';
const softwareCloseBehaviorDirty = softwareSettings !== null
&& softwareCloseBehaviorDraft !== softwareSettings.closeBehavior;
const softwareStatusLabel = softwareSettingsLoading
? t('common.loading')
: softwareSettings === null
? t('common.unavailable')
: softwareCloseBehaviorDirty
? t('config.network.unsaved')
: softwareSavedStatusVisible
? t('config.network.saved')
: '';
const softwareStatusIsSaved = !softwareSettingsLoading
&& softwareSettings !== null
&& !softwareCloseBehaviorDirty
&& softwareSavedStatusVisible;
const networkStatusIsSaved = !loading
&& settings !== null
&& busyAction === null
@@ -538,18 +555,6 @@ export function ConfigPanelPage() {
>
{t('config.tabs.network')}
</button>
<button
type="button"
id="config-subpage-tab-software"
role="tab"
className={activeSubpage === 'software' ? 'active' : ''}
aria-selected={activeSubpage === 'software'}
aria-controls="config-subpage-panel-software"
tabIndex={activeSubpage === 'software' ? 0 : -1}
onClick={() => setActiveSubpage('software')}
>
{t('config.tabs.software')}
</button>
<button
type="button"
id="config-subpage-tab-aliases"
@@ -562,6 +567,18 @@ export function ConfigPanelPage() {
>
{t('app.nav.thinkingAliases')}
</button>
<button
type="button"
id="config-subpage-tab-software"
role="tab"
className={activeSubpage === 'software' ? 'active' : ''}
aria-selected={activeSubpage === 'software'}
aria-controls="config-subpage-panel-software"
tabIndex={activeSubpage === 'software' ? 0 : -1}
onClick={() => setActiveSubpage('software')}
>
{t('config.tabs.software')}
</button>
</div>
{activeSubpage === 'general' ? (
@@ -1008,15 +1025,11 @@ export function ConfigPanelPage() {
<h2>{t('config.software.title')}</h2>
</div>
<div className="config-heading-actions">
<span className={`state-pill ${softwareSettings && !softwareCloseBehaviorDirty ? 'success' : ''}`}>
{softwareSettingsLoading
? t('common.loading')
: softwareSettings === null
? t('common.unavailable')
: softwareCloseBehaviorDirty
? t('config.network.unsaved')
: t('config.network.saved')}
</span>
{softwareStatusLabel ? (
<span className={`state-pill ${softwareStatusIsSaved ? 'success' : ''}`}>
{softwareStatusLabel}
</span>
) : null}
<button
type="button"
className="primary-button compact-button"
@@ -1029,10 +1042,8 @@ export function ConfigPanelPage() {
</div>
</div>
<div className="config-software-content">
<div className="config-management-description">
<strong>{t('config.software.closeBehavior')}</strong>
<div className="config-software-description">
<p>{t('config.software.description')}</p>
<small>{t('config.software.closeBehaviorHint')}</small>
</div>
<label className="config-software-field">
<span>{t('config.software.closeBehavior')}</span>
@@ -1040,7 +1051,10 @@ export function ConfigPanelPage() {
className="config-network-input"
value={softwareCloseBehaviorDraft}
disabled={softwareSettingsLoading || softwareSettings === null || busyAction !== null}
onChange={(event) => setSoftwareCloseBehaviorDraft(event.currentTarget.value as CloseBehavior)}
onChange={(event) => {
setSoftwareSavedStatusVisible(false);
setSoftwareCloseBehaviorDraft(event.currentTarget.value as CloseBehavior);
}}
>
<option value="ask">{t('config.software.behavior.ask')}</option>
<option value="minimize-to-tray">{t('config.software.behavior.minimize')}</option>
+29 -6
View File
@@ -2447,18 +2447,36 @@ textarea:focus-visible {
.config-software-content {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(220px, 320px);
align-items: start;
gap: 24px;
grid-template-columns: minmax(0, 1fr) minmax(260px, 360px);
align-items: stretch;
gap: 16px;
}
.config-software-description,
.config-software-field {
min-width: 0;
min-height: 112px;
padding: 16px;
border: 1px solid var(--theme-d5d2cb);
border: 1px solid var(--theme-e3e1db);
border-radius: 8px;
background: var(--theme-fffdf8);
background: var(--theme-faf8f2);
}
.config-software-description {
display: flex;
align-items: center;
}
.config-software-description p {
margin: 0;
color: var(--theme-6d6760);
font-size: var(--font-size-body);
line-height: var(--line-height-body);
}
.config-software-field {
display: grid;
min-width: 0;
align-content: center;
gap: 8px;
color: var(--theme-39352f);
font-size: var(--font-size-body);
@@ -2487,6 +2505,11 @@ textarea:focus-visible {
.config-software-content {
grid-template-columns: minmax(0, 1fr);
}
.config-software-description,
.config-software-field {
min-height: 0;
}
}
.config-delete-dialog {