notedeck

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

mod.rs (8122B)


      1 use enostr::{FullKeypair, Pubkey};
      2 use nostrdb::{Ndb, Transaction};
      3 
      4 use notedeck::{Accounts, AppContext, DragResponse, Localization, SingleUnkIdAction, UnknownIds};
      5 use notedeck_ui::nip51_set::Nip51SetUiCache;
      6 
      7 pub use crate::accounts::route::AccountsResponse;
      8 use crate::app::get_active_columns_mut;
      9 use crate::decks::DecksCache;
     10 use crate::onboarding::Onboarding;
     11 use crate::profile::{send_default_dms_relay_list, send_new_contact_list};
     12 use crate::subscriptions::Subscriptions;
     13 use crate::ui::onboarding::{FollowPackOnboardingView, FollowPacksResponse, OnboardingResponse};
     14 use crate::{
     15     login_manager::AcquireKeyState,
     16     route::Route,
     17     ui::{
     18         account_login_view::{AccountLoginResponse, AccountLoginView},
     19         accounts::{AccountsView, AccountsViewResponse},
     20     },
     21 };
     22 use tracing::info;
     23 
     24 mod route;
     25 
     26 pub use route::{AccountsRoute, AccountsRouteResponse};
     27 
     28 impl AddAccountAction {
     29     // Simple wrapper around processing the unknown action to expose too
     30     // much internal logic. This allows us to have a must_use on our
     31     // LoginAction type, otherwise the SingleUnkIdAction's must_use will
     32     // be lost when returned in the login action
     33     pub fn process_action(&mut self, ids: &mut UnknownIds, ndb: &Ndb, txn: &Transaction) {
     34         self.unk_id_action.process_action(ids, ndb, txn);
     35     }
     36 }
     37 
     38 #[derive(Debug, Clone)]
     39 pub struct SwitchAccountAction {
     40     pub source_column: usize,
     41 
     42     /// The account to switch to
     43     pub switch_to: Pubkey,
     44     pub switching_to_new: bool,
     45 }
     46 
     47 impl SwitchAccountAction {
     48     pub fn new(source_column: usize, switch_to: Pubkey) -> Self {
     49         SwitchAccountAction {
     50             source_column,
     51             switch_to,
     52             switching_to_new: false,
     53         }
     54     }
     55 
     56     pub fn switching_to_new(mut self) -> Self {
     57         self.switching_to_new = true;
     58         self
     59     }
     60 }
     61 
     62 #[derive(Debug)]
     63 pub enum AccountsAction {
     64     Switch(SwitchAccountAction),
     65     Remove(Pubkey),
     66 }
     67 
     68 #[must_use = "You must call process_login_action on this to handle unknown ids"]
     69 pub struct AddAccountAction {
     70     pub accounts_action: Option<AccountsAction>,
     71     pub unk_id_action: SingleUnkIdAction,
     72 }
     73 
     74 /// Render account management views from a route
     75 #[allow(clippy::too_many_arguments)]
     76 pub fn render_accounts_route(
     77     ui: &mut egui::Ui,
     78     app_ctx: &mut AppContext,
     79     login_state: &mut AcquireKeyState,
     80     onboarding: &mut Onboarding,
     81     follow_packs_ui: &mut Nip51SetUiCache,
     82     route: AccountsRoute,
     83 ) -> DragResponse<AccountsResponse> {
     84     match route {
     85         AccountsRoute::Accounts => AccountsView::new(
     86             app_ctx.ndb,
     87             app_ctx.accounts,
     88             app_ctx.media_jobs.sender(),
     89             app_ctx.img_cache,
     90             app_ctx.i18n,
     91         )
     92         .ui(ui)
     93         .map_output(AccountsRouteResponse::Accounts)
     94         .map_output(AccountsResponse::Account),
     95         AccountsRoute::AddAccount => {
     96             let action = AccountLoginView::new(login_state, app_ctx.clipboard, app_ctx.i18n)
     97                 .ui(ui)
     98                 .inner
     99                 .map(AccountsRouteResponse::AddAccount)
    100                 .map(AccountsResponse::Account);
    101             DragResponse::output(action)
    102         }
    103         AccountsRoute::Onboarding => FollowPackOnboardingView::new(
    104             onboarding,
    105             follow_packs_ui,
    106             app_ctx.ndb,
    107             app_ctx.img_cache,
    108             app_ctx.i18n,
    109             app_ctx.media_jobs.sender(),
    110         )
    111         .ui(ui)
    112         .map_output(|r| match r {
    113             OnboardingResponse::FollowPacks(follow_packs_response) => {
    114                 AccountsResponse::Account(AccountsRouteResponse::AddAccount(
    115                     AccountLoginResponse::Onboarding(follow_packs_response),
    116                 ))
    117             }
    118             OnboardingResponse::ViewProfile(pubkey) => AccountsResponse::ViewProfile(pubkey),
    119         }),
    120     }
    121 }
    122 
    123 pub fn process_accounts_view_response(
    124     i18n: &mut Localization,
    125     accounts: &mut Accounts,
    126     decks: &mut DecksCache,
    127     col: usize,
    128     response: AccountsViewResponse,
    129 ) -> Option<AccountsAction> {
    130     let router = get_active_columns_mut(i18n, accounts, decks)
    131         .column_mut(col)
    132         .router_mut();
    133     let mut action = None;
    134     match response {
    135         AccountsViewResponse::RemoveAccount(pk_to_remove) => {
    136             let cur_action = AccountsAction::Remove(pk_to_remove);
    137             info!("account selection: {:?}", action);
    138             action = Some(cur_action);
    139         }
    140         AccountsViewResponse::SelectAccount(new_pk) => {
    141             let acc_sel = AccountsAction::Switch(SwitchAccountAction::new(col, new_pk));
    142             info!("account selection: {:?}", acc_sel);
    143             action = Some(acc_sel);
    144         }
    145         AccountsViewResponse::RouteToLogin => {
    146             router.route_to(Route::add_account());
    147         }
    148     }
    149     action
    150 }
    151 
    152 pub fn process_login_view_response(
    153     app_ctx: &mut AppContext,
    154     decks: &mut DecksCache,
    155     subs: &mut Subscriptions,
    156     onboarding: &mut Onboarding,
    157     col: usize,
    158     response: AccountLoginResponse,
    159 ) -> AddAccountAction {
    160     let cur_router = get_active_columns_mut(app_ctx.i18n, app_ctx.accounts, decks)
    161         .column_mut(col)
    162         .router_mut();
    163 
    164     let r = match response {
    165         AccountLoginResponse::LoginWith(keypair) => {
    166             cur_router.go_back();
    167             app_ctx.accounts.add_account(keypair)
    168         }
    169         AccountLoginResponse::CreatingNew => {
    170             cur_router.route_to(Route::Accounts(AccountsRoute::Onboarding));
    171 
    172             onboarding.process(app_ctx.pool, app_ctx.ndb, subs, app_ctx.unknown_ids);
    173 
    174             None
    175         }
    176         AccountLoginResponse::Onboarding(onboarding_response) => match onboarding_response {
    177             FollowPacksResponse::NoFollowPacks => {
    178                 onboarding.process(app_ctx.pool, app_ctx.ndb, subs, app_ctx.unknown_ids);
    179                 None
    180             }
    181             FollowPacksResponse::UserSelectedPacks(nip51_sets_ui_state) => {
    182                 let pks_to_follow = nip51_sets_ui_state.get_all_selected();
    183 
    184                 let kp = FullKeypair::generate();
    185 
    186                 send_new_contact_list(kp.to_filled(), app_ctx.ndb, app_ctx.pool, pks_to_follow);
    187                 send_default_dms_relay_list(kp.to_filled(), app_ctx.ndb, app_ctx.pool);
    188                 cur_router.go_back();
    189                 onboarding.end_onboarding(app_ctx.pool, app_ctx.ndb);
    190 
    191                 app_ctx.accounts.add_account(kp.to_keypair())
    192             }
    193         },
    194     };
    195 
    196     if let Some(action) = r {
    197         AddAccountAction {
    198             accounts_action: Some(AccountsAction::Switch(SwitchAccountAction {
    199                 source_column: col,
    200                 switch_to: action.switch_to,
    201                 switching_to_new: true,
    202             })),
    203             unk_id_action: action.unk_id_action,
    204         }
    205     } else {
    206         AddAccountAction {
    207             accounts_action: None,
    208             unk_id_action: SingleUnkIdAction::NoAction,
    209         }
    210     }
    211 }
    212 
    213 impl AccountsRouteResponse {
    214     pub fn process(
    215         self,
    216         app_ctx: &mut AppContext,
    217         app: &mut crate::Damus,
    218         col: usize,
    219     ) -> AddAccountAction {
    220         match self {
    221             AccountsRouteResponse::Accounts(response) => {
    222                 let action = process_accounts_view_response(
    223                     app_ctx.i18n,
    224                     app_ctx.accounts,
    225                     &mut app.decks_cache,
    226                     col,
    227                     response,
    228                 );
    229                 AddAccountAction {
    230                     accounts_action: action,
    231                     unk_id_action: notedeck::SingleUnkIdAction::no_action(),
    232                 }
    233             }
    234             AccountsRouteResponse::AddAccount(response) => {
    235                 let action = process_login_view_response(
    236                     app_ctx,
    237                     &mut app.decks_cache,
    238                     &mut app.subscriptions,
    239                     &mut app.onboarding,
    240                     col,
    241                     response,
    242                 );
    243                 app.view_state.login = Default::default();
    244 
    245                 action
    246             }
    247         }
    248     }
    249 }