Show communities moderated by a person

This commit is contained in:
Bnyro 2023-07-02 19:09:12 +02:00
parent 9dfa5cfea6
commit 5e353c27cb
10 changed files with 141 additions and 38 deletions

16
.vscode/settings.json vendored
View File

@ -1,16 +0,0 @@
{
"C_Cpp.default.compileCommands": "_build/vscode_compile_commands.json",
"files.watcherExclude": {
"**/.dart_tool": true,
".flatpak/**": true,
"_build/**": true
},
"mesonbuild.configureOnOpen": false,
"mesonbuild.buildFolder": "_build",
"mesonbuild.mesonPath": "${workspaceFolder}/.flatpak/meson.sh",
"rust-analyzer.server.path": "${workspaceFolder}/.flatpak/rust-analyzer.sh",
"rust-analyzer.runnables.command": "${workspaceFolder}/.flatpak/cargo.sh",
"rust-analyzer.files.excludeDirs": [
".flatpak"
]
}

View File

@ -40,7 +40,6 @@ impl FactoryComponent for CommentRow {
type Input = CommentRowMsg; type Input = CommentRowMsg;
type Output = crate::AppMsg; type Output = crate::AppMsg;
type CommandOutput = (); type CommandOutput = ();
type Widgets = PostViewWidgets;
type ParentInput = crate::AppMsg; type ParentInput = crate::AppMsg;
type ParentWidget = gtk::Box; type ParentWidget = gtk::Box;
@ -176,7 +175,9 @@ 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);
sender.output_sender().emit(crate::AppMsg::StartFetchPosts(None, true)); sender
.output_sender()
.emit(crate::AppMsg::StartFetchPosts(None, true));
}); });
} }
CommentRowMsg::OpenEditor(is_new) => { CommentRowMsg::OpenEditor(is_new) => {
@ -216,8 +217,7 @@ impl FactoryComponent for CommentRow {
let post_id = self.comment.comment.post_id; let post_id = self.comment.comment.post_id;
let parent_id = self.comment.comment.id; let parent_id = self.comment.comment.id;
std::thread::spawn(move || { std::thread::spawn(move || {
match api::comment::create_comment(post_id, data.body, Some(parent_id)) match api::comment::create_comment(post_id, data.body, Some(parent_id)) {
{
Ok(_comment) => { Ok(_comment) => {
// TODO sender.output_sender().emit(PostPageInput::CreatedComment(comment.comment_view)); // TODO sender.output_sender().emit(PostPageInput::CreatedComment(comment.comment_view));
} }

View File

@ -22,7 +22,6 @@ impl FactoryComponent for CommunityRow {
type Input = CommunityRowMsg; type Input = CommunityRowMsg;
type Output = crate::AppMsg; type Output = crate::AppMsg;
type CommandOutput = (); type CommandOutput = ();
type Widgets = PostViewWidgets;
type ParentInput = crate::AppMsg; type ParentInput = crate::AppMsg;
type ParentWidget = gtk::Box; type ParentWidget = gtk::Box;

View File

@ -20,7 +20,6 @@ impl FactoryComponent for InstanceRow {
type Input = InstanceRowMsg; type Input = InstanceRowMsg;
type Output = InstancesPageInput; type Output = InstancesPageInput;
type CommandOutput = (); type CommandOutput = ();
type Widgets = PostViewWidgets;
type ParentInput = InstancesPageInput; type ParentInput = InstancesPageInput;
type ParentWidget = gtk::Box; type ParentWidget = gtk::Box;

View File

@ -31,7 +31,6 @@ impl FactoryComponent for MentionRow {
type Input = MentionRowMsg; type Input = MentionRowMsg;
type Output = crate::AppMsg; type Output = crate::AppMsg;
type CommandOutput = (); type CommandOutput = ();
type Widgets = MentionRowWidgets;
type ParentInput = crate::AppMsg; type ParentInput = crate::AppMsg;
type ParentWidget = gtk::Box; type ParentWidget = gtk::Box;

View File

@ -7,6 +7,7 @@ pub mod instance_row;
pub mod instances_page; pub mod instances_page;
pub mod login_page; pub mod login_page;
pub mod mention_row; pub mod mention_row;
pub mod moderates_row;
pub mod post_page; pub mod post_page;
pub mod post_row; pub mod post_row;
pub mod private_message_row; pub mod private_message_row;

View File

@ -0,0 +1,116 @@
use gtk::prelude::*;
use lemmy_api_common::lemmy_db_views_actor::structs::CommunityModeratorView;
use relm4::prelude::*;
use relm4_components::web_image::WebImage;
use crate::util::get_web_image_url;
#[derive(Debug)]
pub struct ModeratesRow {
community: CommunityModeratorView,
community_image: Controller<WebImage>,
}
#[derive(Debug)]
pub enum ModeratesRowMsg {
OpenCommunity,
}
#[relm4::factory(pub)]
impl FactoryComponent for ModeratesRow {
type Init = CommunityModeratorView;
type Input = ModeratesRowMsg;
type Output = crate::AppMsg;
type CommandOutput = ();
type ParentInput = crate::AppMsg;
type ParentWidget = gtk::Box;
view! {
root = gtk::Box {
set_orientation: gtk::Orientation::Vertical,
set_spacing: 10,
set_margin_end: 10,
set_margin_start: 10,
set_vexpand: false,
add_controller = gtk::GestureClick {
connect_pressed[sender] => move |_, _, _, _| {
sender.input(ModeratesRowMsg::OpenCommunity);
}
},
gtk::Box {
set_orientation: gtk::Orientation::Horizontal,
set_spacing: 10,
if self.community.community.icon.is_some() {
gtk::Box {
set_hexpand: false,
#[local_ref]
community_image -> gtk::Box {
set_height_request: 35,
set_width_request: 35,
}
}
} else {
gtk::Box {}
},
gtk::Label {
set_label: &self.community.community.title,
},
gtk::Box {
set_hexpand: true,
},
gtk::Label {
set_label: "NSFW",
set_visible: self.community.community.nsfw,
}
},
gtk::Label {
set_label: &self.community.community.description.clone().unwrap_or("".to_string()),
set_halign: gtk::Align::Start,
},
gtk::Separator {}
}
}
fn forward_to_parent(output: Self::Output) -> Option<Self::ParentInput> {
Some(output)
}
fn init_model(value: Self::Init, _index: &DynamicIndex, _sender: FactorySender<Self>) -> Self {
let community_image = WebImage::builder()
.launch(get_web_image_url(value.community.clone().icon))
.detach();
Self {
community: value,
community_image,
}
}
fn init_widgets(
&mut self,
_index: &Self::Index,
root: &Self::Root,
_returned_widget: &<Self::ParentWidget as relm4::factory::FactoryView>::ReturnedWidget,
sender: FactorySender<Self>,
) -> Self::Widgets {
let community_image = self.community_image.widget();
let widgets = view_output!();
widgets
}
fn update(&mut self, message: Self::Input, sender: FactorySender<Self>) {
match message {
ModeratesRowMsg::OpenCommunity => sender.output(crate::AppMsg::OpenCommunity(
self.community.community.id.clone(),
)),
}
}
}

View File

@ -30,7 +30,6 @@ impl FactoryComponent for PostRow {
type Input = PostRowMsg; type Input = PostRowMsg;
type Output = crate::AppMsg; type Output = crate::AppMsg;
type CommandOutput = (); type CommandOutput = ();
type Widgets = PostViewWidgets;
type ParentInput = crate::AppMsg; type ParentInput = crate::AppMsg;
type ParentWidget = gtk::Box; type ParentWidget = gtk::Box;

View File

@ -22,7 +22,6 @@ impl FactoryComponent for PrivateMessageRow {
type Input = PrivateMessageRowInput; type Input = PrivateMessageRowInput;
type Output = crate::AppMsg; type Output = crate::AppMsg;
type CommandOutput = (); type CommandOutput = ();
type Widgets = PrivateMessageRowWidgets;
type ParentInput = crate::AppMsg; type ParentInput = crate::AppMsg;
type ParentWidget = gtk::Box; type ParentWidget = gtk::Box;

View File

@ -1,5 +1,5 @@
use gtk::prelude::*; use gtk::prelude::*;
use lemmy_api_common::{person::GetPersonDetailsResponse, lemmy_db_schema::newtypes::PersonId}; use lemmy_api_common::{lemmy_db_schema::newtypes::PersonId, person::GetPersonDetailsResponse};
use relm4::{factory::FactoryVecDeque, prelude::*}; use relm4::{factory::FactoryVecDeque, prelude::*};
use relm4_components::web_image::WebImage; use relm4_components::web_image::WebImage;
@ -12,16 +12,16 @@ use crate::settings;
use crate::util::get_web_image_msg; use crate::util::get_web_image_msg;
use crate::util::markdown_to_pango_markup; use crate::util::markdown_to_pango_markup;
use super::post_row::PostRow;
use super::community_row::CommunityRow;
use super::comment_row::CommentRow; use super::comment_row::CommentRow;
use super::moderates_row::ModeratesRow;
use super::post_row::PostRow;
pub struct ProfilePage { pub struct ProfilePage {
info: GetPersonDetailsResponse, info: GetPersonDetailsResponse,
avatar: Controller<WebImage>, avatar: Controller<WebImage>,
posts: FactoryVecDeque<PostRow>, posts: FactoryVecDeque<PostRow>,
comments: FactoryVecDeque<CommentRow>, comments: FactoryVecDeque<CommentRow>,
communities: FactoryVecDeque<CommunityRow>, moderates: FactoryVecDeque<ModeratesRow>,
editor_dialog: Controller<EditorDialog>, editor_dialog: Controller<EditorDialog>,
current_profile_page: i64, current_profile_page: i64,
} }
@ -112,7 +112,7 @@ impl SimpleComponent for ProfilePage {
}, },
add_child = &gtk::Box { add_child = &gtk::Box {
#[local_ref] #[local_ref]
communities -> gtk::Box { moderates -> gtk::Box {
set_orientation: gtk::Orientation::Vertical, set_orientation: gtk::Orientation::Vertical,
} }
} -> { } -> {
@ -137,7 +137,7 @@ impl SimpleComponent for ProfilePage {
) -> relm4::ComponentParts<Self> { ) -> relm4::ComponentParts<Self> {
let avatar = WebImage::builder().launch("".to_string()).detach(); let avatar = WebImage::builder().launch("".to_string()).detach();
let posts = FactoryVecDeque::new(gtk::Box::default(), sender.output_sender()); let posts = FactoryVecDeque::new(gtk::Box::default(), sender.output_sender());
let communities = FactoryVecDeque::new(gtk::Box::default(), sender.output_sender()); let moderates = FactoryVecDeque::new(gtk::Box::default(), sender.output_sender());
let comments = FactoryVecDeque::new(gtk::Box::default(), sender.output_sender()); let comments = FactoryVecDeque::new(gtk::Box::default(), sender.output_sender());
let editor_dialog = EditorDialog::builder() let editor_dialog = EditorDialog::builder()
.transient_for(root) .transient_for(root)
@ -151,14 +151,14 @@ impl SimpleComponent for ProfilePage {
avatar, avatar,
posts, posts,
comments, comments,
communities, moderates,
editor_dialog, editor_dialog,
current_profile_page: 1, current_profile_page: 1,
}; };
let avatar = model.avatar.widget(); let avatar = model.avatar.widget();
let posts = model.posts.widget(); let posts = model.posts.widget();
let comments = model.comments.widget(); let comments = model.comments.widget();
let communities = model.communities.widget(); let moderates = model.moderates.widget();
let widgets = view_output!(); let widgets = view_output!();
ComponentParts { model, widgets } ComponentParts { model, widgets }
@ -167,7 +167,9 @@ impl SimpleComponent for ProfilePage {
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) { fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
match message { match message {
ProfileInput::UpdatePerson(person, clear) => { ProfileInput::UpdatePerson(person, clear) => {
sender.output_sender().emit(crate::AppMsg::UpdateState(crate::AppState::Person)); sender
.output_sender()
.emit(crate::AppMsg::UpdateState(crate::AppState::Person));
if clear { if clear {
self.info = person.clone(); self.info = person.clone();
@ -176,7 +178,7 @@ impl SimpleComponent for ProfilePage {
self.posts.guard().clear(); self.posts.guard().clear();
self.comments.guard().clear(); self.comments.guard().clear();
self.communities.guard().clear(); self.moderates.guard().clear();
} }
for post in person.posts { for post in person.posts {
@ -185,6 +187,9 @@ impl SimpleComponent for ProfilePage {
for comment in person.comments { for comment in person.comments {
self.comments.guard().push_back(comment); self.comments.guard().push_back(comment);
} }
for community in person.moderates {
self.moderates.guard().push_back(community);
}
} }
ProfileInput::SendMessageRequest => self.editor_dialog.sender().emit(DialogMsg::Show), ProfileInput::SendMessageRequest => self.editor_dialog.sender().emit(DialogMsg::Show),
ProfileInput::SendMessage(content) => { ProfileInput::SendMessage(content) => {
@ -205,10 +210,12 @@ impl SimpleComponent for ProfilePage {
match api::user::get_user(person_id, page) { match api::user::get_user(person_id, page) {
Ok(person) => { Ok(person) => {
sender.input(ProfileInput::UpdatePerson(person, page == 1)); sender.input(ProfileInput::UpdatePerson(person, page == 1));
}, }
Err(err) => { Err(err) => {
sender.output_sender().emit(crate::AppMsg::ShowMessage(err.to_string())); sender
}, .output_sender()
.emit(crate::AppMsg::ShowMessage(err.to_string()));
}
}; };
}); });
} }