column: add individual column
A column for following a single user Closes: https://github.com/damus-io/notedeck/pull/583 Signed-off-by: kernelkind <kernelkind@gmail.com>
This commit is contained in:
committed by
William Casarin
parent
5b4c7a6371
commit
69a6bf3664
@@ -94,6 +94,12 @@ impl Route {
|
|||||||
Cow::Borrowed("Add External Notifications Column")
|
Cow::Borrowed("Add External Notifications Column")
|
||||||
}
|
}
|
||||||
AddColumnRoute::Hashtag => Cow::Borrowed("Add Hashtag Column"),
|
AddColumnRoute::Hashtag => Cow::Borrowed("Add Hashtag Column"),
|
||||||
|
AddColumnRoute::UndecidedIndividual => {
|
||||||
|
Cow::Borrowed("Subscribe to someone's notes")
|
||||||
|
}
|
||||||
|
AddColumnRoute::ExternalIndividual => {
|
||||||
|
Cow::Borrowed("Subscribe to someone else's notes")
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Route::Support => Cow::Borrowed("Damus Support"),
|
Route::Support => Cow::Borrowed("Damus Support"),
|
||||||
Route::NewDeck => Cow::Borrowed("Add Deck"),
|
Route::NewDeck => Cow::Borrowed("Add Deck"),
|
||||||
|
|||||||
@@ -304,12 +304,7 @@ fn deserialize_columns(ndb: &Ndb, deck_user: &[u8; 32], serialized: Vec<Vec<Stri
|
|||||||
match &ir {
|
match &ir {
|
||||||
IntermediaryRoute::Route(Route::Timeline(TimelineRoute::Thread(_)))
|
IntermediaryRoute::Route(Route::Timeline(TimelineRoute::Thread(_)))
|
||||||
| IntermediaryRoute::Route(Route::Timeline(TimelineRoute::Profile(_))) => {
|
| IntermediaryRoute::Route(Route::Timeline(TimelineRoute::Profile(_))) => {
|
||||||
// Do nothing. Threads & Profiles not yet supported for deserialization
|
// Do nothing. TimelineRoute Threads & Profiles not yet supported for deserialization
|
||||||
}
|
|
||||||
IntermediaryRoute::Timeline(tl)
|
|
||||||
if matches!(tl.kind, TimelineKind::Profile(_)) =>
|
|
||||||
{
|
|
||||||
// Do nothing. Profiles aren't yet supported for deserialization
|
|
||||||
}
|
}
|
||||||
_ => cur_routes.push(ir),
|
_ => cur_routes.push(ir),
|
||||||
}
|
}
|
||||||
@@ -361,6 +356,8 @@ enum Keyword {
|
|||||||
Support,
|
Support,
|
||||||
Deck,
|
Deck,
|
||||||
Edit,
|
Edit,
|
||||||
|
IndividualSelection,
|
||||||
|
ExternalIndividualSelection,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Keyword {
|
impl Keyword {
|
||||||
@@ -526,6 +523,12 @@ fn serialize_route(route: &Route, columns: &Columns) -> Option<String> {
|
|||||||
AddColumnRoute::Hashtag => {
|
AddColumnRoute::Hashtag => {
|
||||||
selections.push(Selection::Keyword(Keyword::HashtagSelection))
|
selections.push(Selection::Keyword(Keyword::HashtagSelection))
|
||||||
}
|
}
|
||||||
|
AddColumnRoute::UndecidedIndividual => {
|
||||||
|
selections.push(Selection::Keyword(Keyword::IndividualSelection))
|
||||||
|
}
|
||||||
|
AddColumnRoute::ExternalIndividual => {
|
||||||
|
selections.push(Selection::Keyword(Keyword::ExternalIndividualSelection))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Route::Support => selections.push(Selection::Keyword(Keyword::Support)),
|
Route::Support => selections.push(Selection::Keyword(Keyword::Support)),
|
||||||
@@ -717,6 +720,16 @@ fn selections_to_route(selections: Vec<Selection>) -> Option<CleanIntermediaryRo
|
|||||||
Selection::Keyword(Keyword::HashtagSelection) => Some(CleanIntermediaryRoute::ToRoute(
|
Selection::Keyword(Keyword::HashtagSelection) => Some(CleanIntermediaryRoute::ToRoute(
|
||||||
Route::AddColumn(AddColumnRoute::Hashtag),
|
Route::AddColumn(AddColumnRoute::Hashtag),
|
||||||
)),
|
)),
|
||||||
|
Selection::Keyword(Keyword::IndividualSelection) => {
|
||||||
|
Some(CleanIntermediaryRoute::ToRoute(Route::AddColumn(
|
||||||
|
AddColumnRoute::UndecidedIndividual,
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
Selection::Keyword(Keyword::ExternalIndividualSelection) => {
|
||||||
|
Some(CleanIntermediaryRoute::ToRoute(Route::AddColumn(
|
||||||
|
AddColumnRoute::ExternalIndividual,
|
||||||
|
)))
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
Selection::Keyword(Keyword::Support) => {
|
Selection::Keyword(Keyword::Support) => {
|
||||||
@@ -746,6 +759,8 @@ fn selections_to_route(selections: Vec<Selection>) -> Option<CleanIntermediaryRo
|
|||||||
| Selection::Keyword(Keyword::NotificationSelection)
|
| Selection::Keyword(Keyword::NotificationSelection)
|
||||||
| Selection::Keyword(Keyword::ExternalNotifSelection)
|
| Selection::Keyword(Keyword::ExternalNotifSelection)
|
||||||
| Selection::Keyword(Keyword::HashtagSelection)
|
| Selection::Keyword(Keyword::HashtagSelection)
|
||||||
|
| Selection::Keyword(Keyword::IndividualSelection)
|
||||||
|
| Selection::Keyword(Keyword::ExternalIndividualSelection)
|
||||||
| Selection::Keyword(Keyword::Edit) => None,
|
| Selection::Keyword(Keyword::Edit) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ impl TimelineKind {
|
|||||||
ListKind::Contact(_pubkey_source) => Cow::Borrowed("Contacts"),
|
ListKind::Contact(_pubkey_source) => Cow::Borrowed("Contacts"),
|
||||||
},
|
},
|
||||||
TimelineKind::Notifications(_pubkey_source) => Cow::Borrowed("Notifications"),
|
TimelineKind::Notifications(_pubkey_source) => Cow::Borrowed("Notifications"),
|
||||||
TimelineKind::Profile(_pubkey_source) => Cow::Borrowed("Profile"),
|
TimelineKind::Profile(_pubkey_source) => Cow::Borrowed("Notes"),
|
||||||
TimelineKind::Universe => Cow::Borrowed("Universe"),
|
TimelineKind::Universe => Cow::Borrowed("Universe"),
|
||||||
TimelineKind::Generic => Cow::Borrowed("Custom"),
|
TimelineKind::Generic => Cow::Borrowed("Custom"),
|
||||||
TimelineKind::Hashtag(hashtag) => Cow::Owned(format!("#{}", hashtag)),
|
TimelineKind::Hashtag(hashtag) => Cow::Owned(format!("#{}", hashtag)),
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use egui::{
|
|||||||
pos2, vec2, Align, Button, Color32, FontId, Id, ImageSource, Margin, Pos2, Rect, RichText,
|
pos2, vec2, Align, Button, Color32, FontId, Id, ImageSource, Margin, Pos2, Rect, RichText,
|
||||||
Separator, Ui, Vec2,
|
Separator, Ui, Vec2,
|
||||||
};
|
};
|
||||||
|
use enostr::Pubkey;
|
||||||
use nostrdb::Ndb;
|
use nostrdb::Ndb;
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
@@ -24,6 +25,8 @@ pub enum AddColumnResponse {
|
|||||||
UndecidedNotification,
|
UndecidedNotification,
|
||||||
ExternalNotification,
|
ExternalNotification,
|
||||||
Hashtag,
|
Hashtag,
|
||||||
|
UndecidedIndividual,
|
||||||
|
ExternalIndividual,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum NotificationColumnType {
|
pub enum NotificationColumnType {
|
||||||
@@ -40,6 +43,9 @@ enum AddColumnOption {
|
|||||||
Home(PubkeySource),
|
Home(PubkeySource),
|
||||||
UndecidedHashtag,
|
UndecidedHashtag,
|
||||||
Hashtag(String),
|
Hashtag(String),
|
||||||
|
UndecidedIndividual,
|
||||||
|
ExternalIndividual,
|
||||||
|
Individual(PubkeySource),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
|
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
|
||||||
@@ -48,6 +54,8 @@ pub enum AddColumnRoute {
|
|||||||
UndecidedNotification,
|
UndecidedNotification,
|
||||||
ExternalNotification,
|
ExternalNotification,
|
||||||
Hashtag,
|
Hashtag,
|
||||||
|
UndecidedIndividual,
|
||||||
|
ExternalIndividual,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AddColumnOption {
|
impl AddColumnOption {
|
||||||
@@ -76,6 +84,13 @@ impl AddColumnOption {
|
|||||||
AddColumnOption::Hashtag(hashtag) => TimelineKind::Hashtag(hashtag)
|
AddColumnOption::Hashtag(hashtag) => TimelineKind::Hashtag(hashtag)
|
||||||
.into_timeline(ndb, None)
|
.into_timeline(ndb, None)
|
||||||
.map(AddColumnResponse::Timeline),
|
.map(AddColumnResponse::Timeline),
|
||||||
|
AddColumnOption::UndecidedIndividual => Some(AddColumnResponse::UndecidedIndividual),
|
||||||
|
AddColumnOption::ExternalIndividual => Some(AddColumnResponse::ExternalIndividual),
|
||||||
|
AddColumnOption::Individual(pubkey_source) => {
|
||||||
|
let tlk = TimelineKind::profile(pubkey_source);
|
||||||
|
tlk.into_timeline(ndb, cur_account.map(|a| a.pubkey.bytes()))
|
||||||
|
.map(AddColumnResponse::Timeline)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -128,8 +143,42 @@ impl<'a> AddColumnView<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn external_notification_ui(&mut self, ui: &mut Ui) -> Option<AddColumnResponse> {
|
fn external_notification_ui(&mut self, ui: &mut Ui) -> Option<AddColumnResponse> {
|
||||||
|
let id = ui.id().with("external_notif");
|
||||||
|
|
||||||
|
self.external_ui(ui, id, |pubkey| {
|
||||||
|
AddColumnOption::Notification(PubkeySource::Explicit(pubkey))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn individual_ui(&mut self, ui: &mut Ui) -> Option<AddColumnResponse> {
|
||||||
|
let mut selected_option: Option<AddColumnResponse> = None;
|
||||||
|
for column_option_data in self.get_individual_options() {
|
||||||
|
let option = column_option_data.option.clone();
|
||||||
|
if self.column_option_ui(ui, column_option_data).clicked() {
|
||||||
|
selected_option = option.take_as_response(self.ndb, self.cur_account);
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.add(Separator::default().spacing(0.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
selected_option
|
||||||
|
}
|
||||||
|
|
||||||
|
fn external_individual_ui(&mut self, ui: &mut Ui) -> Option<AddColumnResponse> {
|
||||||
|
let id = ui.id().with("external_individual");
|
||||||
|
|
||||||
|
self.external_ui(ui, id, |pubkey| {
|
||||||
|
AddColumnOption::Individual(PubkeySource::Explicit(pubkey))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn external_ui(
|
||||||
|
&mut self,
|
||||||
|
ui: &mut Ui,
|
||||||
|
id: egui::Id,
|
||||||
|
to_tl: fn(Pubkey) -> AddColumnOption,
|
||||||
|
) -> Option<AddColumnResponse> {
|
||||||
padding(16.0, ui, |ui| {
|
padding(16.0, ui, |ui| {
|
||||||
let id = ui.id().with("external_notif");
|
|
||||||
let key_state = self.key_state_map.entry(id).or_default();
|
let key_state = self.key_state_map.entry(id).or_default();
|
||||||
|
|
||||||
let text_edit = key_state.get_acquire_textedit(|text| {
|
let text_edit = key_state.get_acquire_textedit(|text| {
|
||||||
@@ -164,8 +213,7 @@ impl<'a> AddColumnView<'a> {
|
|||||||
|
|
||||||
if let Some(keypair) = key_state.check_for_successful_login() {
|
if let Some(keypair) = key_state.check_for_successful_login() {
|
||||||
key_state.should_create_new();
|
key_state.should_create_new();
|
||||||
AddColumnOption::Notification(PubkeySource::Explicit(keypair.pubkey))
|
to_tl(keypair.pubkey).take_as_response(self.ndb, self.cur_account)
|
||||||
.take_as_response(self.ndb, self.cur_account)
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -309,6 +357,12 @@ impl<'a> AddColumnView<'a> {
|
|||||||
icon: egui::include_image!("../../../../assets/icons/notifications_icon_dark_4x.png"),
|
icon: egui::include_image!("../../../../assets/icons/notifications_icon_dark_4x.png"),
|
||||||
option: AddColumnOption::UndecidedHashtag,
|
option: AddColumnOption::UndecidedHashtag,
|
||||||
});
|
});
|
||||||
|
vec.push(ColumnOptionData {
|
||||||
|
title: "Individual",
|
||||||
|
description: "Stay up to date with someone's notes & replies",
|
||||||
|
icon: egui::include_image!("../../../../assets/icons/notifications_icon_dark_4x.png"),
|
||||||
|
option: AddColumnOption::UndecidedIndividual,
|
||||||
|
});
|
||||||
|
|
||||||
vec
|
vec
|
||||||
}
|
}
|
||||||
@@ -342,6 +396,36 @@ impl<'a> AddColumnView<'a> {
|
|||||||
|
|
||||||
vec
|
vec
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_individual_options(&self) -> Vec<ColumnOptionData> {
|
||||||
|
let mut vec = Vec::new();
|
||||||
|
|
||||||
|
if let Some(acc) = self.cur_account {
|
||||||
|
let source = if acc.secret_key.is_some() {
|
||||||
|
PubkeySource::DeckAuthor
|
||||||
|
} else {
|
||||||
|
PubkeySource::Explicit(acc.pubkey)
|
||||||
|
};
|
||||||
|
|
||||||
|
vec.push(ColumnOptionData {
|
||||||
|
title: "Your Notes",
|
||||||
|
description: "Keep track of your notes & replies",
|
||||||
|
icon: egui::include_image!(
|
||||||
|
"../../../../assets/icons/notifications_icon_dark_4x.png"
|
||||||
|
),
|
||||||
|
option: AddColumnOption::Individual(source),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
vec.push(ColumnOptionData {
|
||||||
|
title: "Someone else's Notes",
|
||||||
|
description: "Stay up to date with someone else's notes & replies",
|
||||||
|
icon: egui::include_image!("../../../../assets/icons/notifications_icon_dark_4x.png"),
|
||||||
|
option: AddColumnOption::ExternalIndividual,
|
||||||
|
});
|
||||||
|
|
||||||
|
vec
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ColumnOptionData {
|
struct ColumnOptionData {
|
||||||
@@ -368,6 +452,8 @@ pub fn render_add_column_routes(
|
|||||||
AddColumnRoute::UndecidedNotification => add_column_view.notifications_ui(ui),
|
AddColumnRoute::UndecidedNotification => add_column_view.notifications_ui(ui),
|
||||||
AddColumnRoute::ExternalNotification => add_column_view.external_notification_ui(ui),
|
AddColumnRoute::ExternalNotification => add_column_view.external_notification_ui(ui),
|
||||||
AddColumnRoute::Hashtag => hashtag_ui(ui, ctx.ndb, &mut app.view_state.id_string_map),
|
AddColumnRoute::Hashtag => hashtag_ui(ui, ctx.ndb, &mut app.view_state.id_string_map),
|
||||||
|
AddColumnRoute::UndecidedIndividual => add_column_view.individual_ui(ui),
|
||||||
|
AddColumnRoute::ExternalIndividual => add_column_view.external_individual_ui(ui),
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(resp) = resp {
|
if let Some(resp) = resp {
|
||||||
@@ -407,6 +493,22 @@ pub fn render_add_column_routes(
|
|||||||
.router_mut()
|
.router_mut()
|
||||||
.route_to(crate::route::Route::AddColumn(AddColumnRoute::Hashtag));
|
.route_to(crate::route::Route::AddColumn(AddColumnRoute::Hashtag));
|
||||||
}
|
}
|
||||||
|
AddColumnResponse::UndecidedIndividual => {
|
||||||
|
app.columns_mut(ctx.accounts)
|
||||||
|
.column_mut(col)
|
||||||
|
.router_mut()
|
||||||
|
.route_to(crate::route::Route::AddColumn(
|
||||||
|
AddColumnRoute::UndecidedIndividual,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
AddColumnResponse::ExternalIndividual => {
|
||||||
|
app.columns_mut(ctx.accounts)
|
||||||
|
.column_mut(col)
|
||||||
|
.router_mut()
|
||||||
|
.route_to(crate::route::Route::AddColumn(
|
||||||
|
AddColumnRoute::ExternalIndividual,
|
||||||
|
));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user