Support for viewing the next pages of communities and posts
This commit is contained in:
parent
598288434f
commit
07343a3021
|
@ -22,9 +22,8 @@ Working:
|
||||||
- Editing and deleting posts or comments
|
- Editing and deleting posts or comments
|
||||||
- Viewing the personal inbox (mentions, replies)
|
- Viewing the personal inbox (mentions, replies)
|
||||||
|
|
||||||
Not yet working, but planned to be added soon:
|
Not yet supported:
|
||||||
|
|
||||||
- Viewing the next pages of posts or communities
|
|
||||||
- Private messages
|
- Private messages
|
||||||
|
|
||||||
# Build dependencies
|
# Build dependencies
|
||||||
|
|
|
@ -137,7 +137,7 @@ impl FactoryComponent for CommentRow {
|
||||||
let comment_id = self.comment.comment.id;
|
let comment_id = self.comment.comment.id;
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
let _ = api::comment::delete_comment(comment_id);
|
let _ = api::comment::delete_comment(comment_id);
|
||||||
let _ = sender.output(PostInput::PassAppMessage(crate::AppMsg::StartFetchPosts(None)));
|
let _ = sender.output(PostInput::PassAppMessage(crate::AppMsg::StartFetchPosts(None, true)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
CommentRowMsg::OpenEditCommentDialog => {
|
CommentRowMsg::OpenEditCommentDialog => {
|
||||||
|
|
|
@ -16,11 +16,13 @@ pub struct CommunityPage {
|
||||||
posts: FactoryVecDeque<PostRow>,
|
posts: FactoryVecDeque<PostRow>,
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
create_post_dialog: Controller<EditorDialog>,
|
create_post_dialog: Controller<EditorDialog>,
|
||||||
|
current_posts_page: i64
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum CommunityInput {
|
pub enum CommunityInput {
|
||||||
UpdateCommunity(CommunityView),
|
UpdateCommunity(CommunityView),
|
||||||
|
FetchPosts,
|
||||||
DoneFetchPosts(Vec<PostView>),
|
DoneFetchPosts(Vec<PostView>),
|
||||||
OpenCreatePostDialog,
|
OpenCreatePostDialog,
|
||||||
CreatePostRequest(EditorData),
|
CreatePostRequest(EditorData),
|
||||||
|
@ -112,6 +114,12 @@ impl SimpleComponent for CommunityPage {
|
||||||
#[local_ref]
|
#[local_ref]
|
||||||
posts -> gtk::Box {
|
posts -> gtk::Box {
|
||||||
set_orientation: gtk::Orientation::Vertical,
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
|
},
|
||||||
|
|
||||||
|
gtk::Button {
|
||||||
|
set_label: "More",
|
||||||
|
set_margin_all: 10,
|
||||||
|
connect_clicked => CommunityInput::FetchPosts,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +142,7 @@ impl SimpleComponent for CommunityPage {
|
||||||
_ => CommunityInput::None
|
_ => CommunityInput::None
|
||||||
});
|
});
|
||||||
|
|
||||||
let model = CommunityPage { info: init, avatar, posts, create_post_dialog: dialog };
|
let model = CommunityPage { info: init, avatar, posts, create_post_dialog: dialog, current_posts_page: 0 };
|
||||||
let avatar = model.avatar.widget();
|
let avatar = model.avatar.widget();
|
||||||
let posts = model.posts.widget();
|
let posts = model.posts.widget();
|
||||||
let widgets = view_output!();
|
let widgets = view_output!();
|
||||||
|
@ -148,10 +156,16 @@ impl SimpleComponent for CommunityPage {
|
||||||
self.info = community.clone();
|
self.info = community.clone();
|
||||||
self.avatar.emit(get_web_image_msg(community.community.icon));
|
self.avatar.emit(get_web_image_msg(community.community.icon));
|
||||||
self.posts.guard().clear();
|
self.posts.guard().clear();
|
||||||
|
self.current_posts_page = 0;
|
||||||
|
if community.counts.posts == 0 { return; }
|
||||||
|
sender.input(CommunityInput::FetchPosts);
|
||||||
|
}
|
||||||
|
CommunityInput::FetchPosts => {
|
||||||
|
let name = self.info.community.name.clone();
|
||||||
|
self.current_posts_page += 1;
|
||||||
|
let page = self.current_posts_page;
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
if community.counts.posts == 0 { return; }
|
let community_posts = api::posts::list_posts(page, Some(name), None);
|
||||||
let community_posts = api::posts::list_posts(1, Some(community.community.name), None);
|
|
||||||
if let Ok(community_posts) = community_posts {
|
if let Ok(community_posts) = community_posts {
|
||||||
sender.input(CommunityInput::DoneFetchPosts(community_posts));
|
sender.input(CommunityInput::DoneFetchPosts(community_posts));
|
||||||
}
|
}
|
||||||
|
|
|
@ -280,7 +280,7 @@ impl SimpleComponent for PostPage {
|
||||||
let post_id = self.info.post_view.post.id;
|
let post_id = self.info.post_view.post.id;
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
let _ = api::post::delete_post(post_id);
|
let _ = api::post::delete_post(post_id);
|
||||||
let _ = sender.output(crate::AppMsg::StartFetchPosts(None));
|
let _ = sender.output(crate::AppMsg::StartFetchPosts(None, true));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
PostInput::OpenEditPostDialog => {
|
PostInput::OpenEditPostDialog => {
|
||||||
|
|
|
@ -162,7 +162,7 @@ impl FactoryComponent for PostRow {
|
||||||
let post_id = self.post.post.id;
|
let post_id = self.post.post.id;
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
let _ = api::post::delete_post(post_id);
|
let _ = api::post::delete_post(post_id);
|
||||||
let _ = sender.output(crate::AppMsg::StartFetchPosts(None));
|
let _ = sender.output(crate::AppMsg::StartFetchPosts(None, true));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
77
src/main.rs
77
src/main.rs
|
@ -40,6 +40,9 @@ struct App {
|
||||||
logged_in: bool,
|
logged_in: bool,
|
||||||
current_communities_type: Option<ListingType>,
|
current_communities_type: Option<ListingType>,
|
||||||
current_posts_type: Option<ListingType>,
|
current_posts_type: Option<ListingType>,
|
||||||
|
current_communities_page: i64,
|
||||||
|
current_posts_page: i64,
|
||||||
|
community_search_buffer: gtk::EntryBuffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -52,10 +55,10 @@ pub enum AppMsg {
|
||||||
Retry,
|
Retry,
|
||||||
ShowMessage(String),
|
ShowMessage(String),
|
||||||
DoneChoosingInstance(String),
|
DoneChoosingInstance(String),
|
||||||
StartFetchPosts(Option<ListingType>),
|
StartFetchPosts(Option<ListingType>, bool),
|
||||||
DoneFetchPosts(Vec<PostView>),
|
DoneFetchPosts(Vec<PostView>),
|
||||||
DoneFetchCommunities(Vec<CommunityView>),
|
DoneFetchCommunities(Vec<CommunityView>),
|
||||||
ViewCommunities(Option<String>, Option<ListingType>),
|
FetchCommunities(Option<ListingType>, bool),
|
||||||
OpenCommunity(String),
|
OpenCommunity(String),
|
||||||
DoneFetchCommunity(GetCommunityResponse),
|
DoneFetchCommunity(GetCommunityResponse),
|
||||||
OpenPerson(String),
|
OpenPerson(String),
|
||||||
|
@ -85,21 +88,21 @@ impl SimpleComponent for App {
|
||||||
},
|
},
|
||||||
pack_start = >k::Button {
|
pack_start = >k::Button {
|
||||||
set_label: "Home",
|
set_label: "Home",
|
||||||
connect_clicked => AppMsg::StartFetchPosts(None),
|
connect_clicked => AppMsg::StartFetchPosts(None, true),
|
||||||
},
|
},
|
||||||
pack_start = >k::Button {
|
pack_start = >k::Button {
|
||||||
set_label: "Communities",
|
set_label: "Communities",
|
||||||
connect_clicked => AppMsg::ViewCommunities(None, None),
|
connect_clicked => AppMsg::FetchCommunities(None, true),
|
||||||
},
|
},
|
||||||
pack_start = >k::Button {
|
pack_start = >k::Button {
|
||||||
set_label: "Recommended",
|
set_label: "Recommended",
|
||||||
connect_clicked => AppMsg::StartFetchPosts(Some(ListingType::Subscribed)),
|
connect_clicked => AppMsg::StartFetchPosts(Some(ListingType::Subscribed), true),
|
||||||
#[watch]
|
#[watch]
|
||||||
set_visible: model.logged_in,
|
set_visible: model.logged_in,
|
||||||
},
|
},
|
||||||
pack_start = >k::Button {
|
pack_start = >k::Button {
|
||||||
set_label: "Joined",
|
set_label: "Joined",
|
||||||
connect_clicked => AppMsg::ViewCommunities(None, Some(ListingType::Subscribed)),
|
connect_clicked => AppMsg::FetchCommunities(Some(ListingType::Subscribed), true),
|
||||||
#[watch]
|
#[watch]
|
||||||
set_visible: model.logged_in,
|
set_visible: model.logged_in,
|
||||||
},
|
},
|
||||||
|
@ -113,13 +116,22 @@ impl SimpleComponent for App {
|
||||||
|
|
||||||
match model.state {
|
match model.state {
|
||||||
AppState::Posts => gtk::ScrolledWindow {
|
AppState::Posts => gtk::ScrolledWindow {
|
||||||
set_vexpand: true,
|
|
||||||
set_hexpand: true,
|
set_hexpand: true,
|
||||||
|
|
||||||
#[local_ref]
|
gtk::Box {
|
||||||
posts_box -> gtk::Box {
|
|
||||||
set_orientation: gtk::Orientation::Vertical,
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
set_spacing: 5,
|
|
||||||
|
#[local_ref]
|
||||||
|
posts_box -> gtk::Box {
|
||||||
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
|
set_spacing: 5,
|
||||||
|
},
|
||||||
|
|
||||||
|
gtk::Button {
|
||||||
|
set_label: "More",
|
||||||
|
connect_clicked => AppMsg::StartFetchPosts(model.current_posts_type, false),
|
||||||
|
set_margin_all: 10,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
AppState::Loading => gtk::Box {
|
AppState::Loading => gtk::Box {
|
||||||
|
@ -186,7 +198,7 @@ impl SimpleComponent for App {
|
||||||
|
|
||||||
gtk::Button {
|
gtk::Button {
|
||||||
set_label: "Cancel",
|
set_label: "Cancel",
|
||||||
connect_clicked => AppMsg::StartFetchPosts(None),
|
connect_clicked => AppMsg::StartFetchPosts(None, true),
|
||||||
set_margin_end: 10,
|
set_margin_end: 10,
|
||||||
},
|
},
|
||||||
gtk::Button {
|
gtk::Button {
|
||||||
|
@ -213,7 +225,6 @@ impl SimpleComponent for App {
|
||||||
gtk::Box {
|
gtk::Box {
|
||||||
set_margin_all: 10,
|
set_margin_all: 10,
|
||||||
|
|
||||||
#[name(community_search_query)]
|
|
||||||
gtk::Entry {
|
gtk::Entry {
|
||||||
set_hexpand: true,
|
set_hexpand: true,
|
||||||
set_tooltip_text: Some("Search"),
|
set_tooltip_text: Some("Search"),
|
||||||
|
@ -221,10 +232,7 @@ impl SimpleComponent for App {
|
||||||
},
|
},
|
||||||
gtk::Button {
|
gtk::Button {
|
||||||
set_label: "Search",
|
set_label: "Search",
|
||||||
connect_clicked[sender, community_search_query] => move |_| {
|
connect_clicked => AppMsg::FetchCommunities(model.current_communities_type, true),
|
||||||
let text = community_search_query.text().as_str().to_string();
|
|
||||||
sender.input(AppMsg::ViewCommunities(Some(text), model.current_communities_type));
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -232,6 +240,12 @@ impl SimpleComponent for App {
|
||||||
communities_box -> gtk::Box {
|
communities_box -> gtk::Box {
|
||||||
set_orientation: gtk::Orientation::Vertical,
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
set_spacing: 5,
|
set_spacing: 5,
|
||||||
|
},
|
||||||
|
|
||||||
|
gtk::Button {
|
||||||
|
set_label: "More",
|
||||||
|
connect_clicked => AppMsg::FetchCommunities(model.current_communities_type, false),
|
||||||
|
set_margin_all: 10,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -305,11 +319,12 @@ impl SimpleComponent for App {
|
||||||
let community_page = CommunityPage::builder().launch(default_community().community_view).forward(sender.input_sender(), |msg| msg);
|
let community_page = CommunityPage::builder().launch(default_community().community_view).forward(sender.input_sender(), |msg| msg);
|
||||||
let post_page = PostPage::builder().launch(default_post()).forward(sender.input_sender(), |msg| msg);
|
let post_page = PostPage::builder().launch(default_post()).forward(sender.input_sender(), |msg| msg);
|
||||||
let inbox_page = InboxPage::builder().launch(()).forward(sender.input_sender(), |msg| msg);
|
let inbox_page = InboxPage::builder().launch(()).forward(sender.input_sender(), |msg| msg);
|
||||||
|
let community_search_buffer = gtk::EntryBuffer::builder().build();
|
||||||
let model = App { state, logged_in, posts, communities, profile_page, community_page, post_page, inbox_page, message: None, latest_action: None, current_communities_type: None, current_posts_type: None };
|
|
||||||
|
let model = App { state, logged_in, posts, communities, profile_page, community_page, post_page, inbox_page, message: None, latest_action: None, current_communities_type: None, current_posts_type: None, current_communities_page: 1, current_posts_page: 1, community_search_buffer };
|
||||||
|
|
||||||
// fetch posts if that's the initial page
|
// fetch posts if that's the initial page
|
||||||
if !current_account.instance_url.is_empty() { sender.input(AppMsg::StartFetchPosts(None)) };
|
if !current_account.instance_url.is_empty() { sender.input(AppMsg::StartFetchPosts(None, true)) };
|
||||||
|
|
||||||
// setup all widgets and different stack pages
|
// setup all widgets and different stack pages
|
||||||
let posts_box = model.posts.widget();
|
let posts_box = model.posts.widget();
|
||||||
|
@ -357,15 +372,17 @@ impl SimpleComponent for App {
|
||||||
current_account.instance_url = instance_url;
|
current_account.instance_url = instance_url;
|
||||||
settings::update_current_account(current_account);
|
settings::update_current_account(current_account);
|
||||||
self.state = AppState::Loading;
|
self.state = AppState::Loading;
|
||||||
sender.input(AppMsg::StartFetchPosts(None));
|
sender.input(AppMsg::StartFetchPosts(None, true));
|
||||||
}
|
}
|
||||||
AppMsg::ChooseInstance => {
|
AppMsg::ChooseInstance => {
|
||||||
self.state = AppState::ChooseInstance;
|
self.state = AppState::ChooseInstance;
|
||||||
}
|
}
|
||||||
AppMsg::StartFetchPosts(type_) => {
|
AppMsg::StartFetchPosts(type_, remove_previous) => {
|
||||||
self.current_posts_type = type_;
|
self.current_posts_type = type_;
|
||||||
|
let page = if remove_previous { 1 } else { self.current_posts_page + 1 };
|
||||||
|
self.current_posts_page = page;
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
let message = match api::posts::list_posts(1, None, type_) {
|
let message = match api::posts::list_posts(page, None, type_) {
|
||||||
Ok(posts) => AppMsg::DoneFetchPosts(posts),
|
Ok(posts) => AppMsg::DoneFetchPosts(posts),
|
||||||
Err(err) => AppMsg::ShowMessage(err.to_string())
|
Err(err) => AppMsg::ShowMessage(err.to_string())
|
||||||
};
|
};
|
||||||
|
@ -374,16 +391,20 @@ impl SimpleComponent for App {
|
||||||
}
|
}
|
||||||
AppMsg::DoneFetchPosts(posts) => {
|
AppMsg::DoneFetchPosts(posts) => {
|
||||||
self.state = AppState::Posts;
|
self.state = AppState::Posts;
|
||||||
self.posts.guard().clear();
|
if self.current_posts_page == 1 { self.posts.guard().clear(); }
|
||||||
for post in posts {
|
for post in posts {
|
||||||
self.posts.guard().push_back(post);
|
self.posts.guard().push_back(post);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AppMsg::ViewCommunities(query, listing_type) => {
|
AppMsg::FetchCommunities(listing_type, remove_previous) => {
|
||||||
|
let query_text = self.community_search_buffer.text().as_str().to_owned();
|
||||||
|
let query = if query_text.is_empty() { None } else { Some(query_text) };
|
||||||
self.state = AppState::Communities;
|
self.state = AppState::Communities;
|
||||||
|
let page = if remove_previous { 1 } else { self.current_communities_page + 1 };
|
||||||
|
self.current_communities_page = page;
|
||||||
self.current_communities_type = listing_type;
|
self.current_communities_type = listing_type;
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
let message = match api::communities::fetch_communities(1, query, listing_type) {
|
let message = match api::communities::fetch_communities(page, query, listing_type) {
|
||||||
Ok(communities) => AppMsg::DoneFetchCommunities(communities),
|
Ok(communities) => AppMsg::DoneFetchCommunities(communities),
|
||||||
Err(err) => AppMsg::ShowMessage(err.to_string())
|
Err(err) => AppMsg::ShowMessage(err.to_string())
|
||||||
};
|
};
|
||||||
|
@ -392,7 +413,7 @@ impl SimpleComponent for App {
|
||||||
}
|
}
|
||||||
AppMsg::DoneFetchCommunities(communities) => {
|
AppMsg::DoneFetchCommunities(communities) => {
|
||||||
self.state = AppState::Communities;
|
self.state = AppState::Communities;
|
||||||
self.communities.guard().clear();
|
if self.current_communities_page == 1 { self.communities.guard().clear(); }
|
||||||
for community in communities {
|
for community in communities {
|
||||||
self.communities.guard().push_back(community);
|
self.communities.guard().push_back(community);
|
||||||
}
|
}
|
||||||
|
@ -479,14 +500,14 @@ impl SimpleComponent for App {
|
||||||
self.state = AppState::Message;
|
self.state = AppState::Message;
|
||||||
}
|
}
|
||||||
AppMsg::Retry => {
|
AppMsg::Retry => {
|
||||||
sender.input(self.latest_action.clone().unwrap_or(AppMsg::StartFetchPosts(None)));
|
sender.input(self.latest_action.clone().unwrap_or(AppMsg::StartFetchPosts(None, true)));
|
||||||
}
|
}
|
||||||
AppMsg::OpenInbox => {
|
AppMsg::OpenInbox => {
|
||||||
self.state = AppState::Inbox;
|
self.state = AppState::Inbox;
|
||||||
}
|
}
|
||||||
AppMsg::LoggedIn => {
|
AppMsg::LoggedIn => {
|
||||||
self.logged_in = true;
|
self.logged_in = true;
|
||||||
sender.input(AppMsg::StartFetchPosts(None));
|
sender.input(AppMsg::StartFetchPosts(None, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue