Drop RefCell's and use Relm component mutability instead

This commit is contained in:
Bnyro 2023-06-19 07:34:10 +02:00
parent ea6c6f69fa
commit ef6ee57f6c
3 changed files with 28 additions and 35 deletions

View File

@ -2,14 +2,13 @@ use lemmy_api_common::{community::GetCommunityResponse, lemmy_db_views::structs:
use relm4::{prelude::*, factory::FactoryVecDeque}; use relm4::{prelude::*, factory::FactoryVecDeque};
use gtk::prelude::*; use gtk::prelude::*;
use relm4_components::web_image::WebImage; use relm4_components::web_image::WebImage;
use std::cell::RefCell;
use crate::{api, util::get_web_image_msg}; use crate::{api, util::get_web_image_msg};
use super::post_row::PostRow; use super::post_row::PostRow;
pub struct CommunityPage { pub struct CommunityPage {
info: RefCell<GetCommunityResponse>, info: GetCommunityResponse,
avatar: Controller<WebImage>, avatar: Controller<WebImage>,
posts: FactoryVecDeque<PostRow> posts: FactoryVecDeque<PostRow>
} }
@ -43,16 +42,16 @@ impl SimpleComponent for CommunityPage {
}, },
gtk::Label { gtk::Label {
#[watch] #[watch]
set_text: &model.info.borrow().community_view.community.name, set_text: &model.info.community_view.community.name,
add_css_class: "font-very-bold", add_css_class: "font-very-bold",
}, },
gtk::Label { gtk::Label {
#[watch] #[watch]
set_text: &model.info.borrow().clone().community_view.community.description.unwrap_or("".to_string()), set_text: &model.info.clone().community_view.community.description.unwrap_or("".to_string()),
}, },
gtk::Label { gtk::Label {
#[watch] #[watch]
set_text: &format!("{} subscribers, ", model.info.borrow().community_view.counts.subscribers), set_text: &format!("{} subscribers", model.info.community_view.counts.subscribers),
}, },
gtk::Box { gtk::Box {
@ -64,11 +63,7 @@ impl SimpleComponent for CommunityPage {
gtk::Label { gtk::Label {
#[watch] #[watch]
set_text: &format!("{} posts, ", model.info.borrow().community_view.counts.posts), set_text: &format!("{} posts, {} comments", model.info.community_view.counts.posts, model.info.community_view.counts.comments),
},
gtk::Label {
#[watch]
set_text: &format!("{} comments", model.info.borrow().clone().community_view.counts.comments),
}, },
}, },
@ -90,7 +85,7 @@ impl SimpleComponent for CommunityPage {
) -> 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 model = CommunityPage { info: RefCell::new(init), avatar, posts }; let model = CommunityPage { info: init, avatar, posts };
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!();
@ -101,7 +96,7 @@ impl SimpleComponent for CommunityPage {
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) { fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
match message { match message {
CommunityInput::UpdateCommunity(community) => { CommunityInput::UpdateCommunity(community) => {
*self.info.borrow_mut() = community.clone(); self.info = community.clone();
self.avatar.emit(get_web_image_msg(community.community_view.community.icon)); self.avatar.emit(get_web_image_msg(community.community_view.community.icon));
self.posts.guard().clear(); self.posts.guard().clear();

View File

@ -2,14 +2,13 @@ use lemmy_api_common::{lemmy_db_views::structs::{CommentView}, post::GetPostResp
use relm4::{prelude::*, factory::FactoryVecDeque}; use relm4::{prelude::*, factory::FactoryVecDeque};
use gtk::prelude::*; use gtk::prelude::*;
use relm4_components::web_image::WebImage; use relm4_components::web_image::WebImage;
use std::cell::RefCell;
use crate::{api, util::{get_web_image_msg, get_web_image_url}}; use crate::{api, util::{get_web_image_msg, get_web_image_url}};
use super::comment_row::CommentRow; use super::comment_row::CommentRow;
pub struct PostPage { pub struct PostPage {
info: RefCell<GetPostResponse>, info: GetPostResponse,
image: Controller<WebImage>, image: Controller<WebImage>,
creator_avatar: Controller<WebImage>, creator_avatar: Controller<WebImage>,
community_avatar: Controller<WebImage>, community_avatar: Controller<WebImage>,
@ -46,12 +45,12 @@ impl SimpleComponent for PostPage {
}, },
gtk::Label { gtk::Label {
#[watch] #[watch]
set_text: &model.info.borrow().post_view.post.name, set_text: &model.info.post_view.post.name,
add_css_class: "font-very-bold", add_css_class: "font-very-bold",
}, },
gtk::Label { gtk::Label {
#[watch] #[watch]
set_text: &model.info.borrow().clone().post_view.post.body.unwrap_or("".to_string()), set_text: &model.info.clone().post_view.post.body.unwrap_or("".to_string()),
set_margin_top: 10, set_margin_top: 10,
}, },
@ -65,7 +64,7 @@ impl SimpleComponent for PostPage {
set_text: "posted by " set_text: "posted by "
}, },
if model.info.borrow().post_view.creator.avatar.is_some() { if model.info.post_view.creator.avatar.is_some() {
gtk::Box { gtk::Box {
set_hexpand: false, set_hexpand: false,
set_margin_start: 10, set_margin_start: 10,
@ -77,7 +76,7 @@ impl SimpleComponent for PostPage {
}, },
gtk::Button { gtk::Button {
set_label: &model.info.borrow().post_view.creator.name, set_label: &model.info.post_view.creator.name,
connect_clicked => PostInput::OpenPerson, connect_clicked => PostInput::OpenPerson,
}, },
@ -85,7 +84,7 @@ impl SimpleComponent for PostPage {
set_text: " in " set_text: " in "
}, },
if model.info.borrow().community_view.community.icon.is_some() { if model.info.community_view.community.icon.is_some() {
gtk::Box { gtk::Box {
set_hexpand: false, set_hexpand: false,
#[local_ref] #[local_ref]
@ -96,7 +95,7 @@ impl SimpleComponent for PostPage {
}, },
gtk::Button { gtk::Button {
set_label: &model.info.borrow().community_view.community.title, set_label: &model.info.community_view.community.title,
connect_clicked => PostInput::OpenCommunity, connect_clicked => PostInput::OpenCommunity,
}, },
@ -117,11 +116,11 @@ impl SimpleComponent for PostPage {
gtk::Label { gtk::Label {
#[watch] #[watch]
set_text: &format!("{} comments, ", model.info.borrow().post_view.counts.comments), set_text: &format!("{} comments, ", model.info.post_view.counts.comments),
}, },
gtk::Label { gtk::Label {
#[watch] #[watch]
set_text: &format!("{} score", model.info.borrow().post_view.counts.score), set_text: &format!("{} score", model.info.post_view.counts.score),
}, },
}, },
@ -144,7 +143,7 @@ impl SimpleComponent for PostPage {
let comments = FactoryVecDeque::new(gtk::Box::default(), sender.output_sender()); let comments = FactoryVecDeque::new(gtk::Box::default(), sender.output_sender());
let creator_avatar = WebImage::builder().launch("".to_string()).detach(); let creator_avatar = WebImage::builder().launch("".to_string()).detach();
let community_avatar = WebImage::builder().launch("".to_string()).detach(); let community_avatar = WebImage::builder().launch("".to_string()).detach();
let model = PostPage { info: RefCell::new(init), image, comments, creator_avatar, community_avatar }; let model = PostPage { info: init, image, comments, creator_avatar, community_avatar };
let image = model.image.widget(); let image = model.image.widget();
let comments = model.comments.widget(); let comments = model.comments.widget();
@ -158,7 +157,7 @@ impl SimpleComponent for PostPage {
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) { fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
match message { match message {
PostInput::UpdatePost(post) => { PostInput::UpdatePost(post) => {
*self.info.borrow_mut() = post.clone(); self.info = post.clone();
self.image.emit(get_web_image_msg(post.post_view.post.thumbnail_url)); self.image.emit(get_web_image_msg(post.post_view.post.thumbnail_url));
self.community_avatar.emit(get_web_image_msg(post.community_view.community.icon)); self.community_avatar.emit(get_web_image_msg(post.community_view.community.icon));
@ -180,15 +179,15 @@ impl SimpleComponent for PostPage {
} }
} }
PostInput::OpenPerson => { PostInput::OpenPerson => {
let name = self.info.borrow().post_view.creator.name.clone(); let name = self.info.post_view.creator.name.clone();
let _ = sender.output(crate::AppMsg::OpenPerson(name)); let _ = sender.output(crate::AppMsg::OpenPerson(name));
} }
PostInput::OpenCommunity => { PostInput::OpenCommunity => {
let community_name = self.info.borrow().community_view.community.name.clone(); let community_name = self.info.community_view.community.name.clone();
let _ = sender.output(crate::AppMsg::OpenCommunity(community_name)); let _ = sender.output(crate::AppMsg::OpenCommunity(community_name));
} }
PostInput::OpenLink => { PostInput::OpenLink => {
let post = self.info.borrow().post_view.post.clone(); let post = self.info.post_view.post.clone();
let mut link = get_web_image_url(post.url); let mut link = get_web_image_url(post.url);
if link.is_empty() { if link.is_empty() {
link = get_web_image_url(post.thumbnail_url); link = get_web_image_url(post.thumbnail_url);

View File

@ -2,14 +2,13 @@ use lemmy_api_common::person::GetPersonDetailsResponse;
use relm4::{prelude::*, factory::FactoryVecDeque}; use relm4::{prelude::*, factory::FactoryVecDeque};
use gtk::prelude::*; use gtk::prelude::*;
use relm4_components::web_image::WebImage; use relm4_components::web_image::WebImage;
use std::cell::RefCell;
use crate::util::get_web_image_msg; use crate::util::get_web_image_msg;
use super::post_row::PostRow; use super::post_row::PostRow;
pub struct ProfilePage { pub struct ProfilePage {
info: RefCell<GetPersonDetailsResponse>, info: GetPersonDetailsResponse,
avatar: Controller<WebImage>, avatar: Controller<WebImage>,
posts: FactoryVecDeque<PostRow> posts: FactoryVecDeque<PostRow>
} }
@ -40,12 +39,12 @@ impl SimpleComponent for ProfilePage {
}, },
gtk::Label { gtk::Label {
#[watch] #[watch]
set_text: &model.info.borrow().person_view.person.name, set_text: &model.info.person_view.person.name,
add_css_class: "font-very-bold", add_css_class: "font-very-bold",
}, },
gtk::Label { gtk::Label {
#[watch] #[watch]
set_text: &model.info.borrow().clone().person_view.person.bio.unwrap_or("".to_string()), set_text: &model.info.person_view.person.bio.clone().unwrap_or("".to_string()),
}, },
gtk::Box { gtk::Box {
@ -57,11 +56,11 @@ impl SimpleComponent for ProfilePage {
gtk::Label { gtk::Label {
#[watch] #[watch]
set_text: &format!("{} posts, ", model.info.borrow().person_view.counts.post_count), set_text: &format!("{} posts, ", model.info.person_view.counts.post_count),
}, },
gtk::Label { gtk::Label {
#[watch] #[watch]
set_text: &format!("{} comments", model.info.borrow().person_view.counts.comment_count), set_text: &format!("{} comments", model.info.person_view.counts.comment_count),
}, },
}, },
@ -83,7 +82,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 model = ProfilePage { info: RefCell::new(init), avatar, posts }; let model = ProfilePage { info: init, avatar, posts };
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!();
@ -94,7 +93,7 @@ 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) => { ProfileInput::UpdatePerson(person) => {
*self.info.borrow_mut() = person.clone(); self.info = person.clone();
self.avatar.emit(get_web_image_msg(person.person_view.person.avatar)); self.avatar.emit(get_web_image_msg(person.person_view.person.avatar));
self.posts.guard().clear(); self.posts.guard().clear();
for post in person.posts { for post in person.posts {