diff options
Diffstat (limited to 'main/src/ui/chat_input')
-rw-r--r-- | main/src/ui/chat_input/chat_input_controller.vala | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/main/src/ui/chat_input/chat_input_controller.vala b/main/src/ui/chat_input/chat_input_controller.vala new file mode 100644 index 00000000..59a2abb4 --- /dev/null +++ b/main/src/ui/chat_input/chat_input_controller.vala @@ -0,0 +1,150 @@ +using Gee; +using Gdk; +using Gtk; + +using Dino.Entities; + +namespace Dino.Ui { + +public class ChatInputController : Object { + + public new string? conversation_display_name { get; set; } + public string? conversation_topic { get; set; } + + private Conversation? conversation; + private ChatInput.View chat_input; + private Label status_description_label; + + private StreamInteractor stream_interactor; + private Plugins.InputFieldStatus input_field_status; + + public ChatInputController(ChatInput.View chat_input, StreamInteractor stream_interactor) { + this.chat_input = chat_input; + this.status_description_label = chat_input.chat_input_status; + this.stream_interactor = stream_interactor; + + chat_input.init(stream_interactor); + + reset_input_field_status(); + + chat_input.text_input.buffer.changed.connect(on_text_input_changed); + chat_input.send_text.connect(send_text); + + chat_input.encryption_widget.encryption_changed.connect(on_encryption_changed); + + stream_interactor.get_module(FileManager.IDENTITY).upload_available.connect(on_upload_available); + } + + + + public void set_conversation(Conversation conversation) { + this.conversation = conversation; + + reset_input_field_status(); + + chat_input.initialize_for_conversation(conversation); + chat_input.occupants_tab_completor.initialize_for_conversation(conversation); + chat_input.edit_history.initialize_for_conversation(conversation); + chat_input.encryption_widget.set_conversation(conversation); + } + + private void on_encryption_changed(Plugins.EncryptionListEntry? encryption_entry) { + reset_input_field_status(); + + if (encryption_entry == null) return; + + encryption_entry.encryption_activated(conversation, set_input_field_status); + } + + private void set_input_field_status(Plugins.InputFieldStatus? status) { + input_field_status = status; + + chat_input.set_input_state(status.message_type); + status_description_label.label = status.message; + + chat_input.file_button.sensitive = status.input_state == Plugins.InputFieldStatus.InputState.NORMAL; + } + + private void reset_input_field_status() { + set_input_field_status(new Plugins.InputFieldStatus("", Plugins.InputFieldStatus.MessageType.NONE, Plugins.InputFieldStatus.InputState.NORMAL)); + } + + private void on_upload_available(Account account) { + if (conversation != null && conversation.account.equals(account)) { + chat_input.file_button.visible = true; + chat_input.file_separator.visible = true; + } + } + + private void send_text() { + // Don't do anything if we're in a NO_SEND state. Don't clear the chat input, don't send. + if (input_field_status.input_state == Plugins.InputFieldStatus.InputState.NO_SEND) { + chat_input.highlight_state_description(); + return; + } + + string text = chat_input.text_input.buffer.text; + chat_input.text_input.buffer.text = ""; + if (text.has_prefix("/")) { + string[] token = text.split(" ", 2); + switch(token[0]) { + case "/me": + // Just send as is. + break; + case "/say": + if (token.length == 1) return; + text = token[1]; + break; + case "/kick": + stream_interactor.get_module(MucManager.IDENTITY).kick(conversation.account, conversation.counterpart, token[1]); + return; + case "/affiliate": + if (token.length > 1) { + string[] user_role = token[1].split(" ", 2); + if (user_role.length == 2) { + stream_interactor.get_module(MucManager.IDENTITY).change_affiliation(conversation.account, conversation.counterpart, user_role[0].strip(), user_role[1].strip()); + } + } + return; + case "/nick": + stream_interactor.get_module(MucManager.IDENTITY).change_nick(conversation.account, conversation.counterpart, token[1]); + return; + case "/ping": + Xmpp.XmppStream? stream = stream_interactor.get_stream(conversation.account); + try { + stream.get_module(Xmpp.Xep.Ping.Module.IDENTITY).send_ping(stream, conversation.counterpart.with_resource(token[1]), null); + } catch (Xmpp.InvalidJidError e) { + warning("Could not ping invalid Jid: %s", e.message); + } + return; + case "/topic": + stream_interactor.get_module(MucManager.IDENTITY).change_subject(conversation.account, conversation.counterpart, token[1]); + return; + default: + if (token[0].has_prefix("//")) { + text = text.substring(1); + } else { + string cmd_name = token[0].substring(1); + Dino.Application app = GLib.Application.get_default() as Dino.Application; + if (app != null && app.plugin_registry.text_commands.has_key(cmd_name)) { + string? new_text = app.plugin_registry.text_commands[cmd_name].handle_command(token[1], conversation); + if (new_text == null) return; + text = (!)new_text; + } + } + break; + } + } + stream_interactor.get_module(MessageProcessor.IDENTITY).send_text(text, conversation); + } + + private void on_text_input_changed() { + if (chat_input.text_input.buffer.text != "") { + stream_interactor.get_module(ChatInteraction.IDENTITY).on_message_entered(conversation); + } else { + stream_interactor.get_module(ChatInteraction.IDENTITY).on_message_cleared(conversation); + } + } +} + +} |