aboutsummaryrefslogtreecommitdiff
path: root/main/src/ui/conversation_content_view/message_widget.vala
diff options
context:
space:
mode:
authorfrosty <gabriel@bwaaa.monster>2026-08-27 18:56:06 -0400
committerfrosty <gabriel@bwaaa.monster>2026-08-27 18:56:06 -0400
commit3ab53f7cb601c62ede22f1927db5aa3baf00a6e9 (patch)
treed56db40c79c2d72c1aa054cc7f15e5a448d6e922 /main/src/ui/conversation_content_view/message_widget.vala
parent09891ea2f392bad30f4fd4a0cf6f6098ca5c1b4f (diff)
feat: improve message actions and add copy option
Diffstat (limited to 'main/src/ui/conversation_content_view/message_widget.vala')
-rw-r--r--main/src/ui/conversation_content_view/message_widget.vala40
1 files changed, 37 insertions, 3 deletions
diff --git a/main/src/ui/conversation_content_view/message_widget.vala b/main/src/ui/conversation_content_view/message_widget.vala
index f8db1a45..c5a9c145 100644
--- a/main/src/ui/conversation_content_view/message_widget.vala
+++ b/main/src/ui/conversation_content_view/message_widget.vala
@@ -31,12 +31,15 @@ public class MessageMetaItem : ContentMetaItem {
public Label label = new Label("") { use_markup=true, xalign=0, selectable=true, wrap=true, wrap_mode=Pango.WrapMode.WORD_CHAR, hexpand=true, vexpand=true };
private Widget? content_widget;
+ private bool text_selectable = true;
public MessageMetaItem(ContentItem content_item, StreamInteractor stream_interactor) {
base(content_item);
message_item = content_item as MessageItem;
this.stream_interactor = stream_interactor;
+ label.add_css_class("message-text");
+
stream_interactor.get_module(MessageCorrection.IDENTITY).received_correction.connect(on_updated_item);
stream_interactor.get_module(MessageDeletion.IDENTITY).item_deleted.connect(on_updated_item);
@@ -111,12 +114,12 @@ public class MessageMetaItem : ContentMetaItem {
return markups;
}
- private string prepare_message(ArrayList<Xep.MessageMarkup.Span> markups, out int action_name_length) {
+ private string prepare_message(ArrayList<Xep.MessageMarkup.Span> markups, out int action_name_length, bool truncate = true) {
Message message = message_item.message;
string text = message.body ?? "";
action_name_length = 0;
- if (text.char_count() > 10000) {
+ if (truncate && text.char_count() > 10000) {
text = text.substring(0, text.index_of_nth_char(10000)) + " [" + _("Message too long") + "]";
}
@@ -141,15 +144,32 @@ public class MessageMetaItem : ContentMetaItem {
var text_label = new Label("") {
use_markup=true,
xalign=0,
- selectable=true,
+ selectable=text_selectable,
wrap=true,
wrap_mode=Pango.WrapMode.WORD_CHAR,
hexpand=true
};
+ text_label.add_css_class("message-text");
text_label.activate_link.connect(on_label_activate_link);
return text_label;
}
+ public void set_text_selectable(bool selectable) {
+ text_selectable = selectable;
+ if (content_widget != null) set_text_selectable_recursive(content_widget, selectable);
+ }
+
+ private void set_text_selectable_recursive(Widget widget, bool selectable) {
+ Label? text_label = widget as Label;
+ if (text_label != null && text_label.has_css_class("message-text")) {
+ text_label.selectable = selectable;
+ }
+
+ for (Widget? child = widget.get_first_child(); child != null; child = child.get_next_sibling()) {
+ set_text_selectable_recursive(child, selectable);
+ }
+ }
+
private void add_text_attribute(AttrList attributes, Attribute attribute, string text, int source_start, int span_start, int span_end) {
int source_end = source_start + text.char_count();
int start = int.max(source_start, span_start);
@@ -286,6 +306,7 @@ public class MessageMetaItem : ContentMetaItem {
generate_markup_text(label, text, markups, action_name_length);
content_widget = label;
}
+ set_text_selectable_recursive(content_widget, text_selectable);
if (outer != null && !in_edit_mode) {
outer.set_widget(content_widget, Plugins.WidgetType.GTK4, 2);
@@ -331,6 +352,19 @@ public class MessageMetaItem : ContentMetaItem {
actions.add(action1);
}
+ Plugins.MessageAction copy_action = new Plugins.MessageAction();
+ copy_action.name = "copy";
+ copy_action.icon_name = "dino-edit-copy-symbolic";
+ copy_action.tooltip = _("Copy message");
+ copy_action.callback = () => {
+ var markups = copy_markups(message_item.message);
+ int action_name_length;
+ string text = prepare_message(markups, out action_name_length, false);
+ Gdk.Display? display = Gdk.Display.get_default();
+ if (display != null) display.get_clipboard().set_text(text);
+ };
+ actions.add(copy_action);
+
actions.add(get_reply_action(content_item, message_item.conversation, stream_interactor));
actions.add(get_reaction_action(content_item, message_item.conversation, stream_interactor));