onboarding.rs (4224B)
1 use std::mem; 2 3 use egui::{Layout, ScrollArea}; 4 use nostrdb::Ndb; 5 use notedeck::{tr, DragResponse, Images, Localization, MediaJobSender}; 6 use notedeck_ui::{ 7 colors, 8 nip51_set::{Nip51SetUiCache, Nip51SetWidget, Nip51SetWidgetAction, Nip51SetWidgetFlags}, 9 }; 10 11 use crate::{onboarding::Onboarding, ui::widgets::styled_button}; 12 13 /// Display Follow Packs for the user to choose from authors trusted by the Damus team 14 pub struct FollowPackOnboardingView<'a> { 15 onboarding: &'a mut Onboarding, 16 ui_state: &'a mut Nip51SetUiCache, 17 ndb: &'a Ndb, 18 images: &'a mut Images, 19 loc: &'a mut Localization, 20 jobs: &'a MediaJobSender, 21 } 22 23 pub enum OnboardingResponse { 24 FollowPacks(FollowPacksResponse), 25 ViewProfile(enostr::Pubkey), 26 } 27 28 pub enum FollowPacksResponse { 29 NoFollowPacks, 30 UserSelectedPacks(Nip51SetUiCache), 31 } 32 33 impl<'a> FollowPackOnboardingView<'a> { 34 pub fn new( 35 onboarding: &'a mut Onboarding, 36 ui_state: &'a mut Nip51SetUiCache, 37 ndb: &'a Ndb, 38 images: &'a mut Images, 39 loc: &'a mut Localization, 40 jobs: &'a MediaJobSender, 41 ) -> Self { 42 Self { 43 onboarding, 44 ui_state, 45 ndb, 46 images, 47 loc, 48 jobs, 49 } 50 } 51 52 pub fn scroll_id() -> egui::Id { 53 egui::Id::new("follow_pack_onboarding") 54 } 55 56 pub fn ui(&mut self, ui: &mut egui::Ui) -> DragResponse<OnboardingResponse> { 57 let Some(follow_pack_state) = self.onboarding.get_follow_packs() else { 58 return DragResponse::output(Some(OnboardingResponse::FollowPacks( 59 FollowPacksResponse::NoFollowPacks, 60 ))); 61 }; 62 63 let max_height = ui.available_height() - 48.0; 64 65 let mut action = None; 66 let mut should_reset_list = false; 67 let scroll_out = ScrollArea::vertical() 68 .id_salt(Self::scroll_id()) 69 .max_height(max_height) 70 .show(ui, |ui| { 71 egui::Frame::new().inner_margin(8.0).show(ui, |ui| { 72 self.onboarding.list.borrow_mut().ui_custom_layout( 73 ui, 74 follow_pack_state.len(), 75 |ui, index| { 76 let resp = Nip51SetWidget::new( 77 follow_pack_state, 78 self.ui_state, 79 self.ndb, 80 self.loc, 81 self.images, 82 self.jobs, 83 ) 84 .with_flags(Nip51SetWidgetFlags::TRUST_IMAGES) 85 .render_at_index(ui, index); 86 87 notedeck_ui::hline(ui); 88 89 if let Some(cur_action) = resp.action { 90 match cur_action { 91 Nip51SetWidgetAction::ViewProfile(pubkey) => { 92 action = Some(OnboardingResponse::ViewProfile(pubkey)); 93 } 94 } 95 } 96 97 if resp.visibility_changed { 98 should_reset_list = true; 99 } 100 101 if resp.rendered { 102 1 103 } else { 104 0 105 } 106 }, 107 ); 108 }) 109 }); 110 111 if should_reset_list { 112 self.onboarding.list.borrow_mut().reset(); 113 } 114 115 ui.with_layout(Layout::top_down(egui::Align::Center), |ui| { 116 ui.add_space(4.0); 117 if ui.add(styled_button(tr!(self.loc, "Done", "Button to indicate that the user is done going through the onboarding process.").as_str(), colors::PINK)).clicked() { 118 action = Some(OnboardingResponse::FollowPacks( 119 FollowPacksResponse::UserSelectedPacks(mem::take(self.ui_state)), 120 )); 121 } 122 }); 123 124 DragResponse::output(action).scroll_raw(scroll_out.id) 125 } 126 }