From e238beb3cf0c82048ec353526528332ce2d1c481 Mon Sep 17 00:00:00 2001 From: Bnyro Date: Wed, 21 Jun 2023 14:27:12 +0200 Subject: [PATCH] Support for deleting posts and comments --- src/api/comment.rs | 17 +++++++++++++---- src/api/communities.rs | 5 ++--- src/api/community.rs | 6 +++--- src/api/mod.rs | 5 +++-- src/api/post.rs | 21 +++++++++++++++------ src/api/posts.rs | 4 ++-- src/api/search.rs | 4 ++-- src/api/site.rs | 10 ++++++++++ src/api/user.rs | 4 ++-- src/components/comment_row.rs | 27 +++++++++++++++++++++++++-- src/components/post_page.rs | 26 ++++++++++++++++++++++++-- src/components/post_row.rs | 22 ++++++++++++++++++++-- src/main.rs | 21 +++++++++++++++------ src/settings.rs | 27 +++++++++++++++++++++++++-- src/util.rs | 14 +------------- 15 files changed, 162 insertions(+), 51 deletions(-) create mode 100644 src/api/site.rs diff --git a/src/api/comment.rs b/src/api/comment.rs index af84502..008fa0b 100644 --- a/src/api/comment.rs +++ b/src/api/comment.rs @@ -1,6 +1,6 @@ -use lemmy_api_common::{comment::{CommentResponse, CreateComment, CreateCommentLike}, lemmy_db_schema::newtypes::{PostId, CommentId}}; +use lemmy_api_common::{comment::{CommentResponse, CreateComment, CreateCommentLike, DeleteComment}, lemmy_db_schema::newtypes::{PostId, CommentId}}; -use crate::util; +use crate::settings; pub fn create_comment( @@ -12,7 +12,7 @@ pub fn create_comment( post_id: PostId(post_id), content, parent_id: parent_id.map(CommentId), - auth: util::get_auth_token().unwrap(), + auth: settings::get_current_account().jwt.unwrap(), ..Default::default() }; super::post("/comment", ¶ms) @@ -23,7 +23,16 @@ pub fn like_comment(comment_id: CommentId, score: i16) -> Result Result { + let params = DeleteComment { + comment_id, + deleted: true, + auth: settings::get_current_account().jwt.unwrap(), + }; + super::post("/comment/delete", ¶ms) +} diff --git a/src/api/communities.rs b/src/api/communities.rs index f5f3e94..75b31ee 100644 --- a/src/api/communities.rs +++ b/src/api/communities.rs @@ -1,7 +1,6 @@ use lemmy_api_common::{community::{ListCommunities, ListCommunitiesResponse}, lemmy_db_schema::{SortType, SearchType}, lemmy_db_views_actor::structs::CommunityView}; -use crate::util; - +use crate::settings; use super::search; pub fn fetch_communities(page: i64, query: Option) -> std::result::Result, reqwest::Error> { @@ -9,7 +8,7 @@ pub fn fetch_communities(page: i64, query: Option) -> std::result::Resul let params = ListCommunities { sort: Some(SortType::TopMonth), page: Some(page), - auth: util::get_auth_token(), + auth: settings::get_current_account().jwt, ..Default::default() }; diff --git a/src/api/community.rs b/src/api/community.rs index bd422a3..9a1074a 100644 --- a/src/api/community.rs +++ b/src/api/community.rs @@ -1,11 +1,11 @@ use lemmy_api_common::{community::{GetCommunity, GetCommunityResponse, CommunityResponse, FollowCommunity}, lemmy_db_schema::newtypes::CommunityId}; -use crate::util; +use crate::settings; pub fn get_community(name: String) -> std::result::Result { let params = GetCommunity { name: Some(name), - auth: util::get_auth_token(), + auth: settings::get_current_account().jwt, ..Default::default() }; @@ -19,7 +19,7 @@ pub fn follow_community( let params = FollowCommunity { community_id: CommunityId(community_id), follow, - auth: util::get_auth_token().unwrap(), + auth: settings::get_current_account().jwt.unwrap(), }; super::post("/community/follow", ¶ms) } diff --git a/src/api/mod.rs b/src/api/mod.rs index efac2ea..4810a93 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -1,6 +1,6 @@ use serde::{de::DeserializeOwned, Serialize}; -use crate::settings::get_prefs; +use crate::settings::get_current_account; pub mod communities; pub mod community; @@ -11,6 +11,7 @@ pub mod user; pub mod auth; pub mod moderation; pub mod comment; +pub mod site; static API_VERSION: &str = "v3"; @@ -22,7 +23,7 @@ pub static CLIENT: Lazy = Lazy::new(|| { }); fn get_api_url() -> String { - format!("{}/api/{}", get_prefs().instance_url, API_VERSION).to_string() + format!("{}/api/{}", get_current_account().instance_url, API_VERSION).to_string() } fn get_url(path: &str) -> String { diff --git a/src/api/post.rs b/src/api/post.rs index a227e3f..00d98df 100644 --- a/src/api/post.rs +++ b/src/api/post.rs @@ -1,11 +1,11 @@ -use lemmy_api_common::{post::{GetPost, GetPostResponse, PostResponse, CreatePost, CreatePostLike}, lemmy_db_schema::{newtypes::{PostId, CommunityId}, CommentSortType, ListingType}, comment::{GetComments, GetCommentsResponse}, lemmy_db_views::structs::CommentView}; +use lemmy_api_common::{post::{GetPost, GetPostResponse, PostResponse, CreatePost, CreatePostLike, DeletePost}, lemmy_db_schema::{newtypes::{PostId, CommunityId}, CommentSortType, ListingType}, comment::{GetComments, GetCommentsResponse}, lemmy_db_views::structs::CommentView}; -use crate::util; +use crate::settings; pub fn get_post(id: PostId) -> Result { let params = GetPost { id: Some(id), - auth: util::get_auth_token(), + auth: settings::get_current_account().jwt, ..Default::default() }; @@ -17,7 +17,7 @@ pub fn get_comments(post_id: PostId) -> Result, reqwest::Error> post_id: Some(post_id), sort: Some(CommentSortType::Hot), type_: Some(ListingType::All), - auth: util::get_auth_token(), + auth: settings::get_current_account().jwt, ..Default::default() }; @@ -42,7 +42,7 @@ pub fn create_post( name, body: Some(body), community_id: CommunityId(community_id), - auth: util::get_auth_token().unwrap(), + auth: settings::get_current_account().jwt.unwrap(), ..Default::default() }; super::post("/post", ¶ms) @@ -53,7 +53,16 @@ pub fn like_post(post_id: PostId, score: i16) -> Result Result { + let params = DeletePost { + post_id, + deleted: true, + auth: settings::get_current_account().jwt.unwrap(), + }; + super::post("/post/delete", ¶ms) +} diff --git a/src/api/posts.rs b/src/api/posts.rs index 3e4bed8..b53dfb2 100644 --- a/src/api/posts.rs +++ b/src/api/posts.rs @@ -1,13 +1,13 @@ use lemmy_api_common::{post::{GetPostsResponse, GetPosts}, lemmy_db_views::structs::PostView, lemmy_db_schema::ListingType}; -use crate::util; +use crate::settings; pub fn list_posts(page: i64, community_name: Option, listing_type: Option) -> std::result::Result, reqwest::Error> { let params = GetPosts { page: Some(page), type_: listing_type, community_name, - auth: util::get_auth_token(), + auth: settings::get_current_account().jwt, ..Default::default() }; diff --git a/src/api/search.rs b/src/api/search.rs index d64c50d..0a0da55 100644 --- a/src/api/search.rs +++ b/src/api/search.rs @@ -1,6 +1,6 @@ use lemmy_api_common::{site::{SearchResponse, Search}, lemmy_db_schema::{SortType, SearchType}}; -use crate::util; +use crate::settings; pub fn fetch_search(page: i64, query: String, search_type: Option) -> std::result::Result { let params = Search { @@ -8,7 +8,7 @@ pub fn fetch_search(page: i64, query: String, search_type: Option) - sort: Some(SortType::TopMonth), page: Some(page), type_: search_type, - auth: util::get_auth_token(), + auth: settings::get_current_account().jwt, ..Default::default() }; diff --git a/src/api/site.rs b/src/api/site.rs new file mode 100644 index 0000000..7f13d0d --- /dev/null +++ b/src/api/site.rs @@ -0,0 +1,10 @@ +use lemmy_api_common::site::{GetSiteResponse, GetSite}; + +use crate::settings; + +pub fn fetch_site() -> std::result::Result { + let params = GetSite { + auth: settings::get_current_account().jwt, + }; + super::get("/site", ¶ms) +} diff --git a/src/api/user.rs b/src/api/user.rs index 884d13e..59f86f3 100644 --- a/src/api/user.rs +++ b/src/api/user.rs @@ -1,12 +1,12 @@ use lemmy_api_common::{person::{GetPersonDetailsResponse, GetPersonDetails}}; -use crate::util; +use crate::settings; pub fn get_user(username: String, page: i64) -> std::result::Result { let params = GetPersonDetails { page: Some(page), username: Some(username), - auth: util::get_auth_token(), + auth: settings::get_current_account().jwt, ..Default::default() }; diff --git a/src/components/comment_row.rs b/src/components/comment_row.rs index b6933b7..c967e76 100644 --- a/src/components/comment_row.rs +++ b/src/components/comment_row.rs @@ -3,8 +3,10 @@ use relm4::prelude::*; use gtk::prelude::*; use relm4_components::web_image::WebImage; +use crate::api; use crate::util::get_web_image_url; use crate::util::markdown_to_pango_markup; +use crate::settings; use super::voting_row::VotingRowModel; use super::voting_row::VotingStats; @@ -19,6 +21,7 @@ pub struct CommentRow { #[derive(Debug)] pub enum CommentRowMsg { OpenPerson, + DeleteComment, } #[relm4::factory(pub)] @@ -66,8 +69,21 @@ impl FactoryComponent for CommentRow { set_use_markup: true, }, - #[local_ref] - voting_row -> gtk::Box {}, + gtk::Box { + set_orientation: gtk::Orientation::Vertical, + #[local_ref] + voting_row -> gtk::Box {}, + + if self.comment.creator.id.0 == settings::get_current_account().id { + gtk::Button { + set_icon_name: "edit-delete", + connect_clicked => CommentRowMsg::DeleteComment, + set_margin_start: 10, + } + } else { + gtk::Box {} + } + }, gtk::Separator {} } @@ -102,6 +118,13 @@ impl FactoryComponent for CommentRow { CommentRowMsg::OpenPerson => { sender.output(crate::AppMsg::OpenPerson(self.comment.creator.name.clone())) } + CommentRowMsg::DeleteComment => { + let comment_id = self.comment.comment.id; + std::thread::spawn(move || { + let _ = api::comment::delete_comment(comment_id); + let _ = sender.output(crate::AppMsg::StartFetchPosts(None)); + }); + } } } } \ No newline at end of file diff --git a/src/components/post_page.rs b/src/components/post_page.rs index 009f947..d1033d1 100644 --- a/src/components/post_page.rs +++ b/src/components/post_page.rs @@ -3,7 +3,7 @@ use relm4::{prelude::*, factory::FactoryVecDeque}; use gtk::prelude::*; use relm4_components::web_image::WebImage; -use crate::{api, util::{get_web_image_msg, get_web_image_url, markdown_to_pango_markup}, dialogs::create_post::{CreatePostDialog, CreatePostDialogOutput, DialogMsg, CREATE_COMMENT_DIALOG_BROKER, DialogType}}; +use crate::{api, util::{get_web_image_msg, get_web_image_url, markdown_to_pango_markup}, dialogs::create_post::{CreatePostDialog, CreatePostDialogOutput, DialogMsg, CREATE_COMMENT_DIALOG_BROKER, DialogType}, settings}; use super::{comment_row::CommentRow, voting_row::{VotingRowModel, VotingStats, VotingRowInput}}; @@ -27,7 +27,9 @@ pub enum PostInput { OpenLink, OpenCreateCommentDialog, CreateCommentRequest(String), - CreatedComment(CommentView) + CreatedComment(CommentView), + DeletePost, + EditPost, } #[relm4::component(pub)] @@ -114,6 +116,16 @@ impl SimpleComponent for PostPage { gtk::Button { set_label: "View", connect_clicked => PostInput::OpenLink, + }, + + if model.info.post_view.creator.id.0 == settings::get_current_account().id { + gtk::Button { + set_icon_name: "edit-delete", + connect_clicked => PostInput::DeletePost, + set_margin_start: 10, + } + } else { + gtk::Box {} } }, @@ -237,6 +249,16 @@ impl SimpleComponent for PostPage { if message.is_some() { sender.input(message.unwrap()) }; }); } + PostInput::DeletePost => { + let post_id = self.info.post_view.post.id; + std::thread::spawn(move || { + let _ = api::post::delete_post(post_id); + let _ = sender.output(crate::AppMsg::StartFetchPosts(None)); + }); + } + PostInput::EditPost => { + + } } } } diff --git a/src/components/post_row.rs b/src/components/post_row.rs index be07922..4941c0f 100644 --- a/src/components/post_row.rs +++ b/src/components/post_row.rs @@ -3,7 +3,8 @@ use relm4::prelude::*; use gtk::prelude::*; use relm4_components::web_image::WebImage; -use crate::util::get_web_image_url; +use crate::{util::get_web_image_url, api}; +use crate::settings; use super::voting_row::{VotingRowModel, VotingStats}; @@ -19,7 +20,8 @@ pub struct PostRow { pub enum PostViewMsg { OpenPost, OpenCommunity, - OpenPerson + OpenPerson, + DeletePost } #[relm4::factory(pub)] @@ -104,6 +106,15 @@ impl FactoryComponent for PostRow { set_halign: gtk::Align::Start, set_text: &format!("{} comments", self.post.clone().counts.comments), }, + if self.post.creator.id.0 == settings::get_current_account().id { + gtk::Button { + set_icon_name: "edit-delete", + connect_clicked => PostViewMsg::DeletePost, + set_margin_start: 10, + } + } else { + gtk::Box {} + } }, gtk::Separator { @@ -147,6 +158,13 @@ impl FactoryComponent for PostRow { PostViewMsg::OpenPost => { sender.output(crate::AppMsg::OpenPost(self.post.post.id.clone())) } + PostViewMsg::DeletePost => { + let post_id = self.post.post.id; + std::thread::spawn(move || { + let _ = api::post::delete_post(post_id); + let _ = sender.output(crate::AppMsg::StartFetchPosts(None)); + }); + } } } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 9c08e94..9e1efc6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -265,7 +265,7 @@ impl SimpleComponent for App { root: &Self::Root, sender: ComponentSender, ) -> ComponentParts { - let instance_url = settings::get_prefs().instance_url; + let instance_url = settings::get_current_account().instance_url; let state = if instance_url.is_empty() { AppState::ChooseInstance } else { AppState::Loading }; // initialize all controllers and factories @@ -315,9 +315,9 @@ impl SimpleComponent for App { match msg { AppMsg::DoneChoosingInstance(instance_url) => { if instance_url.trim().is_empty() { return; } - let mut preferences = settings::get_prefs(); - preferences.instance_url = instance_url; - settings::save_prefs(&preferences); + let mut current_account = settings::get_current_account(); + current_account.instance_url = instance_url; + settings::update_current_account(current_account); self.state = AppState::Loading; sender.input(AppMsg::StartFetchPosts(None)); } @@ -409,7 +409,14 @@ impl SimpleComponent for App { let message = match api::auth::login(username, password) { Ok(login) => { if let Some(token) = login.jwt { - util::set_auth_token(Some(token)); + let mut account = settings::get_current_account(); + account.jwt = Some(token); + settings::update_current_account(account.clone()); + if let Ok(site) = api::site::fetch_site() { + let user = site.my_user.unwrap().local_user_view.person; + account.name = user.name; + account.id = user.id.0; + } AppMsg::StartFetchPosts(None) } else { AppMsg::ShowMessage("Wrong credentials!".to_string()) @@ -421,7 +428,9 @@ impl SimpleComponent for App { }); } AppMsg::Logout => { - util::set_auth_token(None); + let mut account = settings::get_current_account(); + account.jwt = None; + settings::update_current_account(account); } AppMsg::ShowMessage(message) => { self.message = Some(message); diff --git a/src/settings.rs b/src/settings.rs index 24dda7e..12f023b 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -4,10 +4,18 @@ use lemmy_api_common::sensitive::Sensitive; use serde::{Deserialize, Serialize}; use crate::APP_ID; +#[derive(Deserialize, Serialize, Default, Clone)] +pub struct Account { + pub instance_url: String, + pub jwt: Option>, + pub id: i32, + pub name: String, +} + #[derive(Deserialize, Serialize, Default)] pub struct Preferences { - pub instance_url: String, - pub jwt: Option> + pub accounts: Vec, + pub current_account_index: u32 } pub fn data_path() -> PathBuf { @@ -33,3 +41,18 @@ pub fn get_prefs() -> Preferences { } return Preferences::default(); } + +pub fn get_current_account() -> Account { + let mut prefs = get_prefs(); + if prefs.accounts.len() == 0 { + prefs.accounts.push(Account::default()); + save_prefs(&prefs); + } + prefs.accounts[prefs.current_account_index as usize].clone() +} + +pub fn update_current_account(account: Account) { + let mut settings = get_prefs(); + settings.accounts[settings.current_account_index as usize] = account; + save_prefs(&settings); +} diff --git a/src/util.rs b/src/util.rs index d1abf99..9802177 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,8 +1,6 @@ -use lemmy_api_common::{lemmy_db_schema::newtypes::DbUrl, sensitive::Sensitive}; +use lemmy_api_common::lemmy_db_schema::newtypes::DbUrl; use relm4_components::web_image::WebImageMsg; -use crate::settings; - pub fn get_web_image_msg(url: Option) -> WebImageMsg { return if let Some(url) = url { WebImageMsg::LoadImage(url.to_string()) @@ -18,13 +16,3 @@ pub fn get_web_image_url(url: Option) -> String { pub fn markdown_to_pango_markup(text: String) -> String { return html2pango::markup_html(&markdown::to_html(&text)).unwrap_or(text) } - -pub fn set_auth_token(token: Option>) { - let mut settings = settings::get_prefs(); - settings.jwt = token.clone(); - settings::save_prefs(&settings); -} - -pub fn get_auth_token() -> Option> { - settings::get_prefs().jwt -}