| ... |
... |
@@ -18,6 +18,8 @@ |
|
18
|
18
|
from typing import cast
|
|
19
|
19
|
from typing import Optional
|
|
20
|
20
|
|
|
|
21
|
+import logging
|
|
|
22
|
+
|
|
21
|
23
|
from gi.repository import Gdk
|
|
22
|
24
|
from gi.repository import Gio
|
|
23
|
25
|
from gi.repository import GLib
|
| ... |
... |
@@ -35,6 +37,8 @@ |
|
35
|
37
|
EMOJI_NUM_GENDERS = len(['f', 'm', 'n'])
|
|
36
|
38
|
MENUS_MAX_ENTRIES = 2 * EMOJI_NUM_GENDERS
|
|
37
|
39
|
|
|
|
40
|
+log = logging.getLogger('gajim.gtk.chat_action_processor')
|
|
|
41
|
+
|
|
38
|
42
|
|
|
39
|
43
|
class ChatActionProcessor(Gtk.Popover):
|
|
40
|
44
|
def __init__(self, message_input: Gtk.TextView) -> None:
|
| ... |
... |
@@ -249,21 +253,34 @@ def _update_emoji_menu(self, |
|
249
|
253
|
self._menu.remove_all()
|
|
250
|
254
|
emoji_data = get_emoji_data()
|
|
251
|
255
|
|
|
|
256
|
+ sn_matches: dict[str, str] = {}
|
|
|
257
|
+ kw_matches: dict[str, str] = {}
|
|
|
258
|
+
|
|
252
|
259
|
for keyword, entries in emoji_data.items():
|
|
253
|
|
- for short_name in entries:
|
|
254
|
|
- if not keyword.startswith(action_text):
|
|
255
|
|
- continue
|
|
256
|
|
- emoji = entries[short_name]
|
|
|
260
|
+ if not keyword.startswith(action_text):
|
|
|
261
|
+ continue
|
|
|
262
|
+ for short_name, emoji in entries.items():
|
|
257
|
263
|
label = f'{emoji} {short_name}'
|
|
258
|
|
- if keyword != short_name:
|
|
259
|
|
- label += f' [{keyword}]'
|
|
260
|
|
- action_data = GLib.Variant('s', emoji)
|
|
261
|
|
- menu_item = Gio.MenuItem()
|
|
262
|
|
- menu_item.set_label(escape_mnemonic(label))
|
|
263
|
|
- menu_item.set_attribute_value('action-data', action_data)
|
|
264
|
|
- self._menu.append_item(menu_item)
|
|
265
|
|
- if self._menu.get_n_items() >= MENUS_MAX_ENTRIES:
|
|
266
|
|
- break
|
|
|
264
|
+ if keyword == short_name:
|
|
|
265
|
+ # Replace a possible keyword match with the shortname match:
|
|
|
266
|
+ sn_matches[emoji] = label
|
|
|
267
|
+ if kw_matches.get(emoji) is not None:
|
|
|
268
|
+ del kw_matches[emoji]
|
|
|
269
|
+ else:
|
|
|
270
|
+ # Only add a keyword match if no shortname match:
|
|
|
271
|
+ if sn_matches.get(emoji) is None:
|
|
|
272
|
+ kw_matches[emoji] = f'{label} [{keyword}]'
|
|
|
273
|
+
|
|
|
274
|
+ log.debug('Found %d "%s…" emoji by short name, %d more by keyword',
|
|
|
275
|
+ len(sn_matches), action_text, len(kw_matches))
|
|
|
276
|
+
|
|
|
277
|
+ # Put all shortname matches before keyword matches:
|
|
|
278
|
+ for emoji, label in list(sn_matches.items()) + list(kw_matches.items()):
|
|
|
279
|
+ action_data = GLib.Variant('s', emoji)
|
|
|
280
|
+ menu_item = Gio.MenuItem()
|
|
|
281
|
+ menu_item.set_label(escape_mnemonic(label))
|
|
|
282
|
+ menu_item.set_attribute_value('action-data', action_data)
|
|
|
283
|
+ self._menu.append_item(menu_item)
|
|
267
|
284
|
if self._menu.get_n_items() >= MENUS_MAX_ENTRIES:
|
|
268
|
285
|
break
|
|
269
|
286
|
|