Browse Source

wip: make a dedicated widget

af/unable-to-decryt-styling
Alexandre Franke 11 months ago
parent
commit
9223e45410
  1. 61
      src/session/view/content/room_history/message_row/content.rs
  2. 79
      src/session/view/content/room_history/message_row/info.rs
  3. 25
      src/session/view/content/room_history/message_row/info.ui
  4. 1
      src/session/view/content/room_history/message_row/mod.rs

61
src/session/view/content/room_history/message_row/content.rs

@ -6,8 +6,14 @@ use ruma::{events::room::message::MessageType, OwnedEventId, OwnedTransactionId}
use tracing::{error, warn};
use super::{
audio::MessageAudio, caption::MessageCaption, file::MessageFile, location::MessageLocation,
reply::MessageReply, text::MessageText, visual_media::MessageVisualMedia,
audio::MessageAudio,
caption::MessageCaption,
file::MessageFile,
info::{MessageIcon, MessageInfo},
location::MessageLocation,
reply::MessageReply,
text::MessageText,
visual_media::MessageVisualMedia,
};
use crate::{
prelude::*,
@ -40,20 +46,6 @@ pub enum ContentFormat {
Ellipsized = 2,
}
enum MessageIcon {
Info,
Warning,
}
impl MessageIcon {
fn icon_name(self) -> &'static str {
match self {
MessageIcon::Info => "info-symbolic",
MessageIcon::Warning => "warning-symbolic",
}
}
}
mod imp {
use std::cell::Cell;
@ -293,9 +285,10 @@ trait MessageContentContainer: IsA<gtk::Widget> {
);
}
MsgLikeKind::UnableToDecrypt(_) => {
self.build_info_message_content(
&gettext("Could not decrypt this message, decryption will be retried once the keys are available."),
MessageIcon::Warning,
let child = self.reuse_child_or_default::<MessageInfo>();
child.set_icon(MessageIcon::Warning);
child.set_text(
&gettext("Could not decrypt this message, decryption will be retried once the keys are available.")
);
}
msg_like_kind => {
@ -365,7 +358,9 @@ trait MessageContentContainer: IsA<gtk::Widget> {
);
}
MessageType::ServerNotice(message) => {
self.build_info_message_content(&message.body.clone(), MessageIcon::Info);
let child = self.reuse_child_or_default::<MessageInfo>();
child.set_icon(MessageIcon::Info);
child.set_text(&message.body.clone());
}
MessageType::Text(message) => {
let child = self.reuse_child_or_default::<MessageText>();
@ -385,32 +380,6 @@ trait MessageContentContainer: IsA<gtk::Widget> {
}
}
/// Build the content widget of the given informative message as a child
/// of this widget
fn build_info_message_content(&self, label: &str, icon: MessageIcon) {
let child = gtk::Grid::new();
let icon_widget = gtk::Image::new();
let icon_name = icon.icon_name();
icon_widget.set_icon_name(Some(icon_name));
icon_widget.set_margin_start(6);
icon_widget.set_margin_end(12);
let label_widget = gtk::Label::new(Some(label));
label_widget.set_css_classes(&["dimmed"]);
label_widget.set_wrap(true);
label_widget.set_wrap_mode(gtk::pango::WrapMode::WordChar);
label_widget.set_xalign(0.0);
label_widget.set_hexpand(true);
child.attach(&icon_widget, 0, 0, 1, 1);
child.attach_next_to(
&label_widget,
Some(&icon_widget),
gtk::PositionType::Right,
1,
1,
);
self.set_child(Some(child.clone().upcast()));
}
/// Build the content widget of the given media message as a child of this
/// widget.
fn build_media_message_content(

79
src/session/view/content/room_history/message_row/info.rs

@ -0,0 +1,79 @@
use adw::{prelude::*, subclass::prelude::*};
use gtk::{glib, CompositeTemplate};
#[derive(Default)]
pub(crate) enum MessageIcon {
#[default]
Info,
Warning,
}
impl MessageIcon {
fn icon_name(self) -> &'static str {
match self {
MessageIcon::Info => "info-symbolic",
MessageIcon::Warning => "warning-symbolic",
}
}
}
mod imp {
use glib::subclass::InitializingObject;
use super::*;
#[derive(Debug, Default, CompositeTemplate)]
#[template(
resource = "/org/gnome/Fractal/ui/session/view/content/room_history/message_row/info.ui"
)]
pub struct MessageInfo {
#[template_child]
icon: TemplateChild<gtk::Image>,
#[template_child]
description: TemplateChild<gtk::Label>,
}
#[glib::object_subclass]
impl ObjectSubclass for MessageInfo {
const NAME: &'static str = "ContentMessageInfo";
type Type = super::MessageInfo;
type ParentType = adw::Bin;
fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
}
fn instance_init(obj: &InitializingObject<Self>) {
obj.init_template();
}
}
impl ObjectImpl for MessageInfo {}
impl WidgetImpl for MessageInfo {}
impl BinImpl for MessageInfo {}
impl MessageInfo {
pub(super) fn set_icon(&self, icon: MessageIcon) {
self.icon.set_icon_name(Some(icon.icon_name()));
}
pub(super) fn set_text(&self, text: String) {
self.description.set_text(&text);
}
}
}
glib::wrapper! {
/// A widget presenting an informative event.
pub struct MessageInfo(ObjectSubclass<imp::MessageInfo>)
@extends gtk::Widget, adw::Bin, @implements gtk::Accessible;
}
impl MessageInfo {
pub fn new() -> Self {
let obj: Self = glib::Object::new();
obj.imp().set_icon(Some(MessageIcon::Info));
obj.imp().set_text("");
obj
}
}

25
src/session/view/content/room_history/message_row/info.ui

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="ContentMessageInfo" parent="AdwBin">
<property name="focusable">True</property>
<property name="valign">center</property>
<property name="halign">center</property>
<child>
<object class="GtkGrid">
<child>
<object class="GtkImage" id="icon">
<property name="margin-start">6</property>
<property name="margin-end">12</property>
</object>
</child>
<child>
<object class="GtkLabel" id="description">
<property name="css-classes">dimmed</property>
<property name="wrap">True</property>
<property name="wrap-mode">word-char</property>
</object>
</child>
</object>
</child>
</template>
</interface>

1
src/session/view/content/room_history/message_row/mod.rs

@ -6,6 +6,7 @@ mod audio;
mod caption;
mod content;
mod file;
mod info;
mod location;
mod message_state_stack;
mod reaction;

Loading…
Cancel
Save