use adw::{prelude::*, subclass::prelude::*};
use gtk::{glib, glib::clone, CompositeTemplate};
use crate::{prelude::*, session::model::Room, utils::BoundObjectWeakRef};
mod imp {
use std::cell::RefCell;
use glib::subclass::InitializingObject;
use super::*;
#[derive(Debug, Default, CompositeTemplate, glib::Properties)]
#[template(resource = "/org/gnome/Fractal/ui/session/view/content/room_history/title.ui")]
#[properties(wrapper_type = super::RoomHistoryTitle)]
pub struct RoomHistoryTitle {
#[property(get, set = Self::set_room, explicit_notify, nullable)]
pub room: BoundObjectWeakRef<Room>,
#[property(get)]
pub title: RefCell<String>,
#[property(get)]
pub subtitle: RefCell<Option<String>>,
#[template_child]
pub subtitle_label: TemplateChild<gtk::Label>,
}
#[glib::object_subclass]
impl ObjectSubclass for RoomHistoryTitle {
const NAME: &'static str = "RoomHistoryTitle";
type Type = super::RoomHistoryTitle;
type ParentType = adw::Bin;
fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
klass.set_css_name("room-title");
}
fn instance_init(obj: &InitializingObject<Self>) {
obj.init_template();
}
}
#[glib::derived_properties]
impl ObjectImpl for RoomHistoryTitle {}
impl WidgetImpl for RoomHistoryTitle {}
impl BinImpl for RoomHistoryTitle {}
impl RoomHistoryTitle {
fn set_room(&self, room: Option<Room>) {
if self.room.obj() == room {
return;
}
self.room.disconnect_signals();
if let Some(room) = room {
let display_name_handler = room.connect_display_name_notify(clone!(
#[weak(rename_to = imp)]
self,
move |_| {
imp.update_title();
}
));
let topic_handler = room.connect_topic_notify(clone!(
#[weak(rename_to = imp)]
self,
move |_| {
imp.update_subtitle();
}
));
self.room
.set(&room, vec![display_name_handler, topic_handler]);
}
self.obj().notify_room();
self.update_title();
self.update_subtitle();
}
fn update_title(&self) {
let Some(room) = self.room.obj() else {
return;
};
let mut title = room.display_name().replace('\n', "");
title.truncate_end_whitespaces();
if *self.title.borrow() == title {
return;
}
self.title.replace(title);
self.obj().notify_title();
}
fn update_subtitle(&self) {
let Some(room) = self.room.obj() else {
return;
};
let subtitle = room
.topic()
.map(|s| {
let mut s = s.replace('\n', "");
s.truncate_end_whitespaces();
s
})
.filter(|s| !s.is_empty());
if *self.subtitle.borrow() == subtitle {
return;
}
let has_subtitle = subtitle.is_some();
self.subtitle.replace(subtitle);
self.obj().notify_subtitle();
self.subtitle_label.set_visible(has_subtitle);
}
}
}
glib::wrapper! {
pub struct RoomHistoryTitle(ObjectSubclass<imp::RoomHistoryTitle>)
@extends gtk::Widget, adw::Bin, @implements gtk::Accessible;
}
impl RoomHistoryTitle {
pub fn new() -> Self {
glib::Object::new()
}
}
impl Default for RoomHistoryTitle {
fn default() -> Self {
Self::new()
}
}