Support for deleting posts and comments

This commit is contained in:
Bnyro 2023-06-21 14:27:12 +02:00
parent 9748dc291e
commit e238beb3cf
15 changed files with 162 additions and 51 deletions

View File

@ -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", &params)
@ -23,7 +23,16 @@ pub fn like_comment(comment_id: CommentId, score: i16) -> Result<CommentResponse
let params = CreateCommentLike {
comment_id,
score,
auth: util::get_auth_token().unwrap(),
auth: settings::get_current_account().jwt.unwrap(),
};
super::post("/comment/like", &params)
}
pub fn delete_comment(comment_id: CommentId) -> Result<CommentResponse, reqwest::Error> {
let params = DeleteComment {
comment_id,
deleted: true,
auth: settings::get_current_account().jwt.unwrap(),
};
super::post("/comment/delete", &params)
}

View File

@ -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<String>) -> std::result::Result<Vec<CommunityView>, reqwest::Error> {
@ -9,7 +8,7 @@ pub fn fetch_communities(page: i64, query: Option<String>) -> 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()
};

View File

@ -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<GetCommunityResponse, reqwest::Error> {
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", &params)
}

View File

@ -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<Client> = 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 {

View File

@ -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<GetPostResponse, reqwest::Error> {
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<Vec<CommentView>, 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", &params)
@ -53,7 +53,16 @@ pub fn like_post(post_id: PostId, score: i16) -> Result<PostResponse, reqwest::E
let params = CreatePostLike {
post_id,
score,
auth: util::get_auth_token().unwrap(),
auth: settings::get_current_account().jwt.unwrap(),
};
super::post("/post/like", &params)
}
pub fn delete_post(post_id: PostId) -> Result<PostResponse, reqwest::Error> {
let params = DeletePost {
post_id,
deleted: true,
auth: settings::get_current_account().jwt.unwrap(),
};
super::post("/post/delete", &params)
}

View File

@ -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<String>, listing_type: Option<ListingType>) -> std::result::Result<Vec<PostView>, 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()
};

View File

@ -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<SearchType>) -> std::result::Result<SearchResponse, reqwest::Error> {
let params = Search {
@ -8,7 +8,7 @@ pub fn fetch_search(page: i64, query: String, search_type: Option<SearchType>) -
sort: Some(SortType::TopMonth),
page: Some(page),
type_: search_type,
auth: util::get_auth_token(),
auth: settings::get_current_account().jwt,
..Default::default()
};

10
src/api/site.rs Normal file
View File

@ -0,0 +1,10 @@
use lemmy_api_common::site::{GetSiteResponse, GetSite};
use crate::settings;
pub fn fetch_site() -> std::result::Result<GetSiteResponse, reqwest::Error> {
let params = GetSite {
auth: settings::get_current_account().jwt,
};
super::get("/site", &params)
}

View File

@ -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<GetPersonDetailsResponse, reqwest::Error> {
let params = GetPersonDetails {
page: Some(page),
username: Some(username),
auth: util::get_auth_token(),
auth: settings::get_current_account().jwt,
..Default::default()
};

View File

@ -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));
});
}
}
}
}

View File

@ -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 => {
}
}
}
}

View File

@ -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));
});
}
}
}
}

View File

@ -265,7 +265,7 @@ impl SimpleComponent for App {
root: &Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
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);

View File

@ -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<Sensitive<String>>,
pub id: i32,
pub name: String,
}
#[derive(Deserialize, Serialize, Default)]
pub struct Preferences {
pub instance_url: String,
pub jwt: Option<Sensitive<String>>
pub accounts: Vec<Account>,
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);
}

View File

@ -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<DbUrl>) -> WebImageMsg {
return if let Some(url) = url {
WebImageMsg::LoadImage(url.to_string())
@ -18,13 +16,3 @@ pub fn get_web_image_url(url: Option<DbUrl>) -> 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<Sensitive<String>>) {
let mut settings = settings::get_prefs();
settings.jwt = token.clone();
settings::save_prefs(&settings);
}
pub fn get_auth_token() -> Option<Sensitive<String>> {
settings::get_prefs().jwt
}