Files
RSSuper/linux/src/view/search.vala
Michael Freno 14efe072fa feat: implement cross-platform features and UI integration
- 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>
2026-03-30 23:06:12 -04:00

129 lines
4.0 KiB
Vala

/*
* Search.vala
*
* Widget for searching feed items
*/
namespace RSSuper {
using Gtk;
/**
* Search - Widget for searching feed items
*/
public class Search : WidgetBase {
private SearchService search_service;
private Entry search_entry;
private Button search_button;
private Label status_label;
private ListView results_view;
private ListStore results_store;
private ScrolledWindow scrolled_window;
public Search(SearchService search_service) {
this.search_service = search_service;
set_orientation(Orientation.VERTICAL);
set_spacing(12);
set_margin(20);
var title_label = new Label("Search");
title_label.add_css_class("heading");
append(title_label);
var search_box = new Box(Orientation.HORIZONTAL, 6);
search_box.set_hexpand(true);
search_entry = new Entry();
search_entry.set_placeholder_text("Search feeds...");
search_entry.set_hexpand(true);
search_entry.activate += on_search;
search_box.append(search_entry);
search_button = new Button.with_label("Search");
search_button.clicked += on_search;
search_box.append(search_button);
append(search_box);
status_label = new Label(null);
status_label.set_xalign(0);
status_label.set_wrap(true);
append(status_label);
scrolled_window = new ScrolledWindow();
scrolled_window.set_hexpand(true);
scrolled_window.set_vexpand(true);
results_store = new ListStore(1, typeof(string));
results_view = new ListView(results_store);
var factory = SignalListItemFactory.new();
factory.setup += on_setup;
factory.bind += on_bind;
factory.unset += on_unset;
results_view.set_factory(factory);
scrolled_window.set_child(results_view);
append(scrolled_window);
}
public override void initialize() {
// Initialize with default state
}
protected override void update_from_state() {
// Update from state if needed
}
private void on_search() {
var query = search_entry.get_text();
if (query.is_empty()) {
status_label.set_text("Please enter a search query");
return;
}
search_button.set_sensitive(false);
status_label.set_text("Searching...");
search_service.search(query, (state) => {
if (state.is_success()) {
var results = state.get_data() as SearchResult[];
update_results(results);
status_label.set_text($"Found {results.length} results");
} else if (state.is_error()) {
status_label.set_text($"Error: {state.get_message()}");
}
search_button.set_sensitive(true);
});
}
private void on_setup(ListItem item) {
var label = new Label(null);
label.set_xalign(0);
label.set_wrap(true);
label.set_max_width_chars(80);
item.set_child(label);
}
private void on_bind(ListItem item) {
var label = item.get_child() as Label;
var result = item.get_item() as SearchResult;
if (result != null) {
label.set_text(result.title);
}
}
private void on_unset(ListItem item) {
item.set_child(null);
}
private void update_results(SearchResult[] results) {
results_store.splice(0, results_store.get_n_items(), results);
}
}
}