diff --git a/src/api/user.rs b/src/api/user.rs index 317cf65..1516ba1 100644 --- a/src/api/user.rs +++ b/src/api/user.rs @@ -11,11 +11,13 @@ use crate::settings; pub fn get_user( id: PersonId, page: i64, + saved_only: bool, ) -> std::result::Result { let params = GetPersonDetails { page: Some(page), person_id: Some(id), auth: settings::get_current_account().jwt, + saved_only: Some(saved_only), ..Default::default() }; diff --git a/src/components/profile_page.rs b/src/components/profile_page.rs index 9fef5df..9e59099 100644 --- a/src/components/profile_page.rs +++ b/src/components/profile_page.rs @@ -24,6 +24,7 @@ pub struct ProfilePage { moderates: FactoryVecDeque, editor_dialog: Controller, current_profile_page: i64, + saved_only: bool, } #[derive(Debug)] @@ -36,7 +37,7 @@ pub enum ProfileInput { #[relm4::component(pub)] impl SimpleComponent for ProfilePage { - type Init = GetPersonDetailsResponse; + type Init = (GetPersonDetailsResponse, bool); type Input = ProfileInput; type Output = crate::AppMsg; @@ -47,46 +48,52 @@ impl SimpleComponent for ProfilePage { set_vexpand: false, set_margin_all: 10, - #[local_ref] - avatar -> gtk::Box { - set_size_request: (150, 150), - set_margin_bottom: 20, - set_margin_top: 20, - #[watch] - set_visible: model.info.person_view.person.avatar.is_some(), - }, - gtk::Label { - #[watch] - set_text: &model.info.person_view.person.name, - add_css_class: "font-very-bold", - }, - gtk::Label { - #[watch] - set_markup: &markdown_to_pango_markup(model.info.person_view.person.bio.clone().unwrap_or("".to_string())), - set_wrap: true, - set_use_markup: true, - }, - gtk::Box { - set_orientation: gtk::Orientation::Horizontal, - set_margin_top: 10, - set_margin_bottom: 10, - set_hexpand: false, - set_halign: gtk::Align::Center, + set_orientation: gtk::Orientation::Vertical, + set_vexpand: false, + set_visible: !model.saved_only, + #[local_ref] + avatar -> gtk::Box { + set_size_request: (150, 150), + set_margin_bottom: 20, + set_margin_top: 20, + #[watch] + set_visible: model.info.person_view.person.avatar.is_some(), + }, gtk::Label { #[watch] - set_text: &format!("{} posts, {} comments", model.info.person_view.counts.post_count, model.info.person_view.counts.comment_count), + set_text: &model.info.person_view.person.name, + add_css_class: "font-very-bold", + }, + gtk::Label { + #[watch] + set_markup: &markdown_to_pango_markup(model.info.person_view.person.bio.clone().unwrap_or("".to_string())), + set_wrap: true, + set_use_markup: true, }, - gtk::Button { - set_label: "Send message", - connect_clicked => ProfileInput::SendMessageRequest, - set_margin_start: 10, - set_visible: settings::get_current_account().jwt.is_some(), - } - }, - gtk::Separator {}, + gtk::Box { + set_orientation: gtk::Orientation::Horizontal, + set_margin_top: 10, + set_margin_bottom: 10, + set_hexpand: false, + set_halign: gtk::Align::Center, + + gtk::Label { + #[watch] + set_text: &format!("{} posts, {} comments", model.info.person_view.counts.post_count, model.info.person_view.counts.comment_count), + }, + gtk::Button { + set_label: "Send message", + connect_clicked => ProfileInput::SendMessageRequest, + set_margin_start: 10, + set_visible: settings::get_current_account().jwt.is_some(), + } + }, + + gtk::Separator {}, + }, gtk::StackSwitcher { set_stack: Some(&stack), @@ -131,7 +138,7 @@ impl SimpleComponent for ProfilePage { } fn init( - init: Self::Init, + (info, saved_only): Self::Init, root: &Self::Root, sender: relm4::ComponentSender, ) -> relm4::ComponentParts { @@ -147,13 +154,14 @@ impl SimpleComponent for ProfilePage { _ => unreachable!(), }); let model = ProfilePage { - info: init, + info, avatar, posts, comments, moderates, editor_dialog, current_profile_page: 1, + saved_only, }; let avatar = model.avatar.widget(); let posts = model.posts.widget(); @@ -206,8 +214,9 @@ impl SimpleComponent for ProfilePage { }; self.current_profile_page = page; let person_id = person_id.unwrap_or(self.info.person_view.person.id); + let saved_only = self.saved_only; std::thread::spawn(move || { - match api::user::get_user(person_id, page) { + match api::user::get_user(person_id, page, saved_only) { Ok(person) => { sender.input(ProfileInput::UpdatePerson(person, page == 1)); } diff --git a/src/main.rs b/src/main.rs index be056d2..0a99eee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -46,6 +46,7 @@ pub enum AppState { Login, Message, Inbox, + Saved, AccountsPage, } @@ -62,6 +63,7 @@ struct App { inbox_page: Controller, login_page: Controller, accounts_page: Controller, + saved_page: Controller, logged_in: bool, about_dialog: Controller, } @@ -79,6 +81,7 @@ pub enum AppMsg { OpenPost(PostId), DoneFetchPost(GetPostResponse), OpenInbox, + OpenSaved, OpenCommunities, PopBackStack, UpdateState(AppState), @@ -122,13 +125,19 @@ impl SimpleComponent for App { #[watch] set_visible: model.logged_in, }, + pack_start = >k::Button { + set_label: "Saved", + connect_clicked => AppMsg::OpenSaved, + #[watch] + set_visible: model.logged_in, + }, }, match model.state { AppState::Posts => gtk::Box { #[local_ref] posts_page -> gtk::ScrolledWindow {} - }, + } AppState::Loading => gtk::Box { set_hexpand: true, set_orientation: gtk::Orientation::Vertical, @@ -142,20 +151,19 @@ impl SimpleComponent for App { gtk::Label { set_text: "Loading", }, - }, + } AppState::ChooseInstance => gtk::Box { #[local_ref] instances_page -> gtk::Box {} - }, + } AppState::Login => gtk::Box { #[local_ref] login_page -> gtk::Box {} - }, + } AppState::Communities => gtk::Box { #[local_ref] communities_page -> gtk::Box {} } - AppState::Person => { gtk::Box { #[local_ref] @@ -196,6 +204,12 @@ impl SimpleComponent for App { inbox_page -> gtk::Box {} } } + AppState::Saved => { + gtk::Box { + #[local_ref] + saved_page -> gtk::ScrolledWindow {} + } + } AppState::AccountsPage => { gtk::Box { #[local_ref] @@ -238,7 +252,7 @@ impl SimpleComponent for App { .launch(()) .forward(sender.input_sender(), |msg| msg); let profile_page = ProfilePage::builder() - .launch(default_person()) + .launch((default_person(), false)) .forward(sender.input_sender(), |msg| msg); let community_page = CommunityPage::builder() .launch(default_community().community_view) @@ -261,6 +275,9 @@ impl SimpleComponent for App { let accounts_page = AccountsPage::builder() .launch(()) .forward(sender.input_sender(), |msg| msg); + let saved_page = ProfilePage::builder() + .launch((default_person(), true)) + .forward(sender.input_sender(), |msg| msg); let model = App { state, @@ -277,6 +294,7 @@ impl SimpleComponent for App { accounts_page, message: None, about_dialog, + saved_page, }; // fetch posts if that's the initial page @@ -294,6 +312,7 @@ impl SimpleComponent for App { let communities_page = model.communities_page.widget(); let login_page = model.login_page.widget(); let accounts_page = model.accounts_page.widget(); + let saved_page = model.saved_page.widget(); let widgets = view_output!(); @@ -420,6 +439,13 @@ impl SimpleComponent for App { self.state = AppState::Inbox; self.inbox_page.sender().emit(InboxInput::FetchInbox); } + AppMsg::OpenSaved => { + let person_id = PersonId(settings::get_current_account().id); + self.state = AppState::Loading; + self.saved_page + .sender() + .emit(ProfileInput::FetchPerson(Some(person_id))); + } AppMsg::LoggedIn => { self.logged_in = true; self.back_queue.clear();