use router action

Signed-off-by: kernelkind <kernelkind@gmail.com>
This commit is contained in:
kernelkind
2025-05-22 19:57:43 -04:00
parent a44667ef1a
commit c36a22828d
5 changed files with 115 additions and 92 deletions

View File

@@ -500,13 +500,14 @@ fn chrome_handle_app_action(
let txn = Transaction::new(ctx.ndb).unwrap(); let txn = Transaction::new(ctx.ndb).unwrap();
notedeck_columns::actionbar::execute_and_process_note_action( let cols = columns
.decks_cache
.active_columns_mut(ctx.accounts)
.unwrap();
let m_action = notedeck_columns::actionbar::execute_and_process_note_action(
note_action, note_action,
ctx.ndb, ctx.ndb,
columns cols,
.decks_cache
.active_columns_mut(ctx.accounts)
.unwrap(),
0, 0,
&mut columns.timeline_cache, &mut columns.timeline_cache,
ctx.note_cache, ctx.note_cache,
@@ -519,6 +520,12 @@ fn chrome_handle_app_action(
ctx.img_cache, ctx.img_cache,
ui, ui,
); );
if let Some(action) = m_action {
let col = cols.column_mut(0);
action.process(col.router_mut());
}
} }
} }
} }

View File

@@ -1,6 +1,7 @@
use crate::{ use crate::{
column::Columns, column::Columns,
route::{Route, Router}, nav::{RouterAction, RouterType},
route::Route,
timeline::{ThreadSelection, TimelineCache, TimelineKind}, timeline::{ThreadSelection, TimelineCache, TimelineKind},
}; };
@@ -21,12 +22,16 @@ pub enum TimelineOpenResult {
NewNotes(NewNotes), NewNotes(NewNotes),
} }
struct NoteActionResponse {
timeline_res: Option<TimelineOpenResult>,
router_action: Option<RouterAction>,
}
/// The note action executor for notedeck_columns /// The note action executor for notedeck_columns
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn execute_note_action( fn execute_note_action(
action: NoteAction, action: NoteAction,
ndb: &Ndb, ndb: &Ndb,
router: &mut Router<Route>,
timeline_cache: &mut TimelineCache, timeline_cache: &mut TimelineCache,
note_cache: &mut NoteCache, note_cache: &mut NoteCache,
pool: &mut RelayPool, pool: &mut RelayPool,
@@ -36,42 +41,43 @@ fn execute_note_action(
zaps: &mut Zaps, zaps: &mut Zaps,
images: &mut Images, images: &mut Images,
ui: &mut egui::Ui, ui: &mut egui::Ui,
) -> Option<TimelineOpenResult> { ) -> NoteActionResponse {
let mut timeline_res = None;
let mut router_action = None;
match action { match action {
NoteAction::Reply(note_id) => { NoteAction::Reply(note_id) => {
router.route_to(Route::reply(note_id)); router_action = Some(RouterAction::route_to(Route::reply(note_id)));
None
} }
NoteAction::Profile(pubkey) => { NoteAction::Profile(pubkey) => {
let kind = TimelineKind::Profile(pubkey); let kind = TimelineKind::Profile(pubkey);
router.route_to(Route::Timeline(kind.clone())); router_action = Some(RouterAction::route_to(Route::Timeline(kind.clone())));
timeline_cache.open(ndb, note_cache, txn, pool, &kind) timeline_res = timeline_cache.open(ndb, note_cache, txn, pool, &kind);
} }
NoteAction::Note(note_id) => 'ex: { NoteAction::Note(note_id) => 'ex: {
let Ok(thread_selection) = ThreadSelection::from_note_id(ndb, note_cache, txn, note_id) let Ok(thread_selection) = ThreadSelection::from_note_id(ndb, note_cache, txn, note_id)
else { else {
tracing::error!("No thread selection for {}?", hex::encode(note_id.bytes())); tracing::error!("No thread selection for {}?", hex::encode(note_id.bytes()));
break 'ex None; break 'ex;
}; };
let kind = TimelineKind::Thread(thread_selection); let kind = TimelineKind::Thread(thread_selection);
router.route_to(Route::Timeline(kind.clone())); router_action = Some(RouterAction::route_to(Route::Timeline(kind.clone())));
// NOTE!!: you need the note_id to timeline root id thing // NOTE!!: you need the note_id to timeline root id thing
timeline_cache.open(ndb, note_cache, txn, pool, &kind) timeline_res = timeline_cache.open(ndb, note_cache, txn, pool, &kind);
} }
NoteAction::Hashtag(htag) => { NoteAction::Hashtag(htag) => {
let kind = TimelineKind::Hashtag(htag.clone()); let kind = TimelineKind::Hashtag(htag.clone());
router.route_to(Route::Timeline(kind.clone())); router_action = Some(RouterAction::route_to(Route::Timeline(kind.clone())));
timeline_cache.open(ndb, note_cache, txn, pool, &kind) timeline_res = timeline_cache.open(ndb, note_cache, txn, pool, &kind);
} }
NoteAction::Quote(note_id) => { NoteAction::Quote(note_id) => {
router.route_to(Route::quote(note_id)); router_action = Some(RouterAction::route_to(Route::quote(note_id)));
None
} }
NoteAction::Zap(zap_action) => 's: { NoteAction::Zap(zap_action) => 's: {
let Some(cur_acc) = accounts.get_selected_account_mut() else { let Some(cur_acc) = accounts.get_selected_account_mut() else {
break 's None; break 's;
}; };
let sender = cur_acc.key.pubkey; let sender = cur_acc.key.pubkey;
@@ -98,26 +104,26 @@ fn execute_note_action(
} }
ZapAction::ClearError(target) => clear_zap_error(&sender, zaps, target), ZapAction::ClearError(target) => clear_zap_error(&sender, zaps, target),
ZapAction::CustomizeAmount(target) => { ZapAction::CustomizeAmount(target) => {
router.route_to(Route::CustomizeZapAmount(target.to_owned())) let route = Route::CustomizeZapAmount(target.to_owned());
router_action = Some(RouterAction::route_to(route));
} }
} }
None
} }
NoteAction::Context(context) => { NoteAction::Context(context) => match ndb.get_note_by_key(txn, context.note_key) {
match ndb.get_note_by_key(txn, context.note_key) { Err(err) => tracing::error!("{err}"),
Err(err) => tracing::error!("{err}"), Ok(note) => {
Ok(note) => { context.action.process(ui, &note, pool);
context.action.process(ui, &note, pool);
}
} }
None },
}
NoteAction::Media(media_action) => { NoteAction::Media(media_action) => {
media_action.process(images); media_action.process(images);
None
} }
} }
NoteActionResponse {
timeline_res,
router_action,
}
} }
/// Execute a NoteAction and process the result /// Execute a NoteAction and process the result
@@ -125,8 +131,8 @@ fn execute_note_action(
pub fn execute_and_process_note_action( pub fn execute_and_process_note_action(
action: NoteAction, action: NoteAction,
ndb: &Ndb, ndb: &Ndb,
columns: &mut Columns, _columns: &mut Columns,
col: usize, _col: usize,
timeline_cache: &mut TimelineCache, timeline_cache: &mut TimelineCache,
note_cache: &mut NoteCache, note_cache: &mut NoteCache,
pool: &mut RelayPool, pool: &mut RelayPool,
@@ -137,12 +143,10 @@ pub fn execute_and_process_note_action(
zaps: &mut Zaps, zaps: &mut Zaps,
images: &mut Images, images: &mut Images,
ui: &mut egui::Ui, ui: &mut egui::Ui,
) { ) -> Option<RouterAction> {
let router = columns.column_mut(col).router_mut(); let resp = execute_note_action(
if let Some(br) = execute_note_action(
action, action,
ndb, ndb,
router,
timeline_cache, timeline_cache,
note_cache, note_cache,
pool, pool,
@@ -152,9 +156,13 @@ pub fn execute_and_process_note_action(
zaps, zaps,
images, images,
ui, ui,
) { );
if let Some(br) = resp.timeline_res {
br.process(ndb, note_cache, txn, timeline_cache, unknown_ids); br.process(ndb, note_cache, txn, timeline_cache, unknown_ids);
} }
resp.router_action
} }
fn send_zap( fn send_zap(

View File

@@ -7,7 +7,7 @@ use crate::{
profile::{ProfileAction, SaveProfileChanges}, profile::{ProfileAction, SaveProfileChanges},
profile_state::ProfileState, profile_state::ProfileState,
relay_pool_manager::RelayPoolManager, relay_pool_manager::RelayPoolManager,
route::Route, route::{Route, Router},
timeline::{route::render_timeline_route, TimelineCache}, timeline::{route::render_timeline_route, TimelineCache},
ui::{ ui::{
self, self,
@@ -198,6 +198,31 @@ fn process_nav_resp(
switching_occured switching_occured
} }
pub enum RouterAction {
GoBack,
RouteTo(Route, RouterType),
}
pub enum RouterType {
Stack,
}
impl RouterAction {
pub fn process(self, stack_router: &mut Router<Route>) {
match self {
RouterAction::GoBack => {
stack_router.go_back();
}
RouterAction::RouteTo(route, router_type) => match router_type {
RouterType::Stack => stack_router.route_to(route),
},
}
}
pub fn route_to(route: Route) -> Self {
RouterAction::RouteTo(route, RouterType::Stack)
}
}
fn process_render_nav_action( fn process_render_nav_action(
app: &mut Damus, app: &mut Damus,
ctx: &mut AppContext<'_>, ctx: &mut AppContext<'_>,
@@ -205,13 +230,8 @@ fn process_render_nav_action(
col: usize, col: usize,
action: RenderNavAction, action: RenderNavAction,
) -> bool { ) -> bool {
match action { let router_action = match action {
RenderNavAction::Back => { RenderNavAction::Back => Some(RouterAction::GoBack),
app.columns_mut(ctx.accounts)
.column_mut(col)
.router_mut()
.go_back();
}
RenderNavAction::RemoveColumn => { RenderNavAction::RemoveColumn => {
let kinds_to_pop = app.columns_mut(ctx.accounts).delete_column(col); let kinds_to_pop = app.columns_mut(ctx.accounts).delete_column(col);
@@ -231,10 +251,8 @@ fn process_render_nav_action(
Err(err) => tracing::error!("Error executing post action: {err}"), Err(err) => tracing::error!("Error executing post action: {err}"),
Ok(_) => tracing::debug!("Post action executed"), Ok(_) => tracing::debug!("Post action executed"),
} }
get_active_columns_mut(ctx.accounts, &mut app.decks_cache)
.column_mut(col) Some(RouterAction::GoBack)
.router_mut()
.go_back();
} }
RenderNavAction::NoteAction(note_action) => { RenderNavAction::NoteAction(note_action) => {
@@ -255,28 +273,26 @@ fn process_render_nav_action(
ctx.zaps, ctx.zaps,
ctx.img_cache, ctx.img_cache,
ui, ui,
); )
} }
RenderNavAction::SwitchingAction(switching_action) => { RenderNavAction::SwitchingAction(switching_action) => {
return switching_action.process(&mut app.timeline_cache, &mut app.decks_cache, ctx); return switching_action.process(&mut app.timeline_cache, &mut app.decks_cache, ctx);
} }
RenderNavAction::ProfileAction(profile_action) => { RenderNavAction::ProfileAction(profile_action) => profile_action.process(
profile_action.process( &mut app.view_state.pubkey_to_profile_state,
&mut app.view_state.pubkey_to_profile_state, ctx.ndb,
ctx.ndb, ctx.pool,
ctx.pool, ),
get_active_columns_mut(ctx.accounts, &mut app.decks_cache)
.column_mut(col)
.router_mut(),
);
}
RenderNavAction::WalletAction(wallet_action) => { RenderNavAction::WalletAction(wallet_action) => {
let router = get_active_columns_mut(ctx.accounts, &mut app.decks_cache) wallet_action.process(ctx.accounts, ctx.global_wallet)
.column_mut(col)
.router_mut();
wallet_action.process(ctx.accounts, ctx.global_wallet, router)
} }
};
if let Some(action) = router_action {
let cols = get_active_columns_mut(ctx.accounts, &mut app.decks_cache).column_mut(col);
let router = cols.router_mut();
action.process(router);
} }
false false

View File

@@ -5,10 +5,7 @@ use nostrdb::{Ndb, Note, NoteBuildOptions, NoteBuilder};
use tracing::info; use tracing::info;
use crate::{ use crate::{nav::RouterAction, profile_state::ProfileState, route::Route};
profile_state::ProfileState,
route::{Route, Router},
};
pub struct SaveProfileChanges { pub struct SaveProfileChanges {
pub kp: FullKeypair, pub kp: FullKeypair,
@@ -48,12 +45,9 @@ impl ProfileAction {
state_map: &mut HashMap<Pubkey, ProfileState>, state_map: &mut HashMap<Pubkey, ProfileState>,
ndb: &Ndb, ndb: &Ndb,
pool: &mut RelayPool, pool: &mut RelayPool,
router: &mut Router<Route>, ) -> Option<RouterAction> {
) {
match self { match self {
ProfileAction::Edit(kp) => { ProfileAction::Edit(kp) => Some(RouterAction::route_to(Route::EditProfile(kp.pubkey))),
router.route_to(Route::EditProfile(kp.pubkey));
}
ProfileAction::SaveChanges(changes) => { ProfileAction::SaveChanges(changes) => {
let raw_msg = format!("[\"EVENT\",{}]", changes.to_note().json().unwrap()); let raw_msg = format!("[\"EVENT\",{}]", changes.to_note().json().unwrap());
@@ -66,7 +60,7 @@ impl ProfileAction {
info!("sending {}", raw_msg); info!("sending {}", raw_msg);
pool.send(&enostr::ClientMessage::raw(raw_msg)); pool.send(&enostr::ClientMessage::raw(raw_msg));
router.go_back(); Some(RouterAction::GoBack)
} }
} }
} }

View File

@@ -4,7 +4,7 @@ use notedeck::{
PendingDefaultZapState, Wallet, WalletError, WalletUIState, ZapWallet, PendingDefaultZapState, Wallet, WalletError, WalletUIState, ZapWallet,
}; };
use crate::route::{Route, Router}; use crate::{nav::RouterAction, route::Route};
use super::widgets::styled_button; use super::widgets::styled_button;
@@ -55,43 +55,40 @@ impl WalletAction {
&self, &self,
accounts: &mut Accounts, accounts: &mut Accounts,
global_wallet: &mut GlobalWallet, global_wallet: &mut GlobalWallet,
router: &mut Router<Route>, ) -> Option<RouterAction> {
) { let mut action = None;
match &self { match &self {
WalletAction::SaveURI => { WalletAction::SaveURI => {
let ui_state = &mut global_wallet.ui_state; let ui_state = &mut global_wallet.ui_state;
if ui_state.for_local_only { if ui_state.for_local_only {
ui_state.for_local_only = false; ui_state.for_local_only = false;
let Some(cur_acc) = accounts.get_selected_account_mut() else { let cur_acc = accounts.get_selected_account_mut()?;
return;
};
if cur_acc.wallet.is_some() { if cur_acc.wallet.is_some() {
return; return None;
} }
let Some(wallet) = try_create_wallet(ui_state) else { let wallet = try_create_wallet(ui_state)?;
return;
};
accounts.update_current_account(move |acc| { accounts.update_current_account(move |acc| {
acc.wallet = Some(wallet.into()); acc.wallet = Some(wallet.into());
}); });
} else { } else {
if global_wallet.wallet.is_some() { if global_wallet.wallet.is_some() {
return; return None;
} }
let Some(wallet) = try_create_wallet(ui_state) else { let wallet = try_create_wallet(ui_state)?;
return;
};
global_wallet.wallet = Some(wallet.into()); global_wallet.wallet = Some(wallet.into());
global_wallet.save_wallet(); global_wallet.save_wallet();
} }
} }
WalletAction::AddLocalOnly => { WalletAction::AddLocalOnly => {
router.route_to(Route::Wallet(notedeck::WalletType::Local)); action = Some(RouterAction::route_to(Route::Wallet(
notedeck::WalletType::Local,
)));
global_wallet.ui_state.for_local_only = true; global_wallet.ui_state.for_local_only = true;
} }
WalletAction::Delete => { WalletAction::Delete => {
@@ -100,7 +97,7 @@ impl WalletAction {
accounts.update_current_account(|acc| { accounts.update_current_account(|acc| {
acc.wallet = None; acc.wallet = None;
}); });
return; return None;
} }
} }
@@ -153,6 +150,7 @@ impl WalletAction {
(wallet.default_zap.get_default_zap_msats() / 1000).to_string(); (wallet.default_zap.get_default_zap_msats() / 1000).to_string();
} }
} }
action
} }
} }