notedeck

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

mod.rs (5897B)


      1 use enostr::{FullKeypair, Pubkey};
      2 use nostrdb::{Ndb, Transaction};
      3 
      4 use notedeck::{Accounts, AppContext, Localization, SingleUnkIdAction, UnknownIds};
      5 
      6 use crate::app::get_active_columns_mut;
      7 use crate::decks::DecksCache;
      8 use crate::profile::send_new_contact_list;
      9 use crate::{
     10     login_manager::AcquireKeyState,
     11     route::Route,
     12     timeline::TimelineCache,
     13     ui::{
     14         account_login_view::{AccountLoginResponse, AccountLoginView},
     15         accounts::{AccountsView, AccountsViewResponse},
     16     },
     17 };
     18 use tracing::info;
     19 
     20 mod route;
     21 
     22 pub use route::{AccountsRoute, AccountsRouteResponse};
     23 
     24 impl AddAccountAction {
     25     // Simple wrapper around processing the unknown action to expose too
     26     // much internal logic. This allows us to have a must_use on our
     27     // LoginAction type, otherwise the SingleUnkIdAction's must_use will
     28     // be lost when returned in the login action
     29     pub fn process_action(&mut self, ids: &mut UnknownIds, ndb: &Ndb, txn: &Transaction) {
     30         self.unk_id_action.process_action(ids, ndb, txn);
     31     }
     32 }
     33 
     34 #[derive(Debug, Clone)]
     35 pub struct SwitchAccountAction {
     36     pub source_column: usize,
     37 
     38     /// The account to switch to
     39     pub switch_to: Pubkey,
     40 }
     41 
     42 impl SwitchAccountAction {
     43     pub fn new(source_column: usize, switch_to: Pubkey) -> Self {
     44         SwitchAccountAction {
     45             source_column,
     46             switch_to,
     47         }
     48     }
     49 }
     50 
     51 #[derive(Debug)]
     52 pub enum AccountsAction {
     53     Switch(SwitchAccountAction),
     54     Remove(Pubkey),
     55 }
     56 
     57 #[must_use = "You must call process_login_action on this to handle unknown ids"]
     58 pub struct AddAccountAction {
     59     pub accounts_action: Option<AccountsAction>,
     60     pub unk_id_action: SingleUnkIdAction,
     61 }
     62 
     63 /// Render account management views from a route
     64 #[allow(clippy::too_many_arguments)]
     65 pub fn render_accounts_route(
     66     ui: &mut egui::Ui,
     67     app_ctx: &mut AppContext,
     68     col: usize,
     69     decks: &mut DecksCache,
     70     timeline_cache: &mut TimelineCache,
     71     login_state: &mut AcquireKeyState,
     72     route: AccountsRoute,
     73 ) -> AddAccountAction {
     74     let resp = match route {
     75         AccountsRoute::Accounts => AccountsView::new(
     76             app_ctx.ndb,
     77             app_ctx.accounts,
     78             app_ctx.img_cache,
     79             app_ctx.i18n,
     80         )
     81         .ui(ui)
     82         .inner
     83         .map(AccountsRouteResponse::Accounts),
     84 
     85         AccountsRoute::AddAccount => {
     86             AccountLoginView::new(login_state, app_ctx.clipboard, app_ctx.i18n)
     87                 .ui(ui)
     88                 .inner
     89                 .map(AccountsRouteResponse::AddAccount)
     90         }
     91     };
     92 
     93     if let Some(resp) = resp {
     94         match resp {
     95             AccountsRouteResponse::Accounts(response) => {
     96                 let action = process_accounts_view_response(
     97                     app_ctx.i18n,
     98                     app_ctx.accounts,
     99                     decks,
    100                     col,
    101                     response,
    102                 );
    103                 AddAccountAction {
    104                     accounts_action: action,
    105                     unk_id_action: SingleUnkIdAction::no_action(),
    106                 }
    107             }
    108             AccountsRouteResponse::AddAccount(response) => {
    109                 let action =
    110                     process_login_view_response(app_ctx, timeline_cache, decks, col, response);
    111                 *login_state = Default::default();
    112                 let router = get_active_columns_mut(app_ctx.i18n, app_ctx.accounts, decks)
    113                     .column_mut(col)
    114                     .router_mut();
    115                 router.go_back();
    116                 action
    117             }
    118         }
    119     } else {
    120         AddAccountAction {
    121             accounts_action: None,
    122             unk_id_action: SingleUnkIdAction::no_action(),
    123         }
    124     }
    125 }
    126 
    127 pub fn process_accounts_view_response(
    128     i18n: &mut Localization,
    129     accounts: &mut Accounts,
    130     decks: &mut DecksCache,
    131     col: usize,
    132     response: AccountsViewResponse,
    133 ) -> Option<AccountsAction> {
    134     let router = get_active_columns_mut(i18n, accounts, decks)
    135         .column_mut(col)
    136         .router_mut();
    137     let mut action = None;
    138     match response {
    139         AccountsViewResponse::RemoveAccount(pk_to_remove) => {
    140             let cur_action = AccountsAction::Remove(pk_to_remove);
    141             info!("account selection: {:?}", action);
    142             action = Some(cur_action);
    143         }
    144         AccountsViewResponse::SelectAccount(new_pk) => {
    145             let acc_sel = AccountsAction::Switch(SwitchAccountAction::new(col, new_pk));
    146             info!("account selection: {:?}", acc_sel);
    147             action = Some(acc_sel);
    148         }
    149         AccountsViewResponse::RouteToLogin => {
    150             router.route_to(Route::add_account());
    151         }
    152     }
    153     action
    154 }
    155 
    156 pub fn process_login_view_response(
    157     app_ctx: &mut AppContext,
    158     timeline_cache: &mut TimelineCache,
    159     decks: &mut DecksCache,
    160     col: usize,
    161     response: AccountLoginResponse,
    162 ) -> AddAccountAction {
    163     let (r, pubkey) = match response {
    164         AccountLoginResponse::CreateNew => {
    165             let kp = FullKeypair::generate();
    166             let pubkey = kp.pubkey;
    167             send_new_contact_list(kp.to_filled(), app_ctx.ndb, app_ctx.pool);
    168             (app_ctx.accounts.add_account(kp.to_keypair()), pubkey)
    169         }
    170         AccountLoginResponse::LoginWith(keypair) => {
    171             let pubkey = keypair.pubkey;
    172             (app_ctx.accounts.add_account(keypair), pubkey)
    173         }
    174     };
    175 
    176     decks.add_deck_default(app_ctx, timeline_cache, pubkey);
    177 
    178     if let Some(action) = r {
    179         AddAccountAction {
    180             accounts_action: Some(AccountsAction::Switch(SwitchAccountAction {
    181                 source_column: col,
    182                 switch_to: action.switch_to,
    183             })),
    184             unk_id_action: action.unk_id_action,
    185         }
    186     } else {
    187         AddAccountAction {
    188             accounts_action: None,
    189             unk_id_action: SingleUnkIdAction::NoAction,
    190         }
    191     }
    192 }