notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

commit 792abf11d77e5989497a893f76d58b6ca1c4a964
parent 679a5afdebbb446552041526f3be740c4c84e128
Author: kernelkind <kernelkind@gmail.com>
Date:   Thu, 21 Nov 2024 20:15:26 -0500

add new column type: hashtag

Signed-off-by: kernelkind <kernelkind@gmail.com>

Diffstat:
Msrc/route.rs | 1+
Msrc/timeline/kind.rs | 17+++++++++++++++++
Msrc/ui/add_column.rs | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
Msrc/view_state.rs | 1+
4 files changed, 79 insertions(+), 18 deletions(-)

diff --git a/src/route.rs b/src/route.rs @@ -113,6 +113,7 @@ impl Route { AddColumnRoute::ExternalNotification => { "Add External Notifications Column".to_owned() } + AddColumnRoute::Hashtag => "Add Hashtag Column".to_owned(), }, Route::Support => "Damus Support".to_owned(), }; diff --git a/src/timeline/kind.rs b/src/timeline/kind.rs @@ -40,6 +40,8 @@ pub enum TimelineKind { /// Generic filter Generic, + + Hashtag(String), } impl Display for TimelineKind { @@ -50,6 +52,7 @@ impl Display for TimelineKind { TimelineKind::Notifications(_) => f.write_str("Notifications"), TimelineKind::Profile(_) => f.write_str("Profile"), TimelineKind::Universe => f.write_str("Universe"), + TimelineKind::Hashtag(_) => f.write_str("Hashtag"), } } } @@ -126,6 +129,19 @@ impl TimelineKind { )) } + TimelineKind::Hashtag(hashtag) => { + let filter = Filter::new() + .kinds([1]) + .limit(filter::default_limit()) + .tags([hashtag.clone()], 't') + .build(); + + Some(Timeline::new( + TimelineKind::Hashtag(hashtag), + FilterState::ready(vec![filter]), + )) + } + TimelineKind::List(ListKind::Contact(pk_src)) => { let pk = match &pk_src { PubkeySource::DeckAuthor => default_user?, @@ -186,6 +202,7 @@ impl TimelineKind { }, TimelineKind::Universe => "Universe".to_owned(), TimelineKind::Generic => "Custom Filter".to_owned(), + TimelineKind::Hashtag(hashtag) => format!("#{}", hashtag), } } } diff --git a/src/ui/add_column.rs b/src/ui/add_column.rs @@ -24,6 +24,7 @@ pub enum AddColumnResponse { Timeline(Timeline), UndecidedNotification, ExternalNotification, + Hashtag, } pub enum NotificationColumnType { @@ -38,6 +39,8 @@ enum AddColumnOption { ExternalNotification, Notification(PubkeySource), Home(PubkeySource), + UndecidedHashtag, + Hashtag(String), } #[derive(Clone, Copy, Eq, PartialEq, Debug, Serialize, Deserialize)] @@ -45,6 +48,7 @@ pub enum AddColumnRoute { Base, UndecidedNotification, ExternalNotification, + Hashtag, } impl AddColumnOption { @@ -69,6 +73,10 @@ impl AddColumnOption { .map(AddColumnResponse::Timeline) } AddColumnOption::ExternalNotification => Some(AddColumnResponse::ExternalNotification), + AddColumnOption::UndecidedHashtag => Some(AddColumnResponse::Hashtag), + AddColumnOption::Hashtag(hashtag) => TimelineKind::Hashtag(hashtag) + .into_timeline(ndb, None) + .map(AddColumnResponse::Timeline), } } } @@ -292,6 +300,12 @@ impl<'a> AddColumnView<'a> { icon: egui::include_image!("../../assets/icons/notifications_icon_dark_4x.png"), option: AddColumnOption::UndecidedNotification, }); + vec.push(ColumnOptionData { + title: "Hashtag", + description: "Stay up to date with a certain hashtag", + icon: egui::include_image!("../../assets/icons/notifications_icon_dark_4x.png"), + option: AddColumnOption::UndecidedHashtag, + }); vec } @@ -338,25 +352,16 @@ pub fn render_add_column_routes( col: usize, route: &AddColumnRoute, ) { + let mut add_column_view = AddColumnView::new( + &mut app.view_state.id_state_map, + &app.ndb, + app.accounts.get_selected_account(), + ); let resp = match route { - AddColumnRoute::Base => AddColumnView::new( - &mut app.view_state.id_state_map, - &app.ndb, - app.accounts.get_selected_account(), - ) - .ui(ui), - AddColumnRoute::UndecidedNotification => AddColumnView::new( - &mut app.view_state.id_state_map, - &app.ndb, - app.accounts.get_selected_account(), - ) - .notifications_ui(ui), - AddColumnRoute::ExternalNotification => AddColumnView::new( - &mut app.view_state.id_state_map, - &app.ndb, - app.accounts.get_selected_account(), - ) - .external_notification_ui(ui), + AddColumnRoute::Base => add_column_view.ui(ui), + AddColumnRoute::UndecidedNotification => add_column_view.notifications_ui(ui), + AddColumnRoute::ExternalNotification => add_column_view.external_notification_ui(ui), + AddColumnRoute::Hashtag => hashtag_ui(ui, &app.ndb, &mut app.view_state.id_string_map), }; if let Some(resp) = resp { @@ -382,10 +387,47 @@ pub fn render_add_column_routes( crate::route::Route::AddColumn(AddColumnRoute::ExternalNotification), ); } + AddColumnResponse::Hashtag => { + app.columns_mut() + .column_mut(col) + .router_mut() + .route_to(crate::route::Route::AddColumn(AddColumnRoute::Hashtag)); + } }; } } +pub fn hashtag_ui( + ui: &mut Ui, + ndb: &Ndb, + id_string_map: &mut HashMap<Id, String>, +) -> Option<AddColumnResponse> { + padding(16.0, ui, |ui| { + let id = ui.id().with("hashtag"); + let text_buffer = id_string_map.entry(id).or_default(); + + let text_edit = egui::TextEdit::singleline(text_buffer) + .hint_text( + RichText::new("Enter the desired hashtag here") + .text_style(NotedeckTextStyle::Body.text_style()), + ) + .vertical_align(Align::Center) + .desired_width(f32::INFINITY) + .min_size(Vec2::new(0.0, 40.0)) + .margin(Margin::same(12.0)); + ui.add(text_edit); + + if ui.button("Add").clicked() { + let resp = AddColumnOption::Hashtag(text_buffer.to_owned()).take_as_response(ndb, None); + id_string_map.remove(&id); + resp + } else { + None + } + }) + .inner +} + mod preview { use crate::{ test_data, diff --git a/src/view_state.rs b/src/view_state.rs @@ -7,6 +7,7 @@ use crate::login_manager::AcquireKeyState; pub struct ViewState { pub login: AcquireKeyState, pub id_state_map: HashMap<egui::Id, AcquireKeyState>, + pub id_string_map: HashMap<egui::Id, String>, } impl ViewState {