feat(界面设计): 系统设置改为分类对话框
build.yaml / build (push) Successful in 45s

This commit is contained in:
xiaoqidun committed 2026-10-30 21:17:28 +08:00
1 parent 8a4967c064
commit f7233616f7
3 files changed
+98 -26

No files matched your search

+13 -3
View File
@@ -447,20 +447,30 @@
</dialog> </dialog>
<dialog id="appearancePanel" class="form-dialog appearance-dialog"> <dialog id="appearancePanel" class="form-dialog appearance-dialog">
<form method="dialog"> <form method="dialog">
<div class="appearance-heading"><h2 id="appearanceTitle" class="form-title">设置</h2><button class="appearance-close" type="submit" title="关闭"><span class="close-icon"></span></button></div> <div class="appearance-heading"><h2 id="appearanceTitle" class="form-title">系统设置</h2><button class="appearance-close" type="submit" title="关闭"><span class="close-icon"></span></button></div>
<div class="appearance-body">
<nav class="appearance-navigation">
<button type="button" data-appearance-category="theme" data-selected="true" autofocus>外观主题</button>
<button id="associationCategory" type="button" data-appearance-category="association" data-selected="false" hidden>文件关联</button>
</nav>
<div class="appearance-content">
<section data-appearance-page="theme">
<div class="appearance-label">外观主题</div> <div class="appearance-label">外观主题</div>
<div class="appearance-themes"> <div class="appearance-themes">
<button type="button" data-theme-choice="system"><span class="theme-system-icon"></span><span>系统</span></button> <button type="button" data-theme-choice="system"><span class="theme-system-icon"></span><span>系统</span></button>
<button type="button" data-theme-choice="light"><span class="theme-light-icon"></span><span>浅色</span></button> <button type="button" data-theme-choice="light"><span class="theme-light-icon"></span><span>浅色</span></button>
<button type="button" data-theme-choice="dark"><span class="theme-dark-icon"></span><span>深色</span></button> <button type="button" data-theme-choice="dark"><span class="theme-dark-icon"></span><span>深色</span></button>
</div> </div>
</form> </section>
<section id="associationSection" class="appearance-associations" hidden> <section id="associationSection" data-appearance-page="association" hidden>
<div class="appearance-label">文件关联</div> <div class="appearance-label">文件关联</div>
<div class="association-row" data-scope="user"><span>当前用户</span><span class="association-state"></span><div class="association-actions"><button class="small-button" type="button" data-action="register">注册</button><button class="small-button" type="button" data-action="remove">撤销</button></div></div> <div class="association-row" data-scope="user"><span>当前用户</span><span class="association-state"></span><div class="association-actions"><button class="small-button" type="button" data-action="register">注册</button><button class="small-button" type="button" data-action="remove">撤销</button></div></div>
<div class="association-row" data-scope="machine"><span>所有用户</span><span class="association-state"></span><div class="association-actions"><button class="small-button" type="button" data-action="register">注册</button><button class="small-button" type="button" data-action="remove">撤销</button></div></div> <div class="association-row" data-scope="machine"><span>所有用户</span><span class="association-state"></span><div class="association-actions"><button class="small-button" type="button" data-action="register">注册</button><button class="small-button" type="button" data-action="remove">撤销</button></div></div>
<div id="associationMessage" class="form-status" hidden></div> <div id="associationMessage" class="form-status" hidden></div>
</section> </section>
</div>
</div>
</form>
</dialog> </dialog>
<dialog id="settingsPanel" class="form-dialog settings-dialog"> <dialog id="settingsPanel" class="form-dialog settings-dialog">
<form id="settingsForm"> <form id="settingsForm">
+71 -18
View File
@@ -1111,11 +1111,6 @@ button:not(:disabled):hover {
overflow-wrap: anywhere; overflow-wrap: anywhere;
} }
.appearance-associations {
padding: 12px;
border-top: 1px solid var(--line);
}
.association-row { .association-row {
display: grid; display: grid;
grid-template-columns: 4em minmax(0, 1fr) auto; grid-template-columns: 4em minmax(0, 1fr) auto;
@@ -1139,8 +1134,8 @@ button:not(:disabled):hover {
#associationMessage { #associationMessage {
margin-top: 12px; margin-top: 12px;
white-space: nowrap; white-space: normal;
overflow-x: auto; overflow-wrap: anywhere;
} }
.form-title { .form-title {
@@ -4839,27 +4834,85 @@ audio.page-media {
} }
.appearance-dialog { .appearance-dialog {
inset: var(--appearance-top, 40px) min(var(--appearance-right, 12px), max(12px, calc(100vw - 297px))) auto auto; width: 680px;
margin: 0; height: 440px;
width: 285px; overflow: hidden;
max-width: calc(100vw - 24px); }
max-height: calc(100dvh - var(--appearance-top, 40px) - 12px);
.appearance-dialog > form {
display: grid;
grid-template-rows: auto minmax(0, 1fr);
height: 100%;
padding: 0; padding: 0;
border-radius: var(--radius-dialog);
background: var(--popup);
box-shadow: var(--shadow-flyout);
} }
.appearance-dialog::backdrop { .appearance-dialog::backdrop {
background: transparent; top: 0;
} }
.appearance-heading { .appearance-heading {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
font-weight: 600; padding: 12px 16px;
margin-bottom: 12px; border-bottom: 1px solid var(--line);
}
.appearance-body {
display: grid;
grid-template-columns: 140px minmax(0, 1fr);
min-height: 0;
}
.appearance-navigation {
display: flex;
flex-direction: column;
gap: 4px;
padding: 12px 8px;
overflow-y: auto;
border-right: 1px solid var(--line);
background: var(--panel);
}
.appearance-navigation button {
flex: none;
min-height: 32px;
padding: 6px 12px;
border: 1px solid transparent;
border-radius: var(--radius-control);
background: transparent;
text-align: left;
}
.appearance-navigation button[data-selected="true"] {
background: var(--selected);
color: var(--accent-strong);
}
.appearance-content {
min-width: 0;
padding: 20px;
overflow-y: auto;
}
@media (max-width: 600px) {
.appearance-body {
grid-template-columns: minmax(0, 1fr);
grid-template-rows: auto minmax(0, 1fr);
}
.appearance-navigation {
flex-direction: row;
flex-wrap: wrap;
padding: 8px 12px;
border-right: 0;
border-bottom: 1px solid var(--line);
}
.appearance-content {
padding: 16px;
}
.appearance-dialog .association-row {
gap: 8px;
}
} }
.appearance-label { .appearance-label {
+14 -5
View File
@@ -203,6 +203,7 @@ const el = {
aboutPanel: document.querySelector("#aboutPanel"), aboutPanel: document.querySelector("#aboutPanel"),
aboutVersion: document.querySelector("#aboutVersion"), aboutVersion: document.querySelector("#aboutVersion"),
associationSection: document.querySelector("#associationSection"), associationSection: document.querySelector("#associationSection"),
associationCategory: document.querySelector("#associationCategory"),
associationMessage: document.querySelector("#associationMessage"), associationMessage: document.querySelector("#associationMessage"),
signButton: document.querySelector("#signButton"), signButton: document.querySelector("#signButton"),
signPanel: document.querySelector("#signPanel"), signPanel: document.querySelector("#signPanel"),
@@ -2122,6 +2123,12 @@ async function openAboutPanel() {
el.aboutVersion.textContent = `${day}-${match[2].slice(0, 7)}`; el.aboutVersion.textContent = `${day}-${match[2].slice(0, 7)}`;
} }
function selectAppearanceCategory(value) {
for (const button of el.appearancePanel.querySelectorAll("[data-appearance-category]")) button.dataset.selected = String(button.dataset.appearanceCategory === value);
for (const section of el.appearancePanel.querySelectorAll("[data-appearance-page]")) section.hidden = section.dataset.appearancePage !== value;
el.appearancePanel.querySelector(".appearance-content").scrollTop = 0;
}
async function refreshFileAssociations() { async function refreshFileAssociations() {
if (!nativeHost || el.associationSection.dataset.busy) return; if (!nativeHost || el.associationSection.dataset.busy) return;
el.associationSection.dataset.busy = "true"; el.associationSection.dataset.busy = "true";
@@ -2132,7 +2139,11 @@ async function refreshFileAssociations() {
} }
try { try {
const states = await nativeHost.call("association.query", {}); const states = await nativeHost.call("association.query", {});
el.associationSection.hidden = !states.user.supported; el.associationCategory.hidden = !states.user.supported;
if (el.associationCategory.hidden && el.associationCategory.dataset.selected === "true") {
selectAppearanceCategory("theme");
if (el.appearancePanel.open) el.appearancePanel.querySelector('[data-appearance-category="theme"]').focus({preventScroll:true});
}
for (const row of el.associationSection.querySelectorAll(".association-row")) { for (const row of el.associationSection.querySelectorAll(".association-row")) {
const state = states[row.dataset.scope]; const state = states[row.dataset.scope];
const label = row.querySelector(".association-state"); const label = row.querySelector(".association-state");
@@ -2142,7 +2153,7 @@ async function refreshFileAssociations() {
row.querySelector('[data-action="remove"]').disabled = !state.writable || !!state.error || !state.registered; row.querySelector('[data-action="remove"]').disabled = !state.writable || !!state.error || !state.registered;
} }
} catch (error) { } catch (error) {
el.associationSection.hidden = false; el.associationCategory.hidden = false;
for (const label of el.associationSection.querySelectorAll(".association-state")) label.textContent = "不可用"; for (const label of el.associationSection.querySelectorAll(".association-state")) label.textContent = "不可用";
el.associationMessage.textContent = `查询失败:${error.message}`; el.associationMessage.textContent = `查询失败:${error.message}`;
el.associationMessage.hidden = false; el.associationMessage.hidden = false;
@@ -5518,13 +5529,11 @@ function resizeViewer() {
async function boot() { async function boot() {
window.ofdgoTheme.connect(nativeHost, error => showError(error, false)); window.ofdgoTheme.connect(nativeHost, error => showError(error, false));
el.appearanceButton.addEventListener("click", () => { el.appearanceButton.addEventListener("click", () => {
const bounds = el.appearanceButton.getBoundingClientRect();
el.appearancePanel.style.setProperty("--appearance-top", `${bounds.bottom + 4}px`);
el.appearancePanel.style.setProperty("--appearance-right", `${Math.max(12, innerWidth - bounds.right)}px`);
el.associationMessage.hidden = true; el.associationMessage.hidden = true;
documentDialogs.showApplication(el.appearancePanel); documentDialogs.showApplication(el.appearancePanel);
if (nativeHost) void refreshFileAssociations(); if (nativeHost) void refreshFileAssociations();
}); });
for (const button of el.appearancePanel.querySelectorAll("[data-appearance-category]")) button.addEventListener("click", () => selectAppearanceCategory(button.dataset.appearanceCategory));
for (const button of el.appearancePanel.querySelectorAll("[data-theme-choice]")) button.addEventListener("click", () => window.ofdgoTheme.set(button.dataset.themeChoice)); for (const button of el.appearancePanel.querySelectorAll("[data-theme-choice]")) button.addEventListener("click", () => window.ofdgoTheme.set(button.dataset.themeChoice));
documentDialogs = new DocumentDialogs({document, titlebar: el.documentTitleBar, documentDialogs = new DocumentDialogs({document, titlebar: el.documentTitleBar,
targets: () => [...document.body.children].filter(node => node !== el.documentTitleBar)}); targets: () => [...document.body.children].filter(node => node !== el.documentTitleBar)});