Commit b3e66ee0 authored by Alexander's avatar Alexander

[stickers] Various UI improvements

- Add a button to open the plugin's data directory
- Add a button to allow manually uploading sticker packs
- Force the Popovers to update when a sticker pack is uploaded
parent a43c6f87
......@@ -18,9 +18,18 @@
from collections import namedtuple
Sticker = namedtuple('Sticker', ['type', 'hashes', 'size', 'dimension', 'desc', 'suggests', 'filename', 'url', 'pixbuf'])
StickerPack = namedtuple('StickerPack', ['id_', 'hash', 'name', 'summary', 'stickers'])
_StickerPack = namedtuple('StickerPack', ['id_', 'hash', 'name', 'summary', 'stickers'])
Hash = namedtuple('Hash', ['algo', 'value'])
class StickerPack(_StickerPack):
@property
def uploaded(self):
'''
True, when all stickers have an URL, meaning we can use it without
having to upload it ourselves.
'''
return all([x.url for x in self.stickers])
def parse_hashes(hashes):
'''
Turn an array of {'algo': ..., 'value': ...} hash descriptions into
......
......@@ -20,16 +20,20 @@ from gi.repository import Gio
from gi.repository import GObject
from gajim.common.i18n import _
from gajim.common.helpers import open_file
from gajim.plugins.gui import GajimPluginConfigDialog
from gajim.plugins.helpers import get_builder
from gajim.gui.dialogs import ConfirmationDialog
from gajim.gui.dialogs import DialogButton
from stickers.utils import sticker_data_path
class StickerPackObject(GObject.GObject):
def __init__(self, name, summary, amount, id_):
def __init__(self, name, summary, amount, uploaded, id_):
self._name = name
self._summary = summary
self._amount = amount
self._uploaded = uploaded
self._id = id_
GObject.GObject.__init__(self)
......@@ -46,6 +50,10 @@ class StickerPackObject(GObject.GObject):
def amount(self):
return self._amount
@property
def uploaded(self):
return self._uploaded
@property
def id_(self):
return self._id
......@@ -65,6 +73,7 @@ class StickersConfigDialog(GajimPluginConfigDialog):
self._ui.sticker_packs_list.bind_model(self._list_model, self._create_sticker_pack_row)
self._ui.reload_sticker_packs.connect('clicked', self.on_sticker_packs_reload_clicked)
self._ui.sticker_packs_location_button.connect('clicked', lambda x: open_file(sticker_data_path()))
def set_wrapper(setting):
return lambda widget: self._on_setting_changed(widget, setting)
......@@ -84,6 +93,7 @@ class StickersConfigDialog(GajimPluginConfigDialog):
self._list_model.append(StickerPackObject(pack.name,
pack.summary,
len(pack.stickers),
pack.uploaded,
pack.id_))
def on_sticker_pack_removed(self, pack):
......@@ -126,6 +136,9 @@ class StickersConfigDialog(GajimPluginConfigDialog):
DialogButton.make('Remove',
callback=delete_sticker_pack)]).show()
def _on_upload_button_clicked(self, id_):
self.plugin.upload_sticker_pack(id_)
def _create_sticker_pack_row(self, pack):
item = get_builder(self.plugin.local_file_path('gtk/config_stickers_listitem.ui'))
# TODO: If available, display the localized version of the sticker pack's
......@@ -135,4 +148,9 @@ class StickersConfigDialog(GajimPluginConfigDialog):
item.amount.set_text(_('%s stickers') % pack.amount)
item.delete_button.connect('clicked', lambda x: self._on_delete_button_clicked(pack.id_))
if pack.uploaded:
item.upload_button.destroy()
else:
item.upload_button.connect('clicked', lambda x: self._on_upload_button_clicked(pack.id_))
return item.sticker_pack_list_item
......@@ -25,21 +25,59 @@
</packing>
</child>
<child>
<object class="GtkButton" id="reload_sticker_packs">
<!-- n-columns=3 n-rows=1 -->
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="halign">end</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<child>
<object class="GtkImage">
<object class="GtkButton" id="reload_sticker_packs">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Reload sticker packs</property>
<property name="stock">gtk-refresh</property>
<property name="halign">end</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<property name="hexpand">False</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="stock">gtk-refresh</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">2</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="sticker_packs_location_button">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Open Sticker Pack Location</property>
<property name="halign">end</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<property name="hexpand">True</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="stock">gtk-open</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
......
......@@ -2,7 +2,7 @@
<!-- Generated with glade 3.38.2 -->
<interface>
<requires lib="gtk+" version="3.24"/>
<!-- n-columns=2 n-rows=1 -->
<!-- n-columns=3 n-rows=1 -->
<object class="GtkGrid" id="sticker_pack_list_item">
<property name="visible">True</property>
<property name="can-focus">False</property>
......@@ -62,6 +62,7 @@
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Delete Sticker Pack</property>
<property name="halign">end</property>
<property name="valign">center</property>
<property name="margin-end">12</property>
......@@ -82,6 +83,44 @@
</packing>
</child>
</object>
<packing>
<property name="left-attach">2</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="vexpand">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkButton" id="upload_button">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Upload Sticker Pack</property>
<property name="halign">end</property>
<property name="valign">center</property>
<property name="margin-right">12</property>
<property name="margin-end">12</property>
<property name="always-show-image">True</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="stock">gtk-add</property>
<property name="icon_size">1</property>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
......
......@@ -106,7 +106,7 @@ def write_sticker_pack_info(pack):
}
with open(sticker_path(pack.id_, 'info.json'), 'w') as file_:
file_.write(json.dumps(obj))
file_.write(json.dumps(obj, indent=4))
def load_sticker_pixbuf(sticker_filename, pack_id, type_, preferred_width, show_animations):
'''
......@@ -252,7 +252,11 @@ class StickersPlugin(GajimPlugin):
This is just so we're able to cache the uploaded URL once a sticker
pack has been fully uploaded.
'''
write_sticker_pack_info(self.sticker_packs[event.id_])
pack = self.sticker_packs[event.id_]
write_sticker_pack_info(pack)
self.config_dialog.on_sticker_pack_removed(pack)
self.config_dialog.on_sticker_pack_added(pack)
self.__update_buttons()
def _on_signed_in(self, event):
if not self.config['UPLOAD_NEW_SIGNIN'] and not self.config['DOWNLOAD_NEW_SIGNIN']:
......@@ -287,6 +291,7 @@ class StickersPlugin(GajimPlugin):
for sticker_pack in self.sticker_packs.values():
self.config_dialog.on_sticker_pack_removed(sticker_pack)
self._load_sticker_packs()
self.__update_buttons()
def _load_sticker_packs(self):
path = sticker_data_path()
......@@ -361,6 +366,33 @@ class StickersPlugin(GajimPlugin):
mention.end)
del self.sticker_mentions[pack.id_]
def upload_sticker_pack(self, pack_id, on_use=False):
'''
Asks the user if the sticker pack should be uploaded.
pack_id: The ID of the sticker pack in question
on_use: Whether this function is called from the context of the attempt
to send a sticker (True).
'''
def on_confirm():
log.debug('Manually uploading sticker pack %s', pack_id)
pack = self.sticker_packs[pack_id]
for account in app.connections:
app.connections[account].get_module('Stickers').publish_pack(pack, upload=True)
if on_use:
text = _('Sending this sticker requires the upload of the sticker pack. Are you sure you want to upload the sticker pack?')
else:
text = _('Are you sure you want to upload the sticker pack?')
ConfirmationDialog(
_('Upload Sticker Pack'),
text,
_('This will also publish the sticker pack on your account(s).'),
[DialogButton.make('Cancel'),
DialogButton.make('Accept',
callback=on_confirm)]).show()
def delete_sticker_pack(self, id_):
'''
Starts the process to remove sticker packs from both
......@@ -491,7 +523,7 @@ class StickersPlugin(GajimPlugin):
pack = self.sticker_packs[local_id]
log.debug('Uploading pack %s', local_id)
# Don't upload files if all stickers already have a URL
upload = not all([x.url for x in pack.stickers])
upload = not pack.uploaded
log.debug('Uploading via HTTP Upload: %s', upload)
app.connections[event.account].get_module('Stickers').publish_pack(pack, upload=upload)
......@@ -676,6 +708,7 @@ class StickersPlugin(GajimPlugin):
chat_type,
self.sticker_packs.values(),
self.local_file_path,
self.upload_sticker_pack,
self._button_icon_pixbuf)
self.controls[control.control_id] = btn
actions_hbox = control.xml.get_object('hbox')
......@@ -690,7 +723,7 @@ class StickersPlugin(GajimPlugin):
self.controls.pop(control.control_id, None)
class StickersButton(Gtk.Button):
def __init__(self, conn, contact, chat_control, chat_type, sticker_packs, local_file_path, icon_pixbuf):
def __init__(self, conn, contact, chat_control, chat_type, sticker_packs, local_file_path, upload_sticker_pack, icon_pixbuf):
Gtk.Button.__init__(self)
icon = Gtk.Image.new_from_pixbuf(icon_pixbuf)
self.set_image(icon)
......@@ -704,6 +737,7 @@ class StickersButton(Gtk.Button):
self._popover = None
self._sticker_packs = sticker_packs
self._local_file_path = local_file_path
self._upload_sticker_pack = upload_sticker_pack
self._query = ''
self._create_popover()
......@@ -734,7 +768,8 @@ class StickersButton(Gtk.Button):
box.set_relief(Gtk.ReliefStyle.NONE)
box.connect('clicked',
self._send_sticker_lambda(sticker,
sticker_pack.id_))
sticker_pack.id_,
sticker_pack.uploaded))
# NOTE: We do this so we can later in the filter function check
# if a given query matches the specific sticker
......@@ -805,13 +840,17 @@ class StickersButton(Gtk.Button):
return True
return False
def _send_sticker_lambda(self, sticker, pack_id):
def _send_sticker_lambda(self, sticker, pack_id, uploaded):
'''
To prevent weirdness, create a lambda to perform
the actual sending.
'''
def actually_send_sticker(argument):
# pylint: disable=unused-argument
if not uploaded:
self._upload_sticker_pack(pack_id, on_use=True)
return
self._popover.popdown()
self._send_sticker(sticker, pack_id)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment