init external notifs column
Signed-off-by: kernelkind <kernelkind@gmail.com>
This commit is contained in:
@@ -61,7 +61,9 @@ impl Columns {
|
||||
}
|
||||
|
||||
pub fn new_column_picker(&mut self) {
|
||||
self.add_column(Column::new(vec![Route::AddColumn]));
|
||||
self.add_column(Column::new(vec![Route::AddColumn(
|
||||
crate::ui::add_column::AddColumnRoute::Base,
|
||||
)]));
|
||||
}
|
||||
|
||||
fn get_new_id() -> u32 {
|
||||
|
||||
18
src/nav.rs
18
src/nav.rs
@@ -13,7 +13,7 @@ use crate::{
|
||||
},
|
||||
ui::{
|
||||
self,
|
||||
add_column::{AddColumnResponse, AddColumnView},
|
||||
add_column::render_add_column_routes,
|
||||
anim::{AnimationHelper, ICON_EXPANSION_MULTIPLE},
|
||||
note::PostAction,
|
||||
support::SupportView,
|
||||
@@ -101,19 +101,9 @@ pub fn render_nav(col: usize, app: &mut Damus, ui: &mut egui::Ui) {
|
||||
|
||||
None
|
||||
}
|
||||
Route::AddColumn => {
|
||||
let resp =
|
||||
AddColumnView::new(&app.ndb, app.accounts.get_selected_account()).ui(ui);
|
||||
Route::AddColumn(route) => {
|
||||
render_add_column_routes(ui, app, col, route);
|
||||
|
||||
if let Some(resp) = resp {
|
||||
match resp {
|
||||
AddColumnResponse::Timeline(timeline) => {
|
||||
let id = timeline.id;
|
||||
app.columns_mut().add_timeline_to_column(col, timeline);
|
||||
app.subscribe_new_timeline(id);
|
||||
}
|
||||
};
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
@@ -205,7 +195,7 @@ pub fn render_nav(col: usize, app: &mut Damus, ui: &mut egui::Ui) {
|
||||
let cur_router = app.columns_mut().column_mut(col).router_mut();
|
||||
cur_router.navigating = false;
|
||||
if cur_router.is_replacing() {
|
||||
cur_router.remove_previous_route();
|
||||
cur_router.remove_previous_routes();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
26
src/route.rs
26
src/route.rs
@@ -6,7 +6,10 @@ use crate::{
|
||||
account_manager::AccountsRoute,
|
||||
column::Columns,
|
||||
timeline::{TimelineId, TimelineRoute},
|
||||
ui::profile::preview::{get_note_users_displayname_string, get_profile_displayname_string},
|
||||
ui::{
|
||||
add_column::AddColumnRoute,
|
||||
profile::preview::{get_note_users_displayname_string, get_profile_displayname_string},
|
||||
},
|
||||
};
|
||||
|
||||
/// App routing. These describe different places you can go inside Notedeck.
|
||||
@@ -16,7 +19,7 @@ pub enum Route {
|
||||
Accounts(AccountsRoute),
|
||||
Relays,
|
||||
ComposeNote,
|
||||
AddColumn,
|
||||
AddColumn(AddColumnRoute),
|
||||
Profile(Pubkey),
|
||||
Support,
|
||||
}
|
||||
@@ -97,7 +100,13 @@ impl Route {
|
||||
AccountsRoute::AddAccount => "Add Account".to_owned(),
|
||||
},
|
||||
Route::ComposeNote => "Compose Note".to_owned(),
|
||||
Route::AddColumn => "Add Column".to_owned(),
|
||||
Route::AddColumn(c) => match c {
|
||||
AddColumnRoute::Base => "Add Column".to_owned(),
|
||||
AddColumnRoute::UndecidedNotification => "Add Notifications Column".to_owned(),
|
||||
AddColumnRoute::ExternalNotification => {
|
||||
"Add External Notifications Column".to_owned()
|
||||
}
|
||||
},
|
||||
Route::Profile(pubkey) => {
|
||||
format!("{}'s Profile", get_profile_displayname_string(ndb, pubkey))
|
||||
}
|
||||
@@ -142,7 +151,7 @@ impl<R: Clone> Router<R> {
|
||||
self.routes.push(route);
|
||||
}
|
||||
|
||||
// Route to R. Then when it is successfully placed, should call `remove_previous_route`
|
||||
// Route to R. Then when it is successfully placed, should call `remove_previous_routes` to remove all previous routes
|
||||
pub fn route_to_replaced(&mut self, route: R) {
|
||||
self.navigating = true;
|
||||
self.replacing = true;
|
||||
@@ -167,14 +176,15 @@ impl<R: Clone> Router<R> {
|
||||
self.routes.pop()
|
||||
}
|
||||
|
||||
pub fn remove_previous_route(&mut self) -> Option<R> {
|
||||
pub fn remove_previous_routes(&mut self) {
|
||||
let num_routes = self.routes.len();
|
||||
if num_routes <= 1 {
|
||||
return None;
|
||||
return;
|
||||
}
|
||||
|
||||
self.returning = false;
|
||||
self.replacing = false;
|
||||
Some(self.routes.remove(num_routes - 2))
|
||||
self.routes.drain(..num_routes - 1);
|
||||
}
|
||||
|
||||
pub fn is_replacing(&self) -> bool {
|
||||
@@ -208,7 +218,7 @@ impl fmt::Display for Route {
|
||||
},
|
||||
Route::ComposeNote => write!(f, "Compose Note"),
|
||||
|
||||
Route::AddColumn => write!(f, "Add Column"),
|
||||
Route::AddColumn(_) => write!(f, "Add Column"),
|
||||
Route::Profile(_) => write!(f, "Profile"),
|
||||
Route::Support => write!(f, "Support"),
|
||||
}
|
||||
|
||||
@@ -1,26 +1,45 @@
|
||||
use egui::{pos2, vec2, Color32, FontId, ImageSource, Pos2, Rect, Separator, Ui};
|
||||
use egui::{pos2, vec2, Color32, FontId, ImageSource, Pos2, Rect, RichText, Separator, Ui};
|
||||
use nostrdb::Ndb;
|
||||
use tracing::{error, info};
|
||||
|
||||
use crate::{
|
||||
app_style::{get_font_size, NotedeckTextStyle},
|
||||
key_parsing::perform_key_retrieval,
|
||||
timeline::{PubkeySource, Timeline, TimelineKind},
|
||||
ui::anim::ICON_EXPANSION_MULTIPLE,
|
||||
user_account::UserAccount,
|
||||
Damus,
|
||||
};
|
||||
|
||||
use super::anim::AnimationHelper;
|
||||
|
||||
pub enum AddColumnResponse {
|
||||
Timeline(Timeline),
|
||||
UndecidedNotification,
|
||||
ExternalNotification,
|
||||
}
|
||||
|
||||
pub enum NotificationColumnType {
|
||||
Home,
|
||||
External,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
enum AddColumnOption {
|
||||
Universe,
|
||||
UndecidedNotification,
|
||||
ExternalNotification,
|
||||
Notification(PubkeySource),
|
||||
Home(PubkeySource),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
|
||||
pub enum AddColumnRoute {
|
||||
Base,
|
||||
UndecidedNotification,
|
||||
ExternalNotification,
|
||||
}
|
||||
|
||||
impl AddColumnOption {
|
||||
pub fn take_as_response(
|
||||
self,
|
||||
@@ -34,11 +53,15 @@ impl AddColumnOption {
|
||||
AddColumnOption::Notification(pubkey) => TimelineKind::Notifications(pubkey)
|
||||
.into_timeline(ndb, cur_account.map(|a| a.pubkey.bytes()))
|
||||
.map(AddColumnResponse::Timeline),
|
||||
AddColumnOption::UndecidedNotification => {
|
||||
Some(AddColumnResponse::UndecidedNotification)
|
||||
}
|
||||
AddColumnOption::Home(pubkey) => {
|
||||
let tlk = TimelineKind::contact_list(pubkey);
|
||||
tlk.into_timeline(ndb, cur_account.map(|a| a.pubkey.bytes()))
|
||||
.map(AddColumnResponse::Timeline)
|
||||
}
|
||||
AddColumnOption::ExternalNotification => Some(AddColumnResponse::ExternalNotification),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,7 +78,7 @@ impl<'a> AddColumnView<'a> {
|
||||
|
||||
pub fn ui(&mut self, ui: &mut Ui) -> Option<AddColumnResponse> {
|
||||
let mut selected_option: Option<AddColumnResponse> = None;
|
||||
for column_option_data in self.get_column_options() {
|
||||
for column_option_data in self.get_base_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);
|
||||
@@ -67,6 +90,65 @@ impl<'a> AddColumnView<'a> {
|
||||
selected_option
|
||||
}
|
||||
|
||||
fn notifications_ui(&mut self, ui: &mut Ui) -> Option<AddColumnResponse> {
|
||||
let mut selected_option: Option<AddColumnResponse> = None;
|
||||
for column_option_data in self.get_notifications_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_notification_ui(&mut self, ui: &mut Ui) -> Option<AddColumnResponse> {
|
||||
ui.label(RichText::new("External Notification").heading());
|
||||
ui.label("Paste the user's npub that you would like to have a notifications column for:");
|
||||
|
||||
let id = ui.id().with("external_notif");
|
||||
let mut text = ui.ctx().data_mut(|data| {
|
||||
let text = data.get_temp_mut_or_insert_with(id, String::new);
|
||||
text.clone()
|
||||
});
|
||||
ui.text_edit_singleline(&mut text);
|
||||
ui.ctx().data_mut(|d| d.insert_temp(id, text.clone()));
|
||||
|
||||
if ui.button("Validate").clicked() {
|
||||
if let Some(payload) = perform_key_retrieval(&text).ready() {
|
||||
match payload {
|
||||
Ok(keypair) => {
|
||||
info!(
|
||||
"Successfully retrieved external notification keypair {}",
|
||||
keypair.pubkey
|
||||
);
|
||||
if let Some(resp) =
|
||||
AddColumnOption::Notification(PubkeySource::Explicit(keypair.pubkey))
|
||||
.take_as_response(self.ndb, self.cur_account)
|
||||
{
|
||||
Some(resp)
|
||||
} else {
|
||||
error!("Failed to get timeline column");
|
||||
None
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
info!("User did not enter a valid npub or nip05");
|
||||
ui.colored_label(Color32::RED, "Please enter a valid npub or nip05");
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ui.spinner();
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn column_option_ui(&mut self, ui: &mut Ui, data: ColumnOptionData) -> egui::Response {
|
||||
let icon_padding = 8.0;
|
||||
let min_icon_width = 32.0;
|
||||
@@ -168,7 +250,7 @@ impl<'a> AddColumnView<'a> {
|
||||
helper.take_animation_response()
|
||||
}
|
||||
|
||||
fn get_column_options(&self) -> Vec<ColumnOptionData> {
|
||||
fn get_base_options(&self) -> Vec<ColumnOptionData> {
|
||||
let mut vec = Vec::new();
|
||||
vec.push(ColumnOptionData {
|
||||
title: "Universe",
|
||||
@@ -190,14 +272,42 @@ impl<'a> AddColumnView<'a> {
|
||||
icon: egui::include_image!("../../assets/icons/home_icon_dark_4x.png"),
|
||||
option: AddColumnOption::Home(source.clone()),
|
||||
});
|
||||
}
|
||||
vec.push(ColumnOptionData {
|
||||
title: "Notifications",
|
||||
description: "Stay up to date with notifications and mentions",
|
||||
icon: egui::include_image!("../../assets/icons/notifications_icon_dark_4x.png"),
|
||||
option: AddColumnOption::UndecidedNotification,
|
||||
});
|
||||
|
||||
vec
|
||||
}
|
||||
|
||||
fn get_notifications_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: "Notifications",
|
||||
description: "Stay up to date with notifications and mentions",
|
||||
title: "Your Notifications",
|
||||
description: "Stay up to date with your notifications and mentions",
|
||||
icon: egui::include_image!("../../assets/icons/notifications_icon_dark_4x.png"),
|
||||
option: AddColumnOption::Notification(source),
|
||||
});
|
||||
}
|
||||
|
||||
vec.push(ColumnOptionData {
|
||||
title: "Someone else's Notifications",
|
||||
description: "Stay up to date with someone else's notifications and mentions",
|
||||
icon: egui::include_image!("../../assets/icons/notifications_icon_dark_4x.png"),
|
||||
option: AddColumnOption::ExternalNotification,
|
||||
});
|
||||
|
||||
vec
|
||||
}
|
||||
}
|
||||
@@ -209,6 +319,46 @@ struct ColumnOptionData {
|
||||
option: AddColumnOption,
|
||||
}
|
||||
|
||||
pub fn render_add_column_routes(
|
||||
ui: &mut egui::Ui,
|
||||
app: &mut Damus,
|
||||
col: usize,
|
||||
route: &AddColumnRoute,
|
||||
) {
|
||||
let resp = match route {
|
||||
AddColumnRoute::Base => {
|
||||
AddColumnView::new(&app.ndb, app.accounts.get_selected_account()).ui(ui)
|
||||
}
|
||||
AddColumnRoute::UndecidedNotification => {
|
||||
AddColumnView::new(&app.ndb, app.accounts.get_selected_account()).notifications_ui(ui)
|
||||
}
|
||||
AddColumnRoute::ExternalNotification => {
|
||||
AddColumnView::new(&app.ndb, app.accounts.get_selected_account())
|
||||
.external_notification_ui(ui)
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(resp) = resp {
|
||||
match resp {
|
||||
AddColumnResponse::Timeline(timeline) => {
|
||||
let id = timeline.id;
|
||||
app.columns_mut().add_timeline_to_column(col, timeline);
|
||||
app.subscribe_new_timeline(id);
|
||||
}
|
||||
AddColumnResponse::UndecidedNotification => {
|
||||
app.columns_mut().column_mut(col).router_mut().route_to(
|
||||
crate::route::Route::AddColumn(AddColumnRoute::UndecidedNotification),
|
||||
);
|
||||
}
|
||||
AddColumnResponse::ExternalNotification => {
|
||||
app.columns_mut().column_mut(col).router_mut().route_to(
|
||||
crate::route::Route::AddColumn(AddColumnRoute::ExternalNotification),
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
mod preview {
|
||||
use crate::{
|
||||
test_data,
|
||||
|
||||
@@ -196,7 +196,11 @@ impl<'a> DesktopSidePanel<'a> {
|
||||
}
|
||||
}
|
||||
SidePanelAction::Columns => {
|
||||
if router.routes().iter().any(|&r| r == Route::AddColumn) {
|
||||
if router
|
||||
.routes()
|
||||
.iter()
|
||||
.any(|&r| matches!(r, Route::AddColumn(_)))
|
||||
{
|
||||
router.go_back();
|
||||
} else {
|
||||
columns.new_column_picker();
|
||||
|
||||
Reference in New Issue
Block a user