228 lines
6.1 KiB
JavaScript
228 lines
6.1 KiB
JavaScript
|
// 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;
|