message-toolbar: Replace toolbar with text when user can't send message

Instead of disabling the toolbar.
Works around an issue where the input doesn't send the text input enter
Wayland signal after it has been deactivated.
This commit is contained in:
Kévin Commaille 2023-12-21 13:29:34 +01:00
parent 7c3f7f83f9
commit 5293f9308c
No known key found for this signature in database
GPG Key ID: 29A48C1F03620416
2 changed files with 190 additions and 142 deletions

View File

@ -1,3 +1,4 @@
use adw::subclass::prelude::*;
use ashpd::{
desktop::location::{Accuracy, LocationProxy},
WindowIdentifier,
@ -9,7 +10,6 @@ use gtk::{
gdk, gio,
glib::{self, clone},
prelude::*,
subclass::prelude::*,
CompositeTemplate,
};
use matrix_sdk::{
@ -87,6 +87,8 @@ mod imp {
pub markdown_enabled: Cell<bool>,
pub completion: CompletionPopover,
#[template_child]
pub main_stack: TemplateChild<gtk::Stack>,
#[template_child]
pub message_entry: TemplateChild<sourceview::View>,
#[template_child]
pub related_event_header: TemplateChild<LabelWithWidgets>,
@ -104,7 +106,7 @@ mod imp {
impl ObjectSubclass for MessageToolbar {
const NAME: &'static str = "MessageToolbar";
type Type = super::MessageToolbar;
type ParentType = gtk::Box;
type ParentType = adw::Bin;
fn class_init(klass: &mut Self::Class) {
CustomEntry::static_type();
@ -252,7 +254,7 @@ mod imp {
// Tab auto-completion.
self.completion.set_parent(&*self.message_entry);
obj.set_sensitive(obj.can_send_messages());
obj.update_can_send_messages();
}
fn dispose(&self) {
@ -261,7 +263,7 @@ mod imp {
}
impl WidgetImpl for MessageToolbar {}
impl BoxImpl for MessageToolbar {}
impl BinImpl for MessageToolbar {}
impl MessageToolbar {
/// Set the room currently displayed.
@ -294,7 +296,7 @@ mod imp {
glib::wrapper! {
/// A toolbar with different actions to send messages.
pub struct MessageToolbar(ObjectSubclass<imp::MessageToolbar>)
@extends gtk::Widget, gtk::Box, @implements gtk::Accessible;
@extends gtk::Widget, adw::Bin, @implements gtk::Accessible;
}
#[gtk::template_callbacks]
@ -348,6 +350,10 @@ impl MessageToolbar {
}
pub fn set_reply_to(&self, event: Event) {
if !self.can_send_messages() {
return;
}
let imp = self.imp();
imp.related_event_header
.set_widgets(vec![Pill::for_user(event.sender().upcast_ref())]);
@ -366,6 +372,9 @@ impl MessageToolbar {
/// Set the event to edit.
pub fn set_edit(&self, event: Event) {
if !self.can_send_messages() {
return;
}
let Some(room) = event.room() else {
return;
};
@ -709,6 +718,10 @@ impl MessageToolbar {
}
pub async fn send_file(&self, file: gio::File) {
if !self.can_send_messages() {
return;
}
match load_file(&file).await {
Ok((bytes, file_info)) => {
let window = self.root().and_downcast::<gtk::Window>().unwrap();
@ -855,9 +868,13 @@ impl MessageToolbar {
if self.can_send_messages() == can_send {
return;
}
let imp = self.imp();
imp.can_send_messages.set(can_send);
let page = if can_send { "enabled" } else { "disabled" };
imp.main_stack.set_visible_child_name(page);
self.imp().can_send_messages.set(can_send);
self.set_sensitive(can_send);
self.notify_can_send_messages();
}

View File

@ -13,147 +13,178 @@
</item>
</section>
</menu>
<template class="MessageToolbar" parent="GtkBox">
<property name="orientation">vertical</property>
<template class="MessageToolbar" parent="AdwBin">
<child>
<object class="GtkBox" id="related_event_toolbar">
<style>
<class name="related-event-toolbar"/>
</style>
<property name="spacing">12</property>
<binding name="visible">
<closure type="gboolean" function="object_is_some">
<lookup name="related-event">MessageToolbar</lookup>
</closure>
</binding>
<object class="GtkStack" id="main_stack">
<property name="transition-type">crossfade</property>
<child>
<object class="GtkBox">
<property name="margin-bottom">6</property>
<property name="margin-top">8</property>
<property name="orientation">vertical</property>
<child>
<object class="LabelWithWidgets" id="related_event_header">
<object class="GtkStackPage">
<property name="name">enabled</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkBox" id="related_event_toolbar">
<style>
<class name="related-event-toolbar"/>
</style>
<property name="spacing">12</property>
<binding name="visible">
<closure type="gboolean" function="object_is_some">
<lookup name="related-event">MessageToolbar</lookup>
</closure>
</binding>
<child>
<object class="GtkBox">
<property name="margin-bottom">6</property>
<property name="margin-top">8</property>
<property name="orientation">vertical</property>
<child>
<object class="LabelWithWidgets" id="related_event_header">
<style>
<class name="heading"/>
</style>
<property name="valign">center</property>
<property name="hexpand">true</property>
<property name="margin-top">2</property>
</object>
</child>
<child>
<object class="ContentMessageContent" id="related_event_content">
<style>
<class name="related-event-content"/>
<class name="dim-label"/>
</style>
<property name="format">ellipsized</property>
</object>
</child>
<child>
<object class="GtkGestureClick">
<signal name="pressed" handler="handle_related_event_click" swapped="yes"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkButton">
<style>
<class name="circular"/>
</style>
<property name="halign">end</property>
<property name="valign">start</property>
<property name="icon-name">close-symbolic</property>
<property name="action-name">message-toolbar.clear-related-event</property>
<property name="tooltip-text" translatable="yes">Cancel</property>
<accessibility>
<property name="label" translatable="yes">Cancel</property>
</accessibility>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<style>
<class name="toolbar"/>
</style>
<child>
<object class="GtkButton">
<property name="valign">end</property>
<property name="icon-name">attachment-symbolic</property>
<property name="action-name">message-toolbar.select-file</property>
<property name="tooltip-text" translatable="yes">Send a File</property>
<accessibility>
<property name="label" translatable="yes">Send a File</property>
</accessibility>
</object>
</child>
<child>
<object class="GtkButton">
<property name="valign">end</property>
<property name="icon-name">emoji-symbolic</property>
<property name="action-name">message-toolbar.open-emoji</property>
<property name="tooltip-text" translatable="yes">Insert an Emoji</property>
<accessibility>
<property name="label" translatable="yes">Insert an Emoji</property>
</accessibility>
</object>
</child>
<child>
<object class="CustomEntry">
<child>
<object class="GtkScrolledWindow">
<property name="vexpand">True</property>
<property name="hexpand">True</property>
<property name="vscrollbar-policy">external</property>
<property name="max-content-height">200</property>
<property name="propagate-natural-height">True</property>
<property name="child">
<object class="GtkSourceView" id="message_entry">
<property name="hexpand">True</property>
<property name="accepts-tab">False</property>
<property name="top-margin">7</property>
<property name="bottom-margin">7</property>
<property name="wrap-mode">word</property>
<accessibility>
<!-- Translators: This is the name of the input widget where messages
are entered before being sent, for accessibility tools. -->
<property name="label" translatable="yes">Message Composer</property>
</accessibility>
</object>
</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuButton">
<property name="valign">end</property>
<property name="direction">up</property>
<property name="icon-name">more-symbolic</property>
<property name="menu-model">message-menu-model</property>
<property name="tooltip-text" translatable="yes">More Options</property>
<accessibility>
<property name="label" translatable="yes">More Options</property>
</accessibility>
</object>
</child>
<child>
<object class="GtkButton">
<property name="valign">end</property>
<property name="icon-name">send-symbolic</property>
<property name="focus-on-click">False</property>
<property name="action-name">message-toolbar.send-text-message</property>
<property name="tooltip-text" translatable="yes">Send Message</property>
<style>
<class name="suggested-action"/>
<class name="circular"/>
</style>
<accessibility>
<property name="label" translatable="yes">Send Message</property>
</accessibility>
</object>
</child>
</object>
</child>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">disabled</property>
<property name="child">
<object class="GtkLabel">
<property name="label" translatable="yes">You dont have permission to send messages to this room</property>
<property name="wrap">True</property>
<property name="wrap-mode">word-char</property>
<property name="halign">center</property>
<property name="valign">center</property>
<style>
<class name="heading"/>
</style>
<property name="valign">center</property>
<property name="hexpand">true</property>
<property name="margin-top">2</property>
</object>
</child>
<child>
<object class="ContentMessageContent" id="related_event_content">
<style>
<class name="related-event-content"/>
<class name="dim-label"/>
</style>
<property name="format">ellipsized</property>
</object>
</child>
<child>
<object class="GtkGestureClick">
<signal name="pressed" handler="handle_related_event_click" swapped="yes"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkButton">
<style>
<class name="circular"/>
</style>
<property name="halign">end</property>
<property name="valign">start</property>
<property name="icon-name">close-symbolic</property>
<property name="action-name">message-toolbar.clear-related-event</property>
<property name="tooltip-text" translatable="yes">Cancel</property>
<accessibility>
<property name="label" translatable="yes">Cancel</property>
</accessibility>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<style>
<class name="toolbar"/>
</style>
<child>
<object class="GtkButton">
<property name="valign">end</property>
<property name="icon-name">attachment-symbolic</property>
<property name="action-name">message-toolbar.select-file</property>
<property name="tooltip-text" translatable="yes">Send a File</property>
<accessibility>
<property name="label" translatable="yes">Send a File</property>
</accessibility>
</object>
</child>
<child>
<object class="GtkButton">
<property name="valign">end</property>
<property name="icon-name">emoji-symbolic</property>
<property name="action-name">message-toolbar.open-emoji</property>
<property name="tooltip-text" translatable="yes">Insert an Emoji</property>
<accessibility>
<property name="label" translatable="yes">Insert an Emoji</property>
</accessibility>
</object>
</child>
<child>
<object class="CustomEntry">
<child>
<object class="GtkScrolledWindow">
<property name="vexpand">True</property>
<property name="hexpand">True</property>
<property name="vscrollbar-policy">external</property>
<property name="max-content-height">200</property>
<property name="propagate-natural-height">True</property>
<property name="child">
<object class="GtkSourceView" id="message_entry">
<property name="hexpand">True</property>
<property name="accepts-tab">False</property>
<property name="top-margin">7</property>
<property name="bottom-margin">7</property>
<property name="wrap-mode">word</property>
<accessibility>
<!-- Translators: This is the name of the input widget where messages
are entered before being sent, for accessibility tools. -->
<property name="label" translatable="yes">Message Composer</property>
</accessibility>
</object>
</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuButton">
<property name="valign">end</property>
<property name="direction">up</property>
<property name="icon-name">more-symbolic</property>
<property name="menu-model">message-menu-model</property>
<property name="tooltip-text" translatable="yes">More Options</property>
<accessibility>
<property name="label" translatable="yes">More Options</property>
</accessibility>
</object>
</child>
<child>
<object class="GtkButton">
<property name="valign">end</property>
<property name="icon-name">send-symbolic</property>
<property name="focus-on-click">False</property>
<property name="action-name">message-toolbar.send-text-message</property>
<property name="tooltip-text" translatable="yes">Send Message</property>
<style>
<class name="suggested-action"/>
<class name="circular"/>
</style>
<accessibility>
<property name="label" translatable="yes">Send Message</property>
</accessibility>
</property>
</object>
</child>
</object>