FeedTheMonkey/data/ui/window.blp
Jeena 8fd52dd8a0 ui: overhaul sidebar, add content filters and state improvements
Sidebar layout:
- Replace AdwNavigationSplitView with GtkPaned for a resizable sidebar
  with a persistent width stored in GSettings.
- Apply navigation-sidebar CSS class to the content Stack only (not the
  ToolbarView) so both header bars share the same colour and height.
- Override Adwaita's automatic paned-first-child header tint and gap via
  application-level CSS.
- Remove the gap between the sidebar header and the first list item.
- Add toggle-sidebar button and F9 shortcut; sidebar visibility and width
  are persisted across restarts.

Loading indicator:
- Replace the large AdwSpinner status page + header Stack with a small
  Gtk.Spinner (16×16) in the header Stack so the header height never
  changes during loading.

Article row:
- Add hexpand to title and excerpt labels so text reflows when the
  sidebar is resized.

Content:
- Inline CSS into the HTML template at load time (/*INJECT_CSS*/
  placeholder) so WebKit does not need a custom URI scheme handler.
- Fix max-width centering and padding for article body and header.
- Fix embedded video/iframe auto-opening in browser by checking
  NavigationType::LinkClicked instead of is_user_gesture().

Content filters:
- Add Preferences dialog with a TextView for content-rewrite rules
  stored in GSettings (content-filters key).
- Rule format: "domain find replace [find replace …]" one per line.
- Rules are applied to article HTML before display and reloaded on
  every refresh.

Shortcuts:
- Add Ctrl+W to close, Ctrl+Q to quit, F1 for keyboard shortcuts
  overlay, j/k and arrow-key navigation via a capture-phase controller
  so keys work regardless of which widget has focus.

Misc:
- Set window title to "FeedTheMonkey" (fixes Hyprland title bar).
- Update About dialog website URL.
2026-03-21 01:13:01 +00:00

191 lines
4.2 KiB
Text

using Gtk 4.0;
using Adw 1;
using WebKit 6.0;
template $FeedTheMonkeyWindow : Adw.ApplicationWindow {
default-width: 900;
default-height: 600;
Adw.ToastOverlay toast_overlay {
Paned paned {
focusable: false;
shrink-start-child: false;
resize-start-child: false;
start-child: Adw.ToolbarView sidebar_toolbar {
top-bar-style: raised;
[top]
Adw.HeaderBar {
show-start-title-buttons: false;
show-end-title-buttons: false;
title-widget: Box {};
[start]
Stack refresh_stack {
StackPage {
name: "button";
child: Button refresh_button {
icon-name: "view-refresh-symbolic";
tooltip-text: _("Refresh");
action-name: "win.reload";
};
}
StackPage {
name: "spinner";
child: Spinner {
spinning: true;
width-request: 16;
height-request: 16;
};
}
}
[end]
MenuButton menu_button {
icon-name: "open-menu-symbolic";
primary: true;
menu-model: primary_menu;
}
}
Stack sidebar_content {
styles ["sidebar-content"]
StackPage {
name: "placeholder";
child: Adw.StatusPage {
icon-name: "rss-symbolic";
title: _("FeedTheMonkey");
description: _("Log in to load your articles");
};
}
StackPage {
name: "loading";
child: Adw.StatusPage {
title: _("Loading…");
};
}
StackPage {
name: "empty";
child: Adw.StatusPage {
icon-name: "rss-symbolic";
title: _("No Unread Articles");
};
}
StackPage {
name: "error";
child: Adw.StatusPage error_status {
icon-name: "network-error-symbolic";
title: _("Could Not Load Articles");
Button {
label: _("Try Again");
halign: center;
action-name: "win.reload";
styles ["pill", "suggested-action"]
}
};
}
StackPage {
name: "list";
child: ScrolledWindow {
hscrollbar-policy: never;
ListView article_list_view {
single-click-activate: false;
show-separators: true;
}
};
}
}
};
end-child: Adw.ToolbarView {
top-bar-style: raised;
[top]
Adw.HeaderBar {
[start]
Button toggle_sidebar_button {
icon-name: "sidebar-show-symbolic";
tooltip-text: _("Toggle Sidebar");
action-name: "win.toggle-sidebar";
}
title-widget: Adw.WindowTitle {
title: _("FeedTheMonkey");
};
[end]
MenuButton article_menu_button {
icon-name: "view-more-symbolic";
menu-model: article_menu;
visible: false;
}
}
Stack content_stack {
StackPage {
name: "empty";
child: Adw.StatusPage {
icon-name: "document-open-symbolic";
title: _("No Article Selected");
};
}
StackPage {
name: "webview";
child: WebKit.WebView web_view {};
}
}
};
}
}
}
menu primary_menu {
section {
item {
label: _("Log Out");
action: "win.logout";
}
}
section {
item {
label: _("Preferences");
action: "win.preferences";
}
}
section {
item {
label: _("Keyboard Shortcuts");
action: "win.show-help-overlay";
}
item {
label: _("About FeedTheMonkey");
action: "app.about";
}
}
}
menu article_menu {
section {
item {
label: _("Mark Unread");
action: "win.mark-unread";
}
item {
label: _("Open in Browser");
action: "win.open-in-browser";
}
}
}