aboutsummaryrefslogtreecommitdiff
path: root/main/src
diff options
context:
space:
mode:
Diffstat (limited to 'main/src')
-rw-r--r--main/src/ui/application.vala8
-rw-r--r--main/src/ui/chat_input/chat_input_controller.vala35
-rw-r--r--main/src/ui/contact_details/dialog.vala1
-rw-r--r--main/src/ui/contact_details/permissions_provider.vala29
-rw-r--r--main/src/ui/contact_details/settings_provider.vala1
-rw-r--r--main/src/ui/notifications.vala23
-rw-r--r--main/src/ui/occupant_menu/view.vala21
7 files changed, 117 insertions, 1 deletions
diff --git a/main/src/ui/application.vala b/main/src/ui/application.vala
index 8738cd53..90c83562 100644
--- a/main/src/ui/application.vala
+++ b/main/src/ui/application.vala
@@ -138,6 +138,14 @@ public class Dino.Ui.Application : Gtk.Application, Dino.Application {
});
add_action(accept_muc_invite_action);
+ SimpleAction accept_voice_request_action = new SimpleAction("accept-voice-request", VariantType.INT32);
+ accept_voice_request_action.activate.connect((variant) => {
+ Conversation? conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation_by_id(variant.get_int32());
+ if (conversation == null) return;
+ stream_interactor.get_module(MucManager.IDENTITY).change_role(conversation.account, conversation.counterpart, conversation.nickname, "participant");
+ });
+ add_action(accept_voice_request_action);
+
SimpleAction loop_conversations_action = new SimpleAction("loop_conversations", null);
loop_conversations_action.activate.connect(() => { window.loop_conversations(false); });
add_action(loop_conversations_action);
diff --git a/main/src/ui/chat_input/chat_input_controller.vala b/main/src/ui/chat_input/chat_input_controller.vala
index fb7f88b1..55196ea4 100644
--- a/main/src/ui/chat_input/chat_input_controller.vala
+++ b/main/src/ui/chat_input/chat_input_controller.vala
@@ -5,6 +5,7 @@ using Gtk;
using Dino.Entities;
namespace Dino.Ui {
+private const string OPEN_CONVERSATION_DETAILS_URI = "x-dino:open-conversation-details";
public class ChatInputController : Object {
@@ -38,8 +39,19 @@ public class ChatInputController : Object {
chat_text_view_controller.send_text.connect(send_text);
chat_input.encryption_widget.encryption_changed.connect(on_encryption_changed);
-
+
chat_input.file_button.clicked.connect(() => file_picker_selected());
+
+ stream_interactor.get_module(MucManager.IDENTITY).received_occupant_role.connect(update_moderated_input_status);
+ stream_interactor.get_module(MucManager.IDENTITY).room_info_updated.connect(update_moderated_input_status);
+
+ status_description_label.activate_link.connect((uri) => {
+ if (uri == OPEN_CONVERSATION_DETAILS_URI){
+ ContactDetails.Dialog contact_details_dialog = new ContactDetails.Dialog(stream_interactor, conversation);
+ contact_details_dialog.present();
+ }
+ return true;
+ });
}
public void set_conversation(Conversation conversation) {
@@ -51,6 +63,10 @@ public class ChatInputController : Object {
chat_input.initialize_for_conversation(conversation);
chat_text_view_controller.initialize_for_conversation(conversation);
+
+ Xmpp.Jid? own_jid = stream_interactor.get_module(MucManager.IDENTITY).get_own_jid(conversation.counterpart, conversation.account);
+
+ update_moderated_input_status(conversation.account, own_jid);
}
public void set_file_upload_active(bool active) {
@@ -69,6 +85,10 @@ public class ChatInputController : Object {
input_field_status = status;
chat_input.set_input_state(status.message_type);
+
+ if (status.contains_markup) status_description_label.use_markup = true;
+ else status_description_label.use_markup = false;
+
status_description_label.label = status.message;
chat_input.file_button.sensitive = status.input_state == Plugins.InputFieldStatus.InputState.NORMAL;
@@ -147,6 +167,19 @@ public class ChatInputController : Object {
stream_interactor.get_module(ChatInteraction.IDENTITY).on_message_cleared(conversation);
}
}
+
+ private void update_moderated_input_status(Account account, Xmpp.Jid jid) {
+ Xmpp.Jid? own_jid = stream_interactor.get_module(MucManager.IDENTITY).get_own_jid(conversation.counterpart, conversation.account);
+ if (conversation.type_ == conversation.Type.GROUPCHAT){
+ if (stream_interactor.get_module(MucManager.IDENTITY).is_moderated_room(conversation.account, conversation.counterpart) &&
+ stream_interactor.get_module(MucManager.IDENTITY).get_role(own_jid, conversation.account)==Xmpp.Xep.Muc.Role.VISITOR) {
+ set_input_field_status(new Plugins.InputFieldStatus(_("This conference does not allow you to send messages. %s").printf("<a href=\"" + OPEN_CONVERSATION_DETAILS_URI + "\">" + _("Request permission") + "</a>"),
+ Plugins.InputFieldStatus.MessageType.ERROR, Plugins.InputFieldStatus.InputState.NO_SEND, true));
+ } else {
+ reset_input_field_status();
+ }
+ }
+ }
private bool on_text_input_key_press(EventKey event) {
if (event.keyval == Gdk.Key.Up && chat_input.chat_text_view.text_view.buffer.text == "") {
diff --git a/main/src/ui/contact_details/dialog.vala b/main/src/ui/contact_details/dialog.vala
index ba9213a8..cf85e691 100644
--- a/main/src/ui/contact_details/dialog.vala
+++ b/main/src/ui/contact_details/dialog.vala
@@ -46,6 +46,7 @@ public class Dialog : Gtk.Dialog {
app.plugin_registry.register_contact_details_entry(new SettingsProvider(stream_interactor));
app.plugin_registry.register_contact_details_entry(new BlockingProvider(stream_interactor));
app.plugin_registry.register_contact_details_entry(new MucConfigFormProvider(stream_interactor));
+ app.plugin_registry.register_contact_details_entry(new PermissionsProvider(stream_interactor));
foreach (Plugins.ContactDetailsProvider provider in app.plugin_registry.contact_details_entries) {
provider.populate(conversation, contact_details, Plugins.WidgetType.GTK);
diff --git a/main/src/ui/contact_details/permissions_provider.vala b/main/src/ui/contact_details/permissions_provider.vala
new file mode 100644
index 00000000..1a8649a8
--- /dev/null
+++ b/main/src/ui/contact_details/permissions_provider.vala
@@ -0,0 +1,29 @@
+using Gtk;
+
+using Dino.Entities;
+
+namespace Dino.Ui.ContactDetails {
+
+public class PermissionsProvider : Plugins.ContactDetailsProvider, Object {
+ public string id { get { return "permissions"; } }
+
+ private StreamInteractor stream_interactor;
+
+ public PermissionsProvider(StreamInteractor stream_interactor) {
+ this.stream_interactor = stream_interactor;
+ }
+
+ public void populate(Conversation conversation, Plugins.ContactDetails contact_details, Plugins.WidgetType type) {
+ if (type != Plugins.WidgetType.GTK) return;
+
+ Xmpp.Jid? own_jid = stream_interactor.get_module(MucManager.IDENTITY).get_own_jid(conversation.counterpart, conversation.account);
+ if (stream_interactor.get_module(MucManager.IDENTITY).get_role(own_jid, conversation.account)==Xmpp.Xep.Muc.Role.VISITOR){
+ Button voice_request = new Button() {visible=true, label=_("Request")};
+ voice_request.clicked.connect(()=>stream_interactor.get_module(MucManager.IDENTITY).request_voice(conversation.account, conversation.counterpart));
+ contact_details.add(_("Permissions"), _("Request permission to send messages"), "", voice_request);
+
+ }
+ }
+}
+
+}
diff --git a/main/src/ui/contact_details/settings_provider.vala b/main/src/ui/contact_details/settings_provider.vala
index adc2e371..262029a2 100644
--- a/main/src/ui/contact_details/settings_provider.vala
+++ b/main/src/ui/contact_details/settings_provider.vala
@@ -45,6 +45,7 @@ public class SettingsProvider : Plugins.ContactDetailsProvider, Object {
combobox.append("on", get_notify_setting_string(Conversation.NotifySetting.ON));
combobox.append("off", get_notify_setting_string(Conversation.NotifySetting.OFF));
contact_details.add(DETAILS_HEADLINE_ROOM, _("Notifications"), "", combobox);
+
combobox.active_id = get_notify_setting_id(conversation.notify_setting);
combobox.changed.connect(() => { conversation.notify_setting = get_notify_setting(combobox.active_id); } );
}
diff --git a/main/src/ui/notifications.vala b/main/src/ui/notifications.vala
index 7b45a46e..dc73bda5 100644
--- a/main/src/ui/notifications.vala
+++ b/main/src/ui/notifications.vala
@@ -43,6 +43,7 @@ public class Notifications : Object {
stream_interactor.get_module(NotificationEvents.IDENTITY).notify_subscription_request.connect(notify_subscription_request);
stream_interactor.get_module(NotificationEvents.IDENTITY).notify_connection_error.connect(notify_connection_error);
stream_interactor.get_module(NotificationEvents.IDENTITY).notify_muc_invite.connect(on_invite_received);
+ stream_interactor.get_module(NotificationEvents.IDENTITY).notify_voice_request.connect(on_voice_request_received);
}
private async void notify_content_item(ContentItem content_item, Conversation conversation) {
@@ -140,6 +141,28 @@ public class Notifications : Object {
notification.add_button_with_target_value(_("Accept"), "app.open-muc-join", group_conversation.id);
GLib.Application.get_default().send_notification(null, notification);
}
+
+ private async void on_voice_request_received(Account account, Jid room_jid, Jid from_jid, string? nick, string? role, string? label) {
+ Conversation? direct_conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation(room_jid, account, Conversation.Type.GROUPCHAT);
+ if (direct_conversation == null) return;
+ string display_name = Util.get_participant_display_name(stream_interactor, direct_conversation, from_jid);
+ string display_room = room_jid.bare_jid.to_string();
+ Notification notification = new Notification(_("Permission request"));
+ string body = _("%s requests the permission to write in %s").printf(display_name, display_room);
+ notification.set_body(body);
+
+ try {
+ Cairo.ImageSurface jid_avatar = (yield Util.get_conversation_avatar_drawer(stream_interactor, direct_conversation)).size(40, 40).draw_image_surface();
+ notification.set_icon(get_pixbuf_icon(jid_avatar));
+ } catch (Error e) { }
+
+ Conversation group_conversation = stream_interactor.get_module(ConversationManager.IDENTITY).create_conversation(room_jid, account, Conversation.Type.GROUPCHAT);
+ group_conversation.nickname = nick;
+ notification.set_default_action_and_target_value("app.accept-voice-request", new Variant.int32(group_conversation.id));
+ notification.add_button_with_target_value(_("Deny"), "app.deny-voice-request", group_conversation.id);
+ notification.add_button_with_target_value(_("Accept"), "app.accept-voice-request", group_conversation.id);
+ GLib.Application.get_default().send_notification(null, notification);
+ }
private Icon get_pixbuf_icon(Cairo.ImageSurface surface) throws Error {
Gdk.Pixbuf avatar = Gdk.pixbuf_get_from_surface(surface, 0, 0, surface.get_width(), surface.get_height());
diff --git a/main/src/ui/occupant_menu/view.vala b/main/src/ui/occupant_menu/view.vala
index 958a4aa3..a512ff24 100644
--- a/main/src/ui/occupant_menu/view.vala
+++ b/main/src/ui/occupant_menu/view.vala
@@ -97,6 +97,21 @@ public class View : Popover {
outer_box.add(kick_button);
kick_button.clicked.connect(kick_button_clicked);
}
+ if (stream_interactor.get_module(MucManager.IDENTITY).is_moderated_room(conversation.account, conversation.counterpart) && role == Xmpp.Xep.Muc.Role.MODERATOR){
+ if (stream_interactor.get_module(MucManager.IDENTITY).get_role(selected_jid, conversation.account) == Xmpp.Xep.Muc.Role.VISITOR) {
+ ModelButton voice_button = new ModelButton() { active=true, text=_("Grant write permission"), visible=true };
+ outer_box.add(voice_button);
+ voice_button.clicked.connect(() =>
+ voice_button_clicked("participant"));
+ }
+ else if (stream_interactor.get_module(MucManager.IDENTITY).get_role(selected_jid, conversation.account) == Xmpp.Xep.Muc.Role.PARTICIPANT){
+ ModelButton voice_button = new ModelButton() { active=true, text=_("Revoke write permission"), visible=true };
+ outer_box.add(voice_button);
+ voice_button.clicked.connect(() =>
+ voice_button_clicked("visitor"));
+ }
+
+ }
if (jid_menu != null) jid_menu.destroy();
stack.add_named(outer_box, "menu");
@@ -119,6 +134,12 @@ public class View : Popover {
stream_interactor.get_module(MucManager.IDENTITY).kick(conversation.account, conversation.counterpart, selected_jid.resourcepart);
}
+
+ private void voice_button_clicked(string role) {
+ if (selected_jid == null) return;
+
+ stream_interactor.get_module(MucManager.IDENTITY).change_role(conversation.account, conversation.counterpart, selected_jid.resourcepart, role);
+ }
}
}