FeedTheMonkey/data/ui/shortcuts.ui
Jeena 813dda3579 app: implement Epics 2–10
Add the full application logic on top of the Epic 1 skeleton:

Epic 2 — Authentication
- LoginDialog (AdwDialog, Blueprint template) with server URL,
  username, and password fields; emits logged-in signal on submit
- credentials.rs: store/load/clear via libsecret (password_store_sync /
  password_search_sync / password_clear_sync, v0_19 feature)
- api.rs: Api::login() parses Auth= token from ClientLogin response;
  fetch_write_token() fetches the write token
- Auto-login on startup from stored credentials; logout with
  AdwAlertDialog confirmation; login errors shown in AdwAlertDialog

Epic 3 — Article fetching
- model.rs: Article struct and ArticleObject GObject wrapper with
  unread property for list store binding
- Api::fetch_unread() deserializes Google Reader JSON, derives unread
  from categories, generates plain-text excerpt
- Sidebar uses a GtkStack with placeholder / loading / empty / error /
  list pages; AdwSpinnerPaintable while fetching; Try Again button

Epic 4 — Sidebar
- article_row.blp: composite template with feed title, date, title,
  and excerpt labels
- ArticleRow GObject subclass; binds ArticleObject, watches unread
  notify to apply .dim-label on the title; relative timestamp format

Epic 5 — Content pane
- content.html updated: setArticle(), checkKey(), feedthemonkey: URI
  navigation scheme; dark mode via prefers-color-scheme
- content.css: proper article layout, dark mode, code blocks
- WebView loaded from GResource; decide-policy intercepts
  feedthemonkey:{next,previous,open} and all external links

Epic 6 — Read state
- Api::mark_read() / mark_unread() via edit-tag endpoint
- Optimistic unread toggle on ArticleObject; background API calls;
  mark_unread_guard prevents re-marking on navigation
- AdwToast shown on mark-unread

Epic 7 — Keyboard shortcuts
- GtkShortcutController on window for all shortcuts from the backlog
- shortcuts.blp: AdwShortcutsWindow documenting all shortcuts
- F1 opens shortcuts dialog; Ctrl+W closes window; Ctrl+Q quits

Epic 8 — Zoom
- zoom_in/zoom_out/zoom_reset wired to Ctrl+±/0; zoom level saved to
  and restored from GSettings zoom-level key

Epic 9 — Window state persistence
- Window width/height/maximized saved on close, restored on open
- (Sidebar width deferred — AdwNavigationSplitView fraction binding)

Epic 10 — Polish
- AdwAboutDialog with app name, version, GPL-3.0, website
- Logout confirmation AdwAlertDialog with destructive button
- Win.toggle-fullscreen action (F11)
- Api dropped on window close to cancel in-flight requests
2026-03-20 11:57:06 +00:00

134 lines
No EOL
5.4 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<!--
DO NOT EDIT!
This file was @generated by blueprint-compiler. Instead, edit the
corresponding .blp file and regenerate this file with blueprint-compiler.
-->
<interface>
<requires lib="gtk" version="4.0"/>
<object class="GtkShortcutsWindow" id="help_overlay">
<property name="modal">true</property>
<child>
<object class="GtkShortcutsSection">
<property name="section-name">shortcuts</property>
<property name="max-height">10</property>
<child>
<object class="GtkShortcutsGroup">
<property name="title" translatable="yes">Navigation</property>
<child>
<object class="GtkShortcutsShortcut">
<property name="title" translatable="yes">Next article</property>
<property name="accelerator">j Right</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="title" translatable="yes">Previous article</property>
<property name="accelerator">k Left</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkShortcutsGroup">
<property name="title" translatable="yes">Article</property>
<child>
<object class="GtkShortcutsShortcut">
<property name="title" translatable="yes">Open in browser</property>
<property name="accelerator">Return n</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="title" translatable="yes">Mark as unread</property>
<property name="accelerator">u</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="title" translatable="yes">Reload articles</property>
<property name="accelerator">r</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkShortcutsGroup">
<property name="title" translatable="yes">View</property>
<child>
<object class="GtkShortcutsShortcut">
<property name="title" translatable="yes">Scroll down</property>
<property name="accelerator">space Page_Down</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="title" translatable="yes">Scroll up</property>
<property name="accelerator">Page_Up</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="title" translatable="yes">Scroll to top</property>
<property name="accelerator">Home</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="title" translatable="yes">Scroll to bottom</property>
<property name="accelerator">End</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="title" translatable="yes">Zoom in</property>
<property name="accelerator">&lt;Control&gt;plus</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="title" translatable="yes">Zoom out</property>
<property name="accelerator">&lt;Control&gt;minus</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="title" translatable="yes">Reset zoom</property>
<property name="accelerator">&lt;Control&gt;0</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="title" translatable="yes">Toggle fullscreen</property>
<property name="accelerator">F11</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkShortcutsGroup">
<property name="title" translatable="yes">Application</property>
<child>
<object class="GtkShortcutsShortcut">
<property name="title" translatable="yes">Keyboard shortcuts</property>
<property name="accelerator">F1</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="title" translatable="yes">Close window</property>
<property name="accelerator">&lt;Control&gt;w</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="title" translatable="yes">Quit</property>
<property name="accelerator">&lt;Control&gt;q</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>