Daniel Brötzmann pushed to branch mainwindow at gajim / gajim
Commits: 9544d729 by wurstsalat at 2021-11-01T19:58:59+01:00 FileTransferJingleRow: Display receiver/sender meta data
- - - - - febe5721 by wurstsalat at 2021-11-01T22:26:30+01:00 CallRow: Display receiver/sender meta data
- - - - - ad5cf996 by wurstsalat at 2021-11-01T23:00:25+01:00 ChatList: Handle incoming calls and jingle file transfer requests
- - - - -
9 changed files:
- gajim/data/style/default.css - gajim/data/style/gajim.css - gajim/gtk/call_widget.py - gajim/gtk/chat_list.py - gajim/gtk/chat_list_stack.py - gajim/gtk/controls/chat.py - gajim/gtk/conversation/rows/call.py - gajim/gtk/conversation/rows/file_transfer_jingle.py - gajim/gtk/conversation/view.py
Changes:
===================================== gajim/data/style/default.css ===================================== @@ -16,8 +16,8 @@ .gajim-subject-message { background: rgb(225, 235, 250); } .gajim-call-message { - color: rgb(40, 70, 100); - background: rgb(225, 235, 250); + color: rgb(70, 70, 70); + background: rgb(230, 230, 230); } .gajim-command-error { background-color: rgb(10, 50, 70);
===================================== gajim/data/style/gajim.css ===================================== @@ -86,6 +86,9 @@ .conversation-call-box { border-radius: 6px; padding: 12px; } +.conversation-call-box label { + font-size: small; +} .conversation-meta { color: @insensitive_fg_color; font-size: small;
===================================== gajim/gtk/call_widget.py ===================================== @@ -309,7 +309,7 @@ def accept_call(self, session): if video is not None: session.approve_content('video')
- def reject_call(self, session): + def decline_call(self, session): if not session: return
===================================== gajim/gtk/chat_list.py ===================================== @@ -15,6 +15,7 @@ import logging import time
+from gi.repository import Gio from gi.repository import Gdk from gi.repository import GLib from gi.repository import Gtk @@ -319,6 +320,10 @@ def process_event(self, event): self._on_presence_received(event) elif event.name == 'message-sent': self._on_message_sent(event) + elif event.name == 'jingle-request-received': + self._on_jingle_request_received(event) + elif event.name == 'file-request-received': + self._on_file_request_received(event) else: log.warning('Unhandled Event: %s', event.name)
@@ -332,7 +337,8 @@ def _on_message_received(self, event): row.set_timestamp(event.properties.mam.timestamp) else: row.set_timestamp(event.properties.timestamp) - row.set_message_text(event.msgtxt, event.additional_data) + row.set_message_text( + event.msgtxt, additional_data=event.additional_data) self._add_unread(row, event.properties) self.invalidate_sort()
@@ -353,7 +359,8 @@ def _on_message_sent(self, event):
# Set timestamp if it's None (outgoing MUC messages) row.set_timestamp(event.timestamp or time.time()) - row.set_message_text(event.message, event.additional_data) + row.set_message_text( + event.message, additional_data=event.additional_data) self.invalidate_sort()
@staticmethod @@ -376,6 +383,25 @@ def _on_presence_received(self, event): row = self._chats.get((event.account, event.jid)) row.update_avatar()
+ def _on_jingle_request_received(self, event): + content_types = [] + for item in event.contents: + content_types.append(item.media) + if 'audio' in content_types or 'video' in content_types: + # AV Call received + row = self._chats.get((event.account, event.jid)) + row.set_timestamp(time.time()) + row.set_nick('') + row.set_message_text( + _('Call'), icon_name='call-start-symbolic') + + def _on_file_request_received(self, event): + row = self._chats.get((event.account, event.jid)) + row.set_timestamp(time.time()) + row.set_nick('') + row.set_message_text( + _('File'), icon_name='text-x-generic-symbolic') + @staticmethod def _add_unread(row, properties): if properties.is_carbon_message and properties.carbon.is_sent: @@ -445,7 +471,8 @@ def __init__(self, workspace_id, account, jid, type_, pinned): return
if line.message is not None: - self.set_message_text(line.message, line.additional_data) + self.set_message_text( + line.message, additional_data=line.additional_data) if line.kind in (KindConstant.CHAT_MSG_SENT, KindConstant.SINGLE_MSG_SENT): self._ui.nick_label.set_text(_('Me:')) @@ -466,14 +493,16 @@ def __init__(self, workspace_id, account, jid, type_, pinned):
if line.kind in (KindConstant.FILE_TRANSFER_INCOMING, KindConstant.FILE_TRANSFER_OUTGOING): - self._ui.message_label.set_text(_('File Transfer')) + self.set_message_text( + _('File'), icon_name='text-x-generic-symbolic') self.timestamp = line.time uf_timestamp = get_uf_relative_time(line.time) self._ui.timestamp_label.set_text(uf_timestamp)
if line.kind in (KindConstant.CALL_INCOMING, KindConstant.CALL_OUTGOING): - self._ui.message_label.set_text(_('Call')) + self.set_message_text( + _('Call'), icon_name='call-start-symbolic') self.timestamp = line.time uf_timestamp = get_uf_relative_time(line.time) self._ui.timestamp_label.set_text(uf_timestamp) @@ -629,14 +658,18 @@ def set_nick(self, nickname): self._ui.nick_label.set_visible(bool(nickname)) self._ui.nick_label.set_text(nickname)
- def set_message_text(self, text, additional_data): + def set_message_text(self, text, icon_name=None, additional_data=None): icon = None - if app.interface.preview_manager.get_previewable(text, additional_data): - file_name = filename_from_uri(text) - icon, file_type = guess_simple_file_type(text) - text = '%(file_type)s (%(file_name)s)' % { - 'file_type': file_type, - 'file_name': file_name} + if icon_name is not None: + icon = Gio.Icon.new_for_string(icon_name) + if additional_data is not None: + if app.interface.preview_manager.get_previewable( + text, additional_data): + file_name = filename_from_uri(text) + icon, file_type = guess_simple_file_type(text) + text = '%(file_type)s (%(file_name)s)' % { + 'file_type': file_type, + 'file_name': file_name} else: text = text.replace('\n', ' ') self._ui.message_label.set_text(text)
===================================== gajim/gtk/chat_list_stack.py ===================================== @@ -31,6 +31,8 @@ 'presence-received', 'message-sent', 'chatstate-received', + 'jingle-request-received', + 'file-request-received' ]
===================================== gajim/gtk/controls/chat.py ===================================== @@ -106,7 +106,7 @@ def __init__(self, account, jid): self.xml.paned1.add2(self._call_widget)
self.conversation_view.connect('accept-call', self._on_accept_call) - self.conversation_view.connect('reject-call', self._on_reject_call) + self.conversation_view.connect('decline-call', self._on_decline_call)
# Menu for the HeaderBar self.control_menu = gui_menu_builder.get_singlechat_menu( @@ -491,8 +491,8 @@ def _process_jingle_av_event(self, event): def _on_accept_call(self, _view, session): self._call_widget.accept_call(session)
- def _on_reject_call(self, _view, session): - self._call_widget.reject_call(session) + def _on_decline_call(self, _view, session): + self._call_widget.decline_call(session)
def _on_call_ended(self, _call_widget): self.conversation_view.update_call_rows()
===================================== gajim/gtk/conversation/rows/call.py ===================================== @@ -19,6 +19,7 @@
from gajim.common import app from gajim.common.const import AvatarSize +from gajim.common.const import KindConstant from gajim.common.i18n import _
from .widgets import SimpleLabel @@ -44,6 +45,7 @@ def __init__(self, account, contact, event=None, db_message=None):
self._contact = contact self._event = event + self._db_message = db_message self._session = None
if is_from_db: @@ -51,21 +53,14 @@ def __init__(self, account, contact, event=None, db_message=None): module = self._client.get_module('Jingle') self._session = module.get_jingle_session(self._contact.jid, sid)
- avatar_placeholder = Gtk.Box() - avatar_placeholder.set_size_request(AvatarSize.ROSTER, -1) - self.grid.attach(avatar_placeholder, 0, 0, 1, 1) + self._avatar_placeholder = Gtk.Box() + self._avatar_placeholder.set_size_request(AvatarSize.ROSTER, -1) + self.grid.attach(self._avatar_placeholder, 0, 0, 1, 1)
if event is None and self._session is None: - icon = Gtk.Image.new_from_icon_name('call-start-symbolic', - Gtk.IconSize.MENU) - self.grid.attach(icon, 1, 0, 1, 1) - - label = SimpleLabel() - label.get_style_context().add_class('dim-label') - label.set_text(_('Call')) - self.grid.attach(label, 2, 0, 1, 1) + self._add_history_call_widget() else: - self._prepare_incoming_call() + self._add_incoming_call_widget()
timestamp_widget = self.create_timestamp_widget(self.timestamp) timestamp_widget.set_hexpand(True) @@ -80,22 +75,14 @@ def update(self): return
self._call_box.destroy() + self._add_history_call_widget()
- icon = Gtk.Image.new_from_icon_name('call-start-symbolic', - Gtk.IconSize.MENU) - self.grid.attach(icon, 1, 0, 1, 1) - - label = SimpleLabel() - label.get_style_context().add_class('dim-label') - label.set_text(_('Call')) - self.grid.attach(label, 2, 0, 1, 1) - self.show_all() self._event = None self._session = None
def _on_accept(self, button): button.set_sensitive(False) - self._reject_button.set_sensitive(False) + self._decline_button.set_sensitive(False) if self._event is not None: session = self._client.get_module('Jingle').get_jingle_session( self._event.fjid, self._event.sid) @@ -103,18 +90,58 @@ def _on_accept(self, button): else: self.get_parent().accept_call(self._session)
- def _on_reject(self, button): - button.set_sensitive(False) - self._accept_button.set_sensitive(False) + def _on_decline(self, button): if self._event is not None: session = self._client.get_module('Jingle').get_jingle_session( self._event.fjid, self._event.sid) - self.get_parent().reject_call(session) + self.get_parent().decline_call(session) else: - self.get_parent().reject_call(self._session) + self.get_parent().decline_call(self._session) self._session = None
- def _prepare_incoming_call(self): + def _add_history_call_widget(self): + if self._db_message is not None: + if self._db_message.kind == KindConstant.CALL_INCOMING: + contact = self._contact + is_self = True + else: + contact = self._client.get_module('Contacts').get_contact( + str(self._client.get_own_jid().bare)) + is_self = False + + if self._event is not None: + if self._event == 'incoming-call': + contact = self._client.get_module('Contacts').get_contact( + str(self._client.get_own_jid().bare)) + is_self = False + else: + contact = self._contact + is_self = True + + scale = self.get_scale_factor() + avatar = contact.get_avatar(AvatarSize.ROSTER, scale, add_show=False) + avatar_image = Gtk.Image.new_from_surface(avatar) + self._avatar_placeholder.add(avatar_image) + + name_widget = self.create_name_widget(contact.name, is_self) + name_widget.set_halign(Gtk.Align.START) + name_widget.set_valign(Gtk.Align.START) + self.grid.attach(name_widget, 1, 0, 1, 1) + + icon = Gtk.Image.new_from_icon_name('call-start-symbolic', + Gtk.IconSize.MENU) + + label = SimpleLabel() + label.get_style_context().add_class('dim-label') + label.set_text(_('Call')) + + content_box = Gtk.Box(spacing=12) + content_box.add(icon) + content_box.add(label) + self.grid.attach(content_box, 1, 1, 1, 1) + self.show_all() + + def _add_incoming_call_widget(self): self._call_box = Gtk.Box( orientation=Gtk.Orientation.VERTICAL, spacing=6) self._call_box.set_size_request(350, -1) @@ -150,17 +177,38 @@ def _prepare_incoming_call(self): label.set_line_wrap(True) self._call_box.add(label)
- self._accept_button = Gtk.Button.new_with_label(_('Accept Call')) - self._accept_button.get_style_context().add_class('suggested-action') + self._decline_button = Gtk.Button() + if self._session is not None: + self._decline_button.set_sensitive(not self._session.accepted) + self._decline_button.get_style_context().add_class( + 'destructive-action') + self._decline_button.connect('clicked', self._on_decline) + decline_icon = Gtk.Image.new_from_icon_name( + 'call-stop-symbolic', Gtk.IconSize.DND) + self._decline_button.add(decline_icon) + decline_label = Gtk.Label(label=_('Decline')) + decline_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=3) + decline_box.add(self._decline_button) + decline_box.add(decline_label) + + self._accept_button = Gtk.Button() + if self._session is not None: + self._accept_button.set_sensitive(not self._session.accepted) + self._accept_button.get_style_context().add_class( + 'suggested-action') self._accept_button.connect('clicked', self._on_accept) - - self._reject_button = Gtk.Button.new_with_label(_('Reject')) - self._reject_button.connect('clicked', self._on_reject) - - button_box = Gtk.Box(spacing=12) + accept_icon = Gtk.Image.new_from_icon_name( + 'call-start-symbolic', Gtk.IconSize.DND) + self._accept_button.add(accept_icon) + accept_label = Gtk.Label(label=_('Accept')) + accept_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=3) + accept_box.add(self._accept_button) + accept_box.add(accept_label) + + button_box = Gtk.Box(spacing=50) button_box.set_halign(Gtk.Align.CENTER) - button_box.add(self._reject_button) - button_box.add(self._accept_button) + button_box.add(decline_box) + button_box.add(accept_box) self._call_box.add(button_box)
self.grid.attach(self._call_box, 1, 0, 1, 1)
===================================== gajim/gtk/conversation/rows/file_transfer_jingle.py ===================================== @@ -23,6 +23,7 @@ from gajim.common import app from gajim.common import ged from gajim.common.const import AvatarSize +from gajim.common.const import KindConstant from gajim.common.file_props import FilesProp from gajim.common.helpers import open_file from gajim.common.i18n import _ @@ -67,8 +68,36 @@ def __init__(self, account, contact, event=None, db_message=None):
avatar_placeholder = Gtk.Box() avatar_placeholder.set_size_request(AvatarSize.ROSTER, -1) + avatar_placeholder.set_valign(Gtk.Align.START) self.grid.attach(avatar_placeholder, 0, 0, 1, 1)
+ if is_from_db: + if db_message.kind == KindConstant.FILE_TRANSFER_INCOMING: + contact = self._contact + is_self = True + else: + contact = self._client.get_module('Contacts').get_contact( + str(self._client.get_own_jid().bare)) + is_self = False + else: + if event.name == 'file-request-sent': + contact = self._client.get_module('Contacts').get_contact( + str(self._client.get_own_jid().bare)) + is_self = False + else: + contact = self._contact + is_self = True + + scale = self.get_scale_factor() + avatar = contact.get_avatar(AvatarSize.ROSTER, scale, add_show=False) + avatar_image = Gtk.Image.new_from_surface(avatar) + avatar_placeholder.add(avatar_image) + + name_widget = self.create_name_widget(contact.name, is_self) + name_widget.set_halign(Gtk.Align.START) + name_widget.set_valign(Gtk.Align.START) + self.grid.attach(name_widget, 1, 0, 1, 1) + timestamp_widget = self.create_timestamp_widget(self.timestamp) timestamp_widget.set_hexpand(True) timestamp_widget.set_halign(Gtk.Align.END) @@ -76,7 +105,7 @@ def __init__(self, account, contact, event=None, db_message=None): self.grid.attach(timestamp_widget, 2, 0, 1, 1)
self._ui = get_builder('file_transfer_jingle.ui') - self.grid.attach(self._ui.transfer_box, 1, 0, 1, 1) + self.grid.attach(self._ui.transfer_box, 1, 1, 1, 1)
self._ui.connect_signals(self)
===================================== gajim/gtk/conversation/view.py ===================================== @@ -60,7 +60,7 @@ class ConversationView(Gtk.ListBox): None, (object, ) ), - 'reject-call': ( + 'decline-call': ( GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, (object, ) @@ -468,8 +468,8 @@ def on_mention(self, name): def accept_call(self, event): self.emit('accept-call', event)
- def reject_call(self, event): - self.emit('reject-call', event) + def decline_call(self, event): + self.emit('decline-call', event)
def _on_contact_setting_changed(self, *args): self.invalidate_filter()
View it on GitLab: https://dev.gajim.org/gajim/gajim/-/compare/07a13025a8787ed23c283c80870bfa06...