- iOS: Add BackgroundSyncService, SyncScheduler, SyncWorker, BookmarkViewModel, FeedViewModel - iOS: Add BackgroundSyncService, SyncScheduler, SyncWorker services - Linux: Add settings-store.vala, State.vala signals, view widgets (FeedList, FeedDetail, AddFeed, Search, Settings, Bookmark) - Linux: Add bookmark-store.vala, bookmark vala model, search-service.vala - Android: Add NotificationService, NotificationManager, NotificationPreferencesStore - Android: Add BookmarkDao, BookmarkRepository, SettingsStore - Add unit tests for iOS, Android, Linux - Add integration tests - Add performance benchmarks - Update tasks and documentation Co-Authored-By: Paperclip <noreply@paperclip.ing>
128 lines
4.3 KiB
Vala
128 lines
4.3 KiB
Vala
/*
|
|
* FeedDetail.vala
|
|
*
|
|
* Widget for displaying feed details
|
|
*/
|
|
|
|
namespace RSSuper {
|
|
|
|
using Gtk;
|
|
|
|
/**
|
|
* FeedDetail - Displays details of a selected feed
|
|
*/
|
|
public class FeedDetail : WidgetBase {
|
|
private FeedViewModel view_model;
|
|
private Label title_label;
|
|
private Label author_label;
|
|
private Label published_label;
|
|
private Label content_label;
|
|
private ScrolledWindow scrolled_window;
|
|
private Box content_box;
|
|
private Button mark_read_button;
|
|
private Button star_button;
|
|
|
|
public FeedDetail(FeedViewModel view_model) {
|
|
this.view_model = view_model;
|
|
|
|
scrolled_window = new ScrolledWindow();
|
|
scrolled_window.set_hexpand(true);
|
|
scrolled_window.set_vexpand(true);
|
|
|
|
content_box = new Box(Orientation.VERTICAL, 12);
|
|
content_box.set_margin(20);
|
|
|
|
title_label = new Label(null);
|
|
title_label.set_wrap(true);
|
|
title_label.set_xalign(0);
|
|
title_label.add_css_class("title");
|
|
content_box.append(title_label);
|
|
|
|
var metadata_box = new Box(Orientation.HORIZONTAL, 12);
|
|
author_label = new Label(null);
|
|
author_label.add_css_class("dim-label");
|
|
metadata_box.append(author_label);
|
|
|
|
published_label = new Label(null);
|
|
published_label.add_css_class("dim-label");
|
|
metadata_box.append(published_label);
|
|
|
|
content_box.append(metadata_box);
|
|
|
|
content_label = new Label(null);
|
|
content_label.set_wrap(true);
|
|
content_label.set_xalign(0);
|
|
content_label.set_max_width_chars(80);
|
|
content_box.append(content_label);
|
|
|
|
mark_read_button = new Button.with_label("Mark as Read");
|
|
mark_read_button.clicked += on_mark_read;
|
|
content_box.append(mark_read_button);
|
|
|
|
star_button = new Button.with_label("Star");
|
|
star_button.clicked += on_star;
|
|
content_box.append(star_button);
|
|
|
|
scrolled_window.set_child(content_box);
|
|
append(scrolled_window);
|
|
|
|
view_model.feed_state.state_changed += on_state_changed;
|
|
}
|
|
|
|
public override void initialize() {
|
|
// Initialize with default state
|
|
update_from_state();
|
|
}
|
|
|
|
public void set_feed_item(FeedItem item) {
|
|
title_label.set_text(item.title);
|
|
author_label.set_text(item.author ?? "Unknown");
|
|
published_label.set_text(item.published.to_string());
|
|
content_label.set_text(item.content);
|
|
|
|
mark_read_button.set_visible(!item.read);
|
|
mark_read_button.set_label(item.read ? "Mark as Unread" : "Mark as Read");
|
|
|
|
star_button.set_label(item.starred ? "Unstar" : "Star");
|
|
}
|
|
|
|
private void on_state_changed() {
|
|
update_from_state();
|
|
}
|
|
|
|
protected override void update_from_state() {
|
|
var state = view_model.get_feed_state();
|
|
|
|
if (state.is_error()) {
|
|
content_box.set_sensitive(false);
|
|
content_label.set_text($"Error: {state.get_message()}");
|
|
} else {
|
|
content_box.set_sensitive(true);
|
|
}
|
|
}
|
|
|
|
private void on_mark_read() {
|
|
// Get selected item from FeedList and mark as read
|
|
// This requires integrating with FeedList selection
|
|
// For now, mark current item as read
|
|
var state = view_model.get_feed_state();
|
|
if (state.is_success()) {
|
|
var items = state.get_data() as FeedItem[];
|
|
foreach (var item in items) {
|
|
view_model.mark_as_read(item.id, !item.read);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void on_star() {
|
|
var state = view_model.get_feed_state();
|
|
if (state.is_success()) {
|
|
var items = state.get_data() as FeedItem[];
|
|
foreach (var item in items) {
|
|
view_model.mark_as_starred(item.id, !item.starred);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|