// Main window + sidebar (AGENTS.md §6, §7). // // Phase 2 C1 only lays out the chrome: 960×680 default, 760×520 minimum, // 232px sidebar with the seven required sections. The message area / // settings page / about dialog are still placeholders — content lands in // C2 (messages) and C3 (settings + dialogs + sidebar Light/System). import { AppearanceMode } from "./theme.slint"; import { NavItem, SectionLabel } from "./components.slint"; import { MessageItem } from "./message-card.slint"; import { MessageList } from "./message-list.slint"; import { EmptyState } from "./empty-state.slint"; export enum SidebarSelection { All, Settings, About, } export component MainWindow inherits Window { title: "Gotify"; preferred-width: 960px; preferred-height: 680px; min-width: 760px; min-height: 520px; // Theme switch — Rust-controllable via `ui.set_theme(...)`. Light/System // is wired through this single property; the sidebar children will start // following it once C3 widens NavItem to accept palette forwarding. in-out property theme: AppearanceMode.Dark; out property is-dark: theme != AppearanceMode.Light; // Palette — all derived from `is-dark` (AGENTS.md §52). out property bg: is-dark ? #1f2024 : #f5f6f8; out property surface: is-dark ? #28292d : #ffffff; out property surface-elev: is-dark ? #2f3035 : #fafbfc; out property border: is-dark ? #3a3b40 : #e4e6ea; out property text-primary: is-dark ? #e6e6e6 : #1a1a1a; out property text-second: is-dark ? #a0a0a0 : #5c5c5c; out property text-muted: is-dark ? #6a6a6a : #9a9a9a; out property accent: is-dark ? #4ea1ff : #0a66c2; out property success: #4caf50; out property warning: #ff9800; out property danger: #f44336; out property priority-low: #6a6a6a; out property priority-normal: is-dark ? #4ea1ff : #0a66c2; out property priority-high: #ff9800; out property priority-max: #f44336; background: bg; in-out property selection: SidebarSelection.All; // Phase 2 C2: mock-driven message list + selection state. Set from Rust // via `ui.set_messages(model)` in `run()`. The list / empty-state switch // is purely driven by `messages.length` (Slint's `for` over an empty // model is a no-op). in-out property <[MessageItem]> messages; in-out property selected-message-index: -1; // Hooks that Phase 6 (Windows Integration) wires to a real Windows // toast. C2 logs them so the click path is observable end-to-end. callback test-notification-clicked(); callback message-card-clicked(int); HorizontalLayout { // §7 Sidebar width: 220-240px. Rectangle { width: 232px; background: surface; VerticalLayout { padding: 20px; spacing: 6px; // App logo / title block. Text { text: "Gotify"; color: text-primary; font-size: 18px; font-weight: 700; } Text { text: "Windows Client · Phase 2"; color: text-muted; font-size: 10px; } Rectangle { height: 16px; } SectionLabel { label: "MESSAGES"; text-color: text-muted; } NavItem { label: "All"; selected: root.selection == SidebarSelection.All; clicked => { root.selection = SidebarSelection.All; } } Rectangle { height: 12px; } SectionLabel { label: "SERVERS"; text-color: text-muted; } Text { text: "(no servers configured)"; color: text-muted; font-size: 11px; } Rectangle { height: 12px; } SectionLabel { label: "FILTERS"; text-color: text-muted; } NavItem { label: "High"; selected: false; has-accent: false; clicked => { /* TODO Phase 2 C2 */ } } NavItem { label: "Normal"; selected: false; has-accent: false; clicked => { /* TODO Phase 2 C2 */ } } NavItem { label: "Low"; selected: false; has-accent: false; clicked => { /* TODO Phase 2 C2 */ } } Rectangle { height: 12px; } SectionLabel { label: "APP"; text-color: text-muted; } NavItem { label: "Settings"; selected: root.selection == SidebarSelection.Settings; clicked => { root.selection = SidebarSelection.Settings; } } NavItem { label: "About"; selected: root.selection == SidebarSelection.About; clicked => { root.selection = SidebarSelection.About; } } } } // Right pane — placeholder content driven by `selection`. Rectangle { background: bg; if root.selection == SidebarSelection.All: VerticalLayout { padding: 24px; spacing: 12px; Text { text: messages.length == 0 ? "Messages" : "Messages · " + messages.length; color: text-primary; font-size: 18px; font-weight: 700; } if messages.length > 0: MessageList { messages: messages; selected-index: root.selected-message-index; height: parent.height - 48px; message-clicked(idx) => { root.selected-message-index = idx; root.message-card-clicked(idx); } } if messages.length == 0: EmptyState { test-notification => { root.test-notification-clicked(); } } } if root.selection == SidebarSelection.Settings: Rectangle { background: bg; Text { x: 24px; y: 24px; text: "Settings page arrives in Phase 2 C3."; color: text-muted; font-size: 13px; } } if root.selection == SidebarSelection.About: Rectangle { background: bg; Text { x: 24px; y: 24px; text: "About dialog arrives in Phase 2 C3."; color: text-muted; font-size: 13px; } } } } }