// SPDX-FileCopyrightText: GSConnect Developers https://github.com/GSConnect // // SPDX-License-Identifier: GPL-2.0-or-later import Gio from 'gi://Gio'; import GObject from 'gi://GObject'; import Gtk from 'gi://Gtk'; import * as Contacts from '../ui/contacts.js'; import * as Messaging from '../ui/messaging.js'; import * as URI from '../utils/uri.js'; import '../utils/ui.js'; const Dialog = GObject.registerClass({ GTypeName: 'GSConnectLegacyMessagingDialog', Properties: { 'device': GObject.ParamSpec.object( 'device', 'Device', 'The device associated with this window', GObject.ParamFlags.READWRITE, GObject.Object ), 'plugin': GObject.ParamSpec.object( 'plugin', 'Plugin', 'The plugin providing messages', GObject.ParamFlags.READWRITE, GObject.Object ), }, Template: 'resource:///org/gnome/Shell/Extensions/GSConnect/ui/legacy-messaging-dialog.ui', Children: [ 'infobar', 'stack', 'message-box', 'message-avatar', 'message-label', 'entry', ], }, class Dialog extends Gtk.Dialog { _init(params) { super._init({ application: Gio.Application.get_default(), device: params.device, plugin: params.plugin, use_header_bar: true, }); this.set_response_sensitive(Gtk.ResponseType.OK, false); // Dup some functions this.headerbar = this.get_titlebar(); this._setHeaderBar = Messaging.Window.prototype._setHeaderBar; // Info bar this.device.bind_property( 'connected', this.infobar, 'reveal-child', GObject.BindingFlags.INVERT_BOOLEAN ); // Message Entry/Send Button this.device.bind_property( 'connected', this.entry, 'sensitive', GObject.BindingFlags.DEFAULT ); this._connectedId = this.device.connect( 'notify::connected', this._onStateChanged.bind(this) ); this._entryChangedId = this.entry.buffer.connect( 'changed', this._onStateChanged.bind(this) ); // Set the message if given if (params.message) { this.message = params.message; this.addresses = params.message.addresses; this.message_avatar.contact = this.device.contacts.query({ number: this.addresses[0].address, }); this.message_label.label = URI.linkify(this.message.body); this.message_box.visible = true; // Otherwise set the address(es) if we were passed those } else if (params.addresses) { this.addresses = params.addresses; } // Load the contact list if we weren't supplied with an address if (this.addresses.length === 0) { this.contact_chooser = new Contacts.ContactChooser({ device: this.device, }); this.stack.add_named(this.contact_chooser, 'contact-chooser'); this.stack.child_set_property(this.contact_chooser, 'position', 0); this._numberSelectedId = this.contact_chooser.connect( 'number-selected', this._onNumberSelected.bind(this) ); this.stack.visible_child_name = 'contact-chooser'; } this.restoreGeometry('legacy-messaging-dialog'); this.connect('destroy', this._onDestroy); } _onDestroy(dialog) { if (dialog._numberSelectedId !== undefined) { dialog.contact_chooser.disconnect(dialog._numberSelectedId); dialog.contact_chooser.destroy(); } dialog.entry.buffer.disconnect(dialog._entryChangedId); dialog.device.disconnect(dialog._connectedId); } vfunc_delete_event() { this.saveGeometry(); return false; } vfunc_response(response_id) { if (response_id === Gtk.ResponseType.OK) { // Refuse to send empty or whitespace only texts if (!this.entry.buffer.text.trim()) return; this.plugin.sendMessage( this.addresses, this.entry.buffer.text, 1, true ); } this.destroy(); } get addresses() { if (this._addresses === undefined) this._addresses = []; return this._addresses; } set addresses(addresses = []) { this._addresses = addresses; // Set the headerbar this._setHeaderBar(this._addresses); // Show the message editor this.stack.visible_child_name = 'message-editor'; this._onStateChanged(); } get device() { if (this._device === undefined) this._device = null; return this._device; } set device(device) { this._device = device; } get plugin() { if (this._plugin === undefined) this._plugin = null; return this._plugin; } set plugin(plugin) { this._plugin = plugin; } _onActivateLink(label, uri) { Gtk.show_uri_on_window( this.get_toplevel(), uri.includes('://') ? uri : `https://${uri}`, Gtk.get_current_event_time() ); return true; } _onNumberSelected(chooser, number) { const contacts = chooser.getSelected(); this.addresses = Object.keys(contacts).map(address => { return {address: address}; }); } _onStateChanged() { if (this.device.connected && this.entry.buffer.text.trim() && this.stack.visible_child_name === 'message-editor') this.set_response_sensitive(Gtk.ResponseType.OK, true); else this.set_response_sensitive(Gtk.ResponseType.OK, false); } /** * Set the contents of the message entry * * @param {string} text - The message to place in the entry */ setMessage(text) { this.entry.buffer.text = text; } }); export default Dialog;