forked from jeena/FeedTheMonkey
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.
This commit is contained in:
parent
141f9ee32d
commit
8fd52dd8a0
16 changed files with 680 additions and 320 deletions
75
src/preferences_dialog.rs
Normal file
75
src/preferences_dialog.rs
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
use gtk4::prelude::*;
|
||||
use gtk4::subclass::prelude::*;
|
||||
use gtk4::{gio, glib};
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct PreferencesDialog(ObjectSubclass<imp::PreferencesDialog>)
|
||||
@extends libadwaita::Dialog, gtk4::Widget,
|
||||
@implements gtk4::Accessible, gtk4::Buildable, gtk4::ConstraintTarget;
|
||||
}
|
||||
|
||||
impl PreferencesDialog {
|
||||
pub fn new() -> Self {
|
||||
glib::Object::builder().build()
|
||||
}
|
||||
}
|
||||
|
||||
pub mod imp {
|
||||
use super::*;
|
||||
use gtk4::CompositeTemplate;
|
||||
use libadwaita::subclass::prelude::*;
|
||||
|
||||
#[derive(CompositeTemplate, Default)]
|
||||
#[template(resource = "/net/jeena/FeedTheMonkey/ui/preferences_dialog.ui")]
|
||||
pub struct PreferencesDialog {
|
||||
#[template_child]
|
||||
pub filters_text_view: TemplateChild<gtk4::TextView>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for PreferencesDialog {
|
||||
const NAME: &'static str = "PreferencesDialog";
|
||||
type Type = super::PreferencesDialog;
|
||||
type ParentType = libadwaita::Dialog;
|
||||
|
||||
fn class_init(klass: &mut Self::Class) {
|
||||
klass.bind_template();
|
||||
}
|
||||
|
||||
fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
|
||||
obj.init_template();
|
||||
}
|
||||
}
|
||||
|
||||
impl ObjectImpl for PreferencesDialog {
|
||||
fn constructed(&self) {
|
||||
self.parent_constructed();
|
||||
self.load();
|
||||
// Save on every text change
|
||||
let obj_weak = self.obj().downgrade();
|
||||
self.filters_text_view.buffer().connect_changed(move |_| {
|
||||
if let Some(obj) = obj_weak.upgrade() {
|
||||
obj.imp().save();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl PreferencesDialog {
|
||||
fn load(&self) {
|
||||
let settings = gio::Settings::new("net.jeena.FeedTheMonkey");
|
||||
let text = settings.string("content-filters");
|
||||
self.filters_text_view.buffer().set_text(&text);
|
||||
}
|
||||
|
||||
fn save(&self) {
|
||||
let buf = self.filters_text_view.buffer();
|
||||
let text = buf.text(&buf.start_iter(), &buf.end_iter(), false);
|
||||
let settings = gio::Settings::new("net.jeena.FeedTheMonkey");
|
||||
settings.set_string("content-filters", &text).ok();
|
||||
}
|
||||
}
|
||||
|
||||
impl WidgetImpl for PreferencesDialog {}
|
||||
impl AdwDialogImpl for PreferencesDialog {}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue