tauri-app: settings view + profile polish

- App.svelte: new 'settings' view with account/actions/about sections,
  sign-out button, pdsBase()/appviewBase() helpers, showError wired
  into logout, profile gains open-in-browser + sign-out + recent-posts
  heading
- NavRail: add settings item + gear icon, View union extended to 5
- tests: NavRail.test.ts now expects 5 buttons + covers settings click,
  NavRailHarness View type extended
This commit is contained in:
tomdebone
2026-07-07 18:52:10 +02:00
parent 550b89673d
commit 43fc889d47
4 changed files with 209 additions and 8 deletions
@@ -4,7 +4,7 @@
// `$bindable`, use a callback prop to bubble state changes up to
// the parent.
type View = "home" | "compose" | "profile" | "search";
type View = "home" | "compose" | "profile" | "search" | "settings";
let {
view = "home",
@@ -19,6 +19,7 @@
{ id: "compose", label: "compose", key: "c", icon: "compose" },
{ id: "profile", label: "profile", key: "p", icon: "profile" },
{ id: "search", label: "search", key: "/", icon: "search" },
{ id: "settings", label: "settings", key: ",", icon: "settings" },
];
</script>
@@ -44,6 +45,11 @@
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6">
<circle cx="12" cy="8" r="4"/><path d="M4 21c0-4 4-7 8-7s8 3 8 7"/>
</svg>
{:else if item.icon === "settings"}
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="3"/>
<path d="M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-1-1.5 1.7 1.7 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1a1.7 1.7 0 0 0 1.5-1 1.7 1.7 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.8.3h.1a1.7 1.7 0 0 0 1-1.5V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.8v.1a1.7 1.7 0 0 0 1.5 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1z"/>
</svg>
{:else}
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6">
<circle cx="11" cy="11" r="7"/><path d="m20 20-3-3"/>
@@ -29,10 +29,10 @@ async function mountHarness() {
}
describe("NavRail (callback-prop pattern)", () => {
it("renders 4 buttons with home active", async () => {
it("renders 5 buttons with home active", async () => {
await mountHarness();
const btns = target.querySelectorAll("button.rail__btn");
expect(btns.length).toBe(4);
expect(btns.length).toBe(5);
expect(btns[0].classList.contains("active")).toBe(true);
expect(target.querySelector('[data-testid="view-value"]')?.textContent).toBe("home");
});
@@ -56,5 +56,10 @@ describe("NavRail (callback-prop pattern)", () => {
await tick();
expect(target.querySelector('[data-testid="view-value"]')?.textContent).toBe("profile");
expect(btns[2].classList.contains("active")).toBe(true);
btns[4].dispatchEvent(new MouseEvent("click", { bubbles: true }));
await tick();
expect(target.querySelector('[data-testid="view-value"]')?.textContent).toBe("settings");
expect(btns[4].classList.contains("active")).toBe(true);
});
});
@@ -5,7 +5,7 @@
import NavRail from "./NavRail.svelte";
type View = "home" | "compose" | "profile" | "search";
type View = "home" | "compose" | "profile" | "search" | "settings";
let view: View = $state("home");
</script>