[polari] Add support for pasting image to public image service
- From: Kunal Jain <kunaljain src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [polari] Add support for pasting image to public image service
- Date: Thu, 11 Feb 2016 18:36:06 +0000 (UTC)
commit e5c418909d8e5fe49f0ba5ab60def7f2d71f4ae1
Author: Kunaal Jain <kunaalus gmail com>
Date: Thu Feb 11 09:46:32 2016 +0530
Add support for pasting image to public image service
Support pasting images in polari by uploading them
to public image service (currently Imgur).
https://bugzilla.gnome.org/show_bug.cgi?id=760346
src/application.js | 3 +++
src/entryArea.js | 24 +++++++++++++++++++++++-
src/pasteManager.js | 44 ++++++++++++++++++++++++++++++++++++++++++++
src/utils.js | 38 +++++++++++++++++++++++++++++++++++++-
4 files changed, 107 insertions(+), 2 deletions(-)
---
diff --git a/src/application.js b/src/application.js
index b0ca0cf..a1e50d6 100644
--- a/src/application.js
+++ b/src/application.js
@@ -385,6 +385,9 @@ const Application = new Lang.Class({
let text = data.toString();
this.pasteManager.pasteText(text);
break;
+ case PasteManager.DndTargetType.IMAGE:
+ this.pasteManager.pasteImage(data);
+ break;
default:
log('Unhandled paste content of type %d'.format(type));
}
diff --git a/src/entryArea.js b/src/entryArea.js
index dff3187..320750f 100644
--- a/src/entryArea.js
+++ b/src/entryArea.js
@@ -1,4 +1,5 @@
const Gdk = imports.gi.Gdk;
+const GdkPixbuf = imports.gi.GdkPixbuf;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
@@ -19,7 +20,8 @@ const ChatEntry = new Lang.Class({
Name: 'ChatEntry',
Extends: Gtk.Entry,
Signals: { 'text-pasted': { param_types: [GObject.TYPE_STRING,
- GObject.TYPE_INT] } },
+ GObject.TYPE_INT] },
+ 'image-pasted': { param_types: [GdkPixbuf.Pixbuf.$gtype] } },
_init: function(params) {
this.parent(params);
@@ -50,6 +52,13 @@ const ChatEntry = new Lang.Class({
this.emit('paste-clipboard');
this._useDefaultHandler = false;
}));
+
+ clipboard.request_image(Lang.bind(this,
+ function(clipboard, pixbuf) {
+ if (pixbuf == null)
+ return;
+ this.emit('image-pasted', pixbuf);
+ }));
},
});
@@ -105,6 +114,7 @@ const EntryArea = new Lang.Class({
this._nickPopover.set_default_widget(this._changeButton);
this._chatEntry.connect('text-pasted', Lang.bind(this, this._onTextPasted));
+ this._chatEntry.connect('image-pasted', Lang.bind(this, this._onImagePasted));
this._chatEntry.connect('changed', Lang.bind(this, this._onEntryChanged));
this._chatEntry.connect('activate', Lang.bind(this,
@@ -215,6 +225,18 @@ const EntryArea = new Lang.Class({
this._pasteButton.grab_focus();
},
+ _onImagePasted: function(entry, data) {
+ this._multiLineLabel.label = _("Upload image to public paste service?");
+
+ let [success, buffer] = data.save_to_bufferv('png',[],[]);
+ if (!success)
+ return;
+
+ this._pasteButton.action_target = new GLib.Variant('(ayi)', [buffer,
PasteManager.DndTargetType.IMAGE]);
+ this.visible_child_name = 'multiline';
+ this._pasteButton.grab_focus();
+ },
+
_onButtonClicked: function() {
this._chatEntry.text = '';
this.visible_child_name = 'default';
diff --git a/src/pasteManager.js b/src/pasteManager.js
index cccd048..2b02080 100644
--- a/src/pasteManager.js
+++ b/src/pasteManager.js
@@ -81,6 +81,14 @@ const PasteManager = new Lang.Class({
this._pasteText(text, n);
},
+ pasteImage: function(data) {
+ let app = Gio.Application.get_default();
+ let n = new UploadNotification("image");
+ app.notificationQueue.addNotification(n);
+
+ this._pasteImage(data, n);
+ },
+
_pasteText: function(text, notification) {
let room = this._roomManager.getActiveRoom();
if (!room) {
@@ -120,6 +128,42 @@ const PasteManager = new Lang.Class({
}));
},
+ _pasteImage: function(data, notification) {
+ let room = this._roomManager.getActiveRoom();
+ if (!room) {
+ notification.close();
+ return;
+ }
+
+ let title;
+ let nick = room.channel.connection.self_contact.alias;
+ if (room.type == Tp.HandleType.ROOM)
+ /* translators: %s is a nick, #%s a channel */
+ title = _("%s in #%s").format(nick, room.display_name);
+ else
+ title = _("Paste from %s").format(nick);
+
+ Utils.imgurPaste(data, title, Lang.bind(this,
+ function(url) {
+ if (!url) {
+ notification.close();
+ return;
+ }
+
+ let type = Tp.ChannelTextMessageType.NORMAL;
+ let message = Tp.ClientMessage.new_text(type, url);
+ room.channel.send_message_async(message, 0, Lang.bind(this,
+ function(c, res) {
+ try {
+ c.send_message_finish(res);
+ } catch(e) {
+ logError(e, 'Failed to send message')
+ }
+ notification.close();
+ }));
+ }));
+ },
+
_onDragDrop: function(widget, context, x, y, time) {
if (!Polari.drag_dest_supports_target(widget, context, null))
return Gdk.EVENT_PROPAGATE;
diff --git a/src/utils.js b/src/utils.js
index e9643b8..6d8dea7 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -36,7 +36,9 @@ const SECRET_SCHEMA = new Secret.Schema(
{ 'account-id': Secret.SchemaAttributeType.STRING }
);
-const GPASTE_BASEURL = 'https://paste.gnome.org/'
+const GPASTE_BASEURL = 'https://paste.gnome.org/';
+
+const IMGUR_CLIENT_ID = '4109e59177ec95e';
// http://daringfireball.net/2010/07/improved_regex_for_matching_urls
const _balancedParens = '\\((?:[^\\s()<>]+|(?:\\(?:[^\\s()<>]+\\)))*\\)';
@@ -204,3 +206,37 @@ function gpaste(text, title, callback) {
callback(null);
});
}
+
+function imgurPaste(data, title, callback) {
+ let base64EncodedBuffer = GLib.base64_encode(data);
+
+ let params = {
+ title: title,
+ image: base64EncodedBuffer
+ };
+
+ let session = new Soup.Session();
+ let createUrl = 'https://api.imgur.com/3/image';
+ let message = Soup.form_request_new_from_hash('POST', createUrl, params);
+
+ let requestHeaders = message.request_headers;
+ requestHeaders.append('Authorization', 'Client-ID ' + IMGUR_CLIENT_ID);
+ session.queue_message(message,
+ function(session, message) {
+ if (message.status_code != Soup.KnownStatusCode.OK) {
+ callback(null);
+ return;
+ }
+
+ let info = {};
+ try {
+ info = JSON.parse(message.response_body.data);
+ } catch(e) {
+ log(e.message);
+ }
+ if (info.success)
+ callback(info.data.link);
+ else
+ callback(null);
+ });
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]