aboutsummaryrefslogtreecommitdiff
path: root/main/src/ui/conversation_content_view
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/ui/conversation_content_view')
-rw-r--r--main/src/ui/conversation_content_view/conversation_view.vala78
-rw-r--r--main/src/ui/conversation_content_view/file_widget.vala10
-rw-r--r--main/src/ui/conversation_content_view/item_actions.vala61
-rw-r--r--main/src/ui/conversation_content_view/message_widget.vala16
4 files changed, 134 insertions, 31 deletions
diff --git a/main/src/ui/conversation_content_view/conversation_view.vala b/main/src/ui/conversation_content_view/conversation_view.vala
index 257a659b..233d3312 100644
--- a/main/src/ui/conversation_content_view/conversation_view.vala
+++ b/main/src/ui/conversation_content_view/conversation_view.vala
@@ -51,26 +51,45 @@ public class ConversationView : Widget, Plugins.ConversationItemCollection, Plug
// Setup all message menu buttons
var correction_button = new Button() { name="correction" };
correction_button.clicked.connect((button) => {
- on_action_button_clicked(button, null);
+ on_action_button_clicked("correction", null);
});
action_buttons["correction"] = correction_button;
message_menu_box.append(correction_button);
- var reply_button = new Button() { name="reply" };
- reply_button.clicked.connect((button) => {
- on_action_button_clicked(button, null);
- });
- action_buttons["reply"] = reply_button;
- message_menu_box.append(reply_button);
-
var reaction_button = new MenuButton() { name="reaction" };
EmojiChooser chooser = new EmojiChooser();
chooser.emoji_picked.connect((emoji) => {
- on_action_button_clicked(reaction_button, new GLib.Variant.string(emoji));
+ on_action_button_clicked("reaction", new GLib.Variant.string(emoji));
});
reaction_button.popover = chooser;
action_buttons["reaction"] = reaction_button;
message_menu_box.append(reaction_button);
+
+ var reply_button = new Button() { name="reply" };
+ reply_button.clicked.connect((button) => {
+ on_action_button_clicked("reply", null);
+ });
+ action_buttons["reply"] = reply_button;
+ message_menu_box.append(reply_button);
+
+ var delete_button = new Button() { name="delete" };
+ delete_button.clicked.connect((button) => {
+ on_action_button_clicked("delete", null);
+ });
+ action_buttons["delete"] = delete_button;
+ message_menu_box.append(delete_button);
+
+ var menu_button = new MenuButton() { name="menu", tooltip_text=_("More actions") };
+ action_buttons["menu"] = menu_button;
+ message_menu_box.append(menu_button);
+
+ SimpleAction action_action = new SimpleAction("action", VariantType.STRING);
+ action_action.activate.connect((parameter) => {
+ on_action_button_clicked(parameter.get_string());
+ });
+ SimpleActionGroup action_group = new SimpleActionGroup();
+ action_group.insert(action_action);
+ this.insert_action_group("action", action_group);
}
public ConversationView init(StreamInteractor stream_interactor) {
@@ -139,7 +158,7 @@ public class ConversationView : Widget, Plugins.ConversationItemCollection, Plug
private bool is_highlight_fixed() {
foreach (Widget widget in action_buttons.values) {
MenuButton? menu_button = widget as MenuButton;
- if (menu_button != null && menu_button.popover.visible) return true;
+ if (menu_button != null && menu_button.popover != null && menu_button.popover.visible) return true;
ToggleButton? toggle_button = widget as ToggleButton;
if (toggle_button != null && toggle_button.active) return true;
@@ -224,24 +243,35 @@ public class ConversationView : Widget, Plugins.ConversationItemCollection, Plug
if (message_actions != null) {
message_menu_box.visible = true;
+ Menu menu_model = new Menu();
+ ((MenuButton)action_buttons["menu"]).menu_model = menu_model;
+
foreach (Widget widget in action_buttons.values) {
widget.visible = false;
}
// Configure as many buttons as we need with the actions for the current meta item
foreach (var message_action in current_message_actions) {
- Widget button_widget = action_buttons[message_action.name];
- button_widget.visible = true;
- if (message_action.name == "reaction") {
- MenuButton button = (MenuButton) button_widget;
- button.sensitive = message_action.sensitive;
- button.icon_name = message_action.icon_name;
- button.tooltip_text = Util.string_if_tooltips_active(message_action.tooltip);
- } else if (message_action.callback != null) {
- Button button = (Button) button_widget;
- button.sensitive = message_action.sensitive;
- button.icon_name = message_action.icon_name;
- button.tooltip_text = Util.string_if_tooltips_active(message_action.tooltip);
+ if (message_action.shortcut_action) {
+ Widget button_widget = action_buttons[message_action.name];
+ button_widget.visible = true;
+
+ if (message_action.name == "reaction") {
+ MenuButton button = (MenuButton) button_widget;
+ button.sensitive = message_action.sensitive;
+ button.icon_name = message_action.icon_name;
+ button.tooltip_text = Util.string_if_tooltips_active(message_action.tooltip);
+ } else if (message_action.callback != null) {
+ Button button = (Button) button_widget;
+ button.sensitive = message_action.sensitive;
+ button.icon_name = message_action.icon_name;
+ button.tooltip_text = Util.string_if_tooltips_active(message_action.tooltip);
+ }
+ } else {
+ MenuItem item = new MenuItem(message_action.tooltip, null);
+ item.set_action_and_target_value("action.action", new GLib.Variant.string(message_action.name));
+ menu_model.append_item(item);
+ action_buttons["menu"].visible = true;
}
}
} else {
@@ -510,9 +540,9 @@ public class ConversationView : Widget, Plugins.ConversationItemCollection, Plug
(upper_item.mark == Message.Marked.WONTSEND) == (lower_item.mark == Message.Marked.WONTSEND);
}
- private void on_action_button_clicked(Widget widget, GLib.Variant? variant = null) {
+ private void on_action_button_clicked(string action_name, GLib.Variant? variant = null) {
foreach (var action in message_actions) {
- if (action.name != widget.name) continue;
+ if (action.name != action_name) continue;
action.callback(variant);
}
}
diff --git a/main/src/ui/conversation_content_view/file_widget.vala b/main/src/ui/conversation_content_view/file_widget.vala
index 0e3cee03..cb734e5f 100644
--- a/main/src/ui/conversation_content_view/file_widget.vala
+++ b/main/src/ui/conversation_content_view/file_widget.vala
@@ -31,10 +31,12 @@ public class FileMetaItem : ConversationSummary.ContentMetaItem {
Gee.List<Plugins.MessageAction> actions = new ArrayList<Plugins.MessageAction>();
- if (stream_interactor.get_module(ContentItemStore.IDENTITY).get_message_id_for_content_item(file_item.conversation, content_item) != null) {
- actions.add(get_reply_action(content_item, file_item.conversation, stream_interactor));
- actions.add(get_reaction_action(content_item, file_item.conversation, stream_interactor));
- }
+ actions.add(get_reply_action(content_item, file_item.conversation, stream_interactor));
+ actions.add(get_reaction_action(content_item, file_item.conversation, stream_interactor));
+
+ var delete_action = get_delete_action(content_item, file_item.conversation, stream_interactor);
+ if (delete_action != null) actions.add(delete_action);
+
return actions;
}
}
diff --git a/main/src/ui/conversation_content_view/item_actions.vala b/main/src/ui/conversation_content_view/item_actions.vala
index d4195bdd..6102dc9a 100644
--- a/main/src/ui/conversation_content_view/item_actions.vala
+++ b/main/src/ui/conversation_content_view/item_actions.vala
@@ -48,4 +48,65 @@ namespace Dino.Ui {
}
return action;
}
+
+ public Plugins.MessageAction? get_delete_action(ContentItem content_item, Conversation conversation, StreamInteractor stream_interactor) {
+ bool is_deletable = stream_interactor.get_module(MessageDeletion.IDENTITY).is_deletable(conversation, content_item);
+ if (!is_deletable) return null;
+
+ bool can_delete_for_everyone = stream_interactor.get_module(MessageDeletion.IDENTITY).can_delete_for_everyone(conversation, content_item);
+
+ Plugins.MessageAction action = new Plugins.MessageAction();
+ action.name = "delete";
+ action.icon_name = "user-trash-symbolic";
+ action.tooltip = _("Delete message");
+ action.shortcut_action = false;
+ action.callback = () => {
+ Adw.AlertDialog dialog = new Adw.AlertDialog(_("Delete message"), null) { content_width = 350, follows_content_size = false };
+ if (can_delete_for_everyone) {
+ CheckButton check_button = new CheckButton() { label="Delete for everyone", active=true };
+
+ Box extra_child = new Box(Orientation.VERTICAL, 8);
+ extra_child.append(new Label("Would you like to remove this message for everyone or just for yourself?") { xalign=0, use_markup=true, wrap=true });
+ extra_child.append(new Label("The message will only be deleted for others <b>if their app supports it</b>!") { xalign=0, use_markup=true, wrap=true });
+ extra_child.append(check_button);
+ dialog.extra_child = extra_child;
+
+ check_button.toggled.connect(() => {
+ dialog.remove_response("delete");
+ dialog.remove_response("cancel");
+ if (check_button.active) {
+ dialog.add_response("delete", "Delete for everyone");
+ } else {
+ dialog.add_response("delete", "Only delete for yourself");
+ }
+ dialog.set_response_appearance("delete", Adw.ResponseAppearance.DESTRUCTIVE);
+ dialog.add_response("cancel", "Cancel");
+ });
+ dialog.response.connect((response) => {
+ if (response == "delete") {
+ if (check_button.active) {
+ stream_interactor.get_module(MessageDeletion.IDENTITY).delete_globally(conversation, content_item);
+ } else {
+ stream_interactor.get_module(MessageDeletion.IDENTITY).delete_locally(conversation, content_item, conversation.account.bare_jid);
+ }
+ }
+ });
+ dialog.add_response("delete", "Delete for everyone");
+ dialog.set_response_appearance("delete", Adw.ResponseAppearance.DESTRUCTIVE);
+ dialog.add_response("cancel", "Cancel");
+ } else {
+ dialog.extra_child = new Label("This message <b>can't be deleted</b> for everyone. Would you like to remove it only for yourself?") { use_markup=true, wrap=true };
+ dialog.add_response("delete", "Only delete for myself");
+ dialog.set_response_appearance("delete", Adw.ResponseAppearance.DESTRUCTIVE);
+ dialog.add_response("cancel", "Cancel");
+ dialog.response.connect((response) => {
+ if (response == "delete") {
+ stream_interactor.get_module(MessageDeletion.IDENTITY).delete_locally(conversation, content_item, conversation.account.bare_jid);
+ }
+ });
+ }
+ dialog.present(((Dino.Ui.Application)Dino.Application.get_default()).window);
+ };
+ return action;
+ }
} \ No newline at end of file
diff --git a/main/src/ui/conversation_content_view/message_widget.vala b/main/src/ui/conversation_content_view/message_widget.vala
index d116e7de..5f0c067a 100644
--- a/main/src/ui/conversation_content_view/message_widget.vala
+++ b/main/src/ui/conversation_content_view/message_widget.vala
@@ -36,7 +36,8 @@ public class MessageMetaItem : ContentMetaItem {
message_item = content_item as MessageItem;
this.stream_interactor = stream_interactor;
- stream_interactor.get_module(MessageCorrection.IDENTITY).received_correction.connect(on_received_correction);
+ stream_interactor.get_module(MessageCorrection.IDENTITY).received_correction.connect(on_updated_item);
+ stream_interactor.get_module(MessageDeletion.IDENTITY).item_deleted.connect(on_updated_item);
label.activate_link.connect(on_label_activate_link);
@@ -157,6 +158,10 @@ public class MessageMetaItem : ContentMetaItem {
string dim_color = Util.is_dark_theme(this.label) ? "#BDBDBD" : "#707070";
+ if (message.body == "") {
+ markup_text = @"<i><span size='small' color='$dim_color'>%s</span></i>".printf(_("Message deleted"));
+ theme_dependent = true;
+ }
if (message.edit_to != null) {
markup_text += @" <span size='small' color='$dim_color'>(%s)</span>".printf(_("edited"));
theme_dependent = true;
@@ -231,6 +236,7 @@ public class MessageMetaItem : ContentMetaItem {
action1.name = "correction";
action1.icon_name = "document-edit-symbolic";
action1.tooltip = _("Edit message");
+ action1.shortcut_action = false;
action1.callback = () => {
this.in_edit_mode = true;
};
@@ -240,6 +246,9 @@ public class MessageMetaItem : ContentMetaItem {
actions.add(get_reply_action(content_item, message_item.conversation, stream_interactor));
actions.add(get_reaction_action(content_item, message_item.conversation, stream_interactor));
+ var delete_action = get_delete_action(content_item, message_item.conversation, stream_interactor);
+ if (delete_action != null) actions.add(delete_action);
+
return actions;
}
@@ -277,7 +286,7 @@ public class MessageMetaItem : ContentMetaItem {
}
}
- private void on_received_correction(ContentItem content_item) {
+ private void on_updated_item(ContentItem content_item) {
if (this.content_item.id == content_item.id) {
this.content_item = content_item;
message_item = content_item as MessageItem;
@@ -294,7 +303,8 @@ public class MessageMetaItem : ContentMetaItem {
}
public override void dispose() {
- stream_interactor.get_module(MessageCorrection.IDENTITY).received_correction.disconnect(on_received_correction);
+ stream_interactor.get_module(MessageCorrection.IDENTITY).received_correction.disconnect(on_updated_item);
+ stream_interactor.get_module(MessageDeletion.IDENTITY).item_deleted.disconnect(on_updated_item);
this.notify["in-edit-mode"].disconnect(on_in_edit_mode_changed);
if (marked_notify_handler_id != -1) {
this.disconnect(marked_notify_handler_id);