Mercurial > libervia-desktop-kivy
annotate cagou/plugins/plugin_wid_chat.py @ 425:13884aac1220
chat: show images in attachments:
- if an image is received from somebody in roster, it is automatically displayed (we
display only for people in roster to avoid IP address leak)
- encrypted files are decrypted and stored in cache before being displayed
- GIFs image are shown as attachment because they are badly handle in Kivy (images
frequencies is not handled correctly, and memory consumption explode). Instead, a click
on it will open the GIF in the appropriate software of the platform.
- a click on an attachment image will open it in the gallery
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 26 Feb 2020 16:47:39 +0100 |
parents | 8a9bfe3fb9c6 |
children | d3a6ae859556 |
rev | line source |
---|---|
379 | 1 #!/usr/bin/env python3 |
22 | 2 |
3 # Cagou: desktop/mobile frontend for Salut à Toi XMPP client | |
378 | 4 # Copyright (C) 2016-2020 Jérôme Poisson (goffi@goffi.org) |
22 | 5 |
6 # This program is free software: you can redistribute it and/or modify | |
7 # it under the terms of the GNU Affero General Public License as published by | |
8 # the Free Software Foundation, either version 3 of the License, or | |
9 # (at your option) any later version. | |
10 | |
11 # This program is distributed in the hope that it will be useful, | |
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 # GNU Affero General Public License for more details. | |
15 | |
16 # You should have received a copy of the GNU Affero General Public License | |
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 | |
19 | |
276 | 20 from functools import partial |
412 | 21 from pathlib import Path |
276 | 22 import sys |
412 | 23 import uuid |
425 | 24 from urllib.parse import urlparse |
78 | 25 from kivy.uix.boxlayout import BoxLayout |
22 | 26 from kivy.uix.textinput import TextInput |
354 | 27 from kivy.uix.screenmanager import Screen, NoTransition |
28 from kivy.uix import screenmanager | |
367
abb57182ebfb
chat: prepend nick to message input when occupant avatar is touched on group chat.
Goffi <goffi@goffi.org>
parents:
357
diff
changeset
|
29 from kivy.uix.behaviors import ButtonBehavior |
185
ab3f5173ef5c
chat, simple XHTML: font size adjustement
Goffi <goffi@goffi.org>
parents:
184
diff
changeset
|
30 from kivy.metrics import sp, dp |
276 | 31 from kivy.clock import Clock |
22 | 32 from kivy import properties |
411
b018386653c2
chat: work around ScrollView bug in attachments by using a StackLayout instead:
Goffi <goffi@goffi.org>
parents:
409
diff
changeset
|
33 from kivy.uix.stacklayout import StackLayout |
325 | 34 from kivy.uix.dropdown import DropDown |
35 from kivy.core.window import Window | |
36 from sat.core import log as logging | |
37 from sat.core.i18n import _ | |
38 from sat.core import exceptions | |
333
69d2a96ce26f
chat: serialise `options` in `fileUpload` following change in backend
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
39 from sat.tools.common import data_format |
22 | 40 from sat_frontends.quick_frontend import quick_widgets |
41 from sat_frontends.quick_frontend import quick_chat | |
106
9909ed7a7a20
moved SimpleXHTMLWidget to a dedicated module
Goffi <goffi@goffi.org>
parents:
105
diff
changeset
|
42 from sat_frontends.tools import jid |
325 | 43 from cagou import G |
404
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
44 from ..core.constants import Const as C |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
45 from ..core import cagou_widget |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
46 from ..core import xmlui |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
47 from ..core.image import Image |
425 | 48 from ..core.common import SymbolButton, JidButton, ContactButton |
404
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
49 from ..core.behaviors import FilterBehavior |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
50 from ..core import menu |
425 | 51 from ..core.common_widgets import ImagesGallery |
22 | 52 |
276 | 53 log = logging.getLogger(__name__) |
22 | 54 |
55 PLUGIN_INFO = { | |
312 | 56 "name": _("chat"), |
22 | 57 "main": "Chat", |
312 | 58 "description": _("instant messaging with one person or a group"), |
59 "icon_symbol": "chat", | |
22 | 60 } |
61 | |
244
5bd94bc08f5c
plugin chat: fixed OTR State filtering + removed some legacy code
Goffi <goffi@goffi.org>
parents:
242
diff
changeset
|
62 # FIXME: OTR specific code is legacy, and only used nowadays for lock color |
5bd94bc08f5c
plugin chat: fixed OTR State filtering + removed some legacy code
Goffi <goffi@goffi.org>
parents:
242
diff
changeset
|
63 # we can probably get rid of them. |
122
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
64 OTR_STATE_UNTRUSTED = 'untrusted' |
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
65 OTR_STATE_TRUSTED = 'trusted' |
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
66 OTR_STATE_TRUST = (OTR_STATE_UNTRUSTED, OTR_STATE_TRUSTED) |
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
67 OTR_STATE_UNENCRYPTED = 'unencrypted' |
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
68 OTR_STATE_ENCRYPTED = 'encrypted' |
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
69 OTR_STATE_ENCRYPTION = (OTR_STATE_UNENCRYPTED, OTR_STATE_ENCRYPTED) |
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
70 |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
71 SYMBOL_UNENCRYPTED = 'lock-open' |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
72 SYMBOL_ENCRYPTED = 'lock' |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
73 SYMBOL_ENCRYPTED_TRUSTED = 'lock-filled' |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
74 COLOR_UNENCRYPTED = (0.4, 0.4, 0.4, 1) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
75 COLOR_ENCRYPTED = (0.4, 0.4, 0.4, 1) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
76 COLOR_ENCRYPTED_TRUSTED = (0.29,0.87,0.0,1) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
77 |
326 | 78 # below this limit, new messages will be prepended |
79 INFINITE_SCROLL_LIMIT = dp(600) | |
80 | |
412 | 81 # File sending progress |
82 PROGRESS_UPDATE = 0.2 # number of seconds before next progress update | |
83 | |
22 | 84 |
411
b018386653c2
chat: work around ScrollView bug in attachments by using a StackLayout instead:
Goffi <goffi@goffi.org>
parents:
409
diff
changeset
|
85 # FIXME: a ScrollLayout was supposed to be used here, but due |
b018386653c2
chat: work around ScrollView bug in attachments by using a StackLayout instead:
Goffi <goffi@goffi.org>
parents:
409
diff
changeset
|
86 # to https://github.com/kivy/kivy/issues/6745, a StackLayout is used for now |
b018386653c2
chat: work around ScrollView bug in attachments by using a StackLayout instead:
Goffi <goffi@goffi.org>
parents:
409
diff
changeset
|
87 class AttachmentsLayout(StackLayout): |
412 | 88 """Layout for attachments in a received message""" |
89 padding = properties.VariableListProperty([dp(5), dp(5), 0, dp(5)]) | |
90 attachments = properties.ObjectProperty() | |
91 | |
92 | |
93 class AttachmentsToSend(BoxLayout): | |
94 """Layout for attachments to be sent with current message""" | |
409
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
95 attachments = properties.ObjectProperty() |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
96 |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
97 |
425 | 98 class BaseAttachmentItem(BoxLayout): |
409
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
99 data = properties.DictProperty() |
412 | 100 progress = properties.NumericProperty(0) |
409
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
101 |
425 | 102 |
103 class AttachmentItem(BaseAttachmentItem): | |
104 | |
409
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
105 def get_symbol(self, data): |
418
8a9bfe3fb9c6
chat: use constant instead of hard-coded string for C.MESS_KEY_MEDIA_TYPE
Goffi <goffi@goffi.org>
parents:
417
diff
changeset
|
106 media_type = data.get(C.MESS_KEY_MEDIA_TYPE, '') |
409
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
107 main_type = media_type.split('/', 1)[0] |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
108 if main_type == 'image': |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
109 return "file-image" |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
110 elif main_type == 'video': |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
111 return "file-video" |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
112 elif main_type == 'audio': |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
113 return "file-audio" |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
114 else: |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
115 return "doc" |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
116 |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
117 def on_press(self): |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
118 url = self.data.get('url') |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
119 if url: |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
120 G.local_platform.open_url(url, self) |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
121 else: |
412 | 122 log.warning(f"can't find URL in {self.data}") |
123 | |
124 | |
425 | 125 class AttachmentImageItem(ButtonBehavior, BaseAttachmentItem): |
126 image = properties.ObjectProperty() | |
127 | |
128 def on_press(self): | |
129 gallery = ImagesGallery(sources=[self.image.source]) | |
130 G.host.showExtraUI(gallery) | |
131 | |
132 | |
412 | 133 class AttachmentToSendItem(AttachmentItem): |
134 # True when the item is being sent | |
135 sending = properties.BooleanProperty(False) | |
409
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
136 |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
137 |
367
abb57182ebfb
chat: prepend nick to message input when occupant avatar is touched on group chat.
Goffi <goffi@goffi.org>
parents:
357
diff
changeset
|
138 class MessAvatar(ButtonBehavior, Image): |
44
7819e9efa250
chat: avatar and nick are now displayed, need further aesthetic improvments
Goffi <goffi@goffi.org>
parents:
42
diff
changeset
|
139 pass |
7819e9efa250
chat: avatar and nick are now displayed, need further aesthetic improvments
Goffi <goffi@goffi.org>
parents:
42
diff
changeset
|
140 |
7819e9efa250
chat: avatar and nick are now displayed, need further aesthetic improvments
Goffi <goffi@goffi.org>
parents:
42
diff
changeset
|
141 |
325 | 142 class MessageWidget(quick_chat.MessageWidget, BoxLayout): |
22 | 143 mess_data = properties.ObjectProperty() |
57 | 144 mess_xhtml = properties.ObjectProperty() |
45 | 145 mess_padding = (dp(5), dp(5)) |
47
abb81efef3bb
chat: update avatar following quick frontend improvments
Goffi <goffi@goffi.org>
parents:
46
diff
changeset
|
146 avatar = properties.ObjectProperty() |
103
c601e3d40342
chat: display delivery receipt (with a green check mark)
Goffi <goffi@goffi.org>
parents:
102
diff
changeset
|
147 delivery = properties.ObjectProperty() |
185
ab3f5173ef5c
chat, simple XHTML: font size adjustement
Goffi <goffi@goffi.org>
parents:
184
diff
changeset
|
148 font_size = properties.NumericProperty(sp(12)) |
325 | 149 right_part = properties.ObjectProperty() |
150 header_box = properties.ObjectProperty() | |
47
abb81efef3bb
chat: update avatar following quick frontend improvments
Goffi <goffi@goffi.org>
parents:
46
diff
changeset
|
151 |
409
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
152 def on_kv_post(self, __): |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
153 if not self.mess_data: |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
154 raise exceptions.InternalError( |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
155 "mess_data must always be set in MessageWidget") |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
156 |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
157 self.mess_data.widgets.add(self) |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
158 self.add_attachments() |
44
7819e9efa250
chat: avatar and nick are now displayed, need further aesthetic improvments
Goffi <goffi@goffi.org>
parents:
42
diff
changeset
|
159 |
7819e9efa250
chat: avatar and nick are now displayed, need further aesthetic improvments
Goffi <goffi@goffi.org>
parents:
42
diff
changeset
|
160 @property |
7819e9efa250
chat: avatar and nick are now displayed, need further aesthetic improvments
Goffi <goffi@goffi.org>
parents:
42
diff
changeset
|
161 def chat(self): |
7819e9efa250
chat: avatar and nick are now displayed, need further aesthetic improvments
Goffi <goffi@goffi.org>
parents:
42
diff
changeset
|
162 """return parent Chat instance""" |
7819e9efa250
chat: avatar and nick are now displayed, need further aesthetic improvments
Goffi <goffi@goffi.org>
parents:
42
diff
changeset
|
163 return self.mess_data.parent |
22 | 164 |
325 | 165 def _get_from_mess_data(self, name, default): |
166 if self.mess_data is None: | |
167 return default | |
168 return getattr(self.mess_data, name) | |
169 | |
289
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
170 def _get_message(self): |
22 | 171 """Return currently displayed message""" |
325 | 172 if self.mess_data is None: |
173 return "" | |
22 | 174 return self.mess_data.main_message |
175 | |
289
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
176 def _set_message(self, message): |
325 | 177 if self.mess_data is None: |
178 return False | |
312 | 179 if message == self.mess_data.message.get(""): |
289
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
180 return False |
312 | 181 self.mess_data.message = {"": message} |
289
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
182 return True |
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
183 |
325 | 184 message = properties.AliasProperty( |
185 partial(_get_from_mess_data, name="main_message", default=""), | |
186 _set_message, | |
187 bind=['mess_data'], | |
188 ) | |
189 message_xhtml = properties.AliasProperty( | |
190 partial(_get_from_mess_data, name="main_message_xhtml", default=""), | |
191 bind=['mess_data']) | |
192 mess_type = properties.AliasProperty( | |
193 partial(_get_from_mess_data, name="type", default=""), bind=['mess_data']) | |
194 own_mess = properties.AliasProperty( | |
195 partial(_get_from_mess_data, name="own_mess", default=False), bind=['mess_data']) | |
196 nick = properties.AliasProperty( | |
197 partial(_get_from_mess_data, name="nick", default=""), bind=['mess_data']) | |
198 time_text = properties.AliasProperty( | |
199 partial(_get_from_mess_data, name="time_text", default=""), bind=['mess_data']) | |
57 | 200 |
289
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
201 @property |
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
202 def info_type(self): |
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
203 return self.mess_data.info_type |
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
204 |
54
514c187afebc
chat: changed udpate to use dict instead of single key/value
Goffi <goffi@goffi.org>
parents:
47
diff
changeset
|
205 def update(self, update_dict): |
514c187afebc
chat: changed udpate to use dict instead of single key/value
Goffi <goffi@goffi.org>
parents:
47
diff
changeset
|
206 if 'avatar' in update_dict: |
514c187afebc
chat: changed udpate to use dict instead of single key/value
Goffi <goffi@goffi.org>
parents:
47
diff
changeset
|
207 self.avatar.source = update_dict['avatar'] |
103
c601e3d40342
chat: display delivery receipt (with a green check mark)
Goffi <goffi@goffi.org>
parents:
102
diff
changeset
|
208 if 'status' in update_dict: |
c601e3d40342
chat: display delivery receipt (with a green check mark)
Goffi <goffi@goffi.org>
parents:
102
diff
changeset
|
209 status = update_dict['status'] |
312 | 210 self.delivery.text = '\u2714' if status == 'delivered' else '' |
47
abb81efef3bb
chat: update avatar following quick frontend improvments
Goffi <goffi@goffi.org>
parents:
46
diff
changeset
|
211 |
425 | 212 def _setPath(self, item, path): |
213 """Set path of decrypted file to an item""" | |
214 item.data['path'] = path | |
215 | |
409
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
216 def add_attachments(self): |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
217 """Add attachments layout + attachments item""" |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
218 attachments = self.mess_data.attachments |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
219 if not attachments: |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
220 return |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
221 root_layout = AttachmentsLayout() |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
222 self.right_part.add_widget(root_layout) |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
223 layout = root_layout.attachments |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
224 for attachment in attachments: |
425 | 225 media_type = attachment.get(C.MESS_KEY_MEDIA_TYPE, '') |
226 main_type = media_type.split('/', 1)[0] | |
227 if ((main_type == 'image' | |
228 # GIF images are really badly handled by Kivy, the | |
229 # memory consumption explode, and the images frequencies | |
230 # are not handled correctly, thus we can't display them | |
231 # and user will have to open the item. | |
232 and media_type != "image/gif" | |
233 and (self.mess_data.own_mess or self.chat.contact_list.isInRoster( | |
234 self.mess_data.from_jid)))): | |
235 url = urlparse(attachment['url']) | |
236 if url.scheme == "aesgcm": | |
237 # we remove the URL now, we'll replace it by | |
238 # the local decrypted version | |
239 del attachment['url'] | |
240 item = AttachmentImageItem(data=attachment) | |
241 G.host.downloadURL( | |
242 url.geturl(), | |
243 callback=partial(self._setPath, item), | |
244 dest=C.FILE_DEST_CACHE, | |
245 profile=self.chat.profile, | |
246 ) | |
247 else: | |
248 item = AttachmentImageItem(data=attachment) | |
249 else: | |
250 item = AttachmentItem(data=attachment) | |
409
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
251 layout.add_widget(item) |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
252 |
22 | 253 |
78 | 254 class MessageInputBox(BoxLayout): |
276 | 255 message_input = properties.ObjectProperty() |
256 | |
257 def send_text(self): | |
258 self.message_input.send_text() | |
78 | 259 |
260 | |
22 | 261 class MessageInputWidget(TextInput): |
262 | |
276 | 263 def keyboard_on_key_down(self, window, keycode, text, modifiers): |
264 # We don't send text when shift is pressed to be able to add line feeds | |
265 # (i.e. multi-lines messages). We don't send on Android either as the | |
266 # send button appears on this platform. | |
267 if (keycode[-1] == "enter" | |
268 and "shift" not in modifiers | |
269 and sys.platform != 'android'): | |
270 self.send_text() | |
22 | 271 else: |
276 | 272 return super(MessageInputWidget, self).keyboard_on_key_down( |
273 window, keycode, text, modifiers) | |
274 | |
275 def send_text(self): | |
276 self.dispatch('on_text_validate') | |
22 | 277 |
278 | |
278
444ba439530f
chat: moved transfer button to header_box
Goffi <goffi@goffi.org>
parents:
277
diff
changeset
|
279 class TransferButton(SymbolButton): |
444ba439530f
chat: moved transfer button to header_box
Goffi <goffi@goffi.org>
parents:
277
diff
changeset
|
280 chat = properties.ObjectProperty() |
444ba439530f
chat: moved transfer button to header_box
Goffi <goffi@goffi.org>
parents:
277
diff
changeset
|
281 |
444ba439530f
chat: moved transfer button to header_box
Goffi <goffi@goffi.org>
parents:
277
diff
changeset
|
282 def on_release(self, *args): |
417
5b50b7ef2617
menu (TransferMenu): UI improvments:
Goffi <goffi@goffi.org>
parents:
414
diff
changeset
|
283 menu.TransferMenu( |
5b50b7ef2617
menu (TransferMenu): UI improvments:
Goffi <goffi@goffi.org>
parents:
414
diff
changeset
|
284 encrypted=self.chat.encrypted, |
5b50b7ef2617
menu (TransferMenu): UI improvments:
Goffi <goffi@goffi.org>
parents:
414
diff
changeset
|
285 callback=self.chat.transferFile, |
5b50b7ef2617
menu (TransferMenu): UI improvments:
Goffi <goffi@goffi.org>
parents:
414
diff
changeset
|
286 ).show(self) |
278
444ba439530f
chat: moved transfer button to header_box
Goffi <goffi@goffi.org>
parents:
277
diff
changeset
|
287 |
444ba439530f
chat: moved transfer button to header_box
Goffi <goffi@goffi.org>
parents:
277
diff
changeset
|
288 |
287
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
289 class ExtraMenu(DropDown): |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
290 chat = properties.ObjectProperty() |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
291 |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
292 def on_select(self, menu): |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
293 if menu == 'bookmark': |
312 | 294 G.host.bridge.menuLaunch(C.MENU_GLOBAL, ("groups", "bookmarks"), |
287
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
295 {}, C.NO_SECURITY_LIMIT, self.chat.profile, |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
296 callback=partial( |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
297 G.host.actionManager, profile=self.chat.profile), |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
298 errback=G.host.errback) |
393
e2f806779b53
chat: added a "close" item in menu, to leave MUC/close current chat widget.
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
299 elif menu == 'close': |
e2f806779b53
chat: added a "close" item in menu, to leave MUC/close current chat widget.
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
300 if self.chat.type == C.CHAT_GROUP: |
e2f806779b53
chat: added a "close" item in menu, to leave MUC/close current chat widget.
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
301 # for MUC, we have to indicate the backend that we've left |
e2f806779b53
chat: added a "close" item in menu, to leave MUC/close current chat widget.
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
302 G.host.bridge.mucLeave(self.chat.target, self.chat.profile) |
e2f806779b53
chat: added a "close" item in menu, to leave MUC/close current chat widget.
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
303 else: |
e2f806779b53
chat: added a "close" item in menu, to leave MUC/close current chat widget.
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
304 # for one2one, backend doesn't keep any state, so we just delete the |
e2f806779b53
chat: added a "close" item in menu, to leave MUC/close current chat widget.
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
305 # widget here in the frontend |
e2f806779b53
chat: added a "close" item in menu, to leave MUC/close current chat widget.
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
306 G.host.widgets.deleteWidget( |
e2f806779b53
chat: added a "close" item in menu, to leave MUC/close current chat widget.
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
307 self.chat, all_instances=True, explicit_close=True) |
287
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
308 else: |
312 | 309 raise exceptions.InternalError("Unknown menu: {}".format(menu)) |
287
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
310 |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
311 |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
312 class ExtraButton(SymbolButton): |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
313 chat = properties.ObjectProperty() |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
314 |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
315 |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
316 class EncryptionMainButton(SymbolButton): |
117 | 317 |
318 def __init__(self, chat, **kwargs): | |
319 """ | |
320 @param chat(Chat): Chat instance | |
321 """ | |
122
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
322 self.chat = chat |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
323 self.encryption_menu = EncryptionMenu(chat) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
324 super(EncryptionMainButton, self).__init__(**kwargs) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
325 self.bind(on_release=self.encryption_menu.open) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
326 |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
327 def selectAlgo(self, name): |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
328 """Mark an encryption algorithm as selected. |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
329 |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
330 This will also deselect all other button |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
331 @param name(unicode, None): encryption plugin name |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
332 None for plain text |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
333 """ |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
334 buttons = self.encryption_menu.container.children |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
335 buttons[-1].selected = name is None |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
336 for button in buttons[:-1]: |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
337 button.selected = button.text == name |
117 | 338 |
135
091e288838e1
plugin chat: use new Symbol widget to display encryption button
Goffi <goffi@goffi.org>
parents:
126
diff
changeset
|
339 def getColor(self): |
122
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
340 if self.chat.otr_state_encryption == OTR_STATE_UNENCRYPTED: |
135
091e288838e1
plugin chat: use new Symbol widget to display encryption button
Goffi <goffi@goffi.org>
parents:
126
diff
changeset
|
341 return (0.4, 0.4, 0.4, 1) |
091e288838e1
plugin chat: use new Symbol widget to display encryption button
Goffi <goffi@goffi.org>
parents:
126
diff
changeset
|
342 elif self.chat.otr_state_trust == OTR_STATE_TRUSTED: |
091e288838e1
plugin chat: use new Symbol widget to display encryption button
Goffi <goffi@goffi.org>
parents:
126
diff
changeset
|
343 return (0.29,0.87,0.0,1) |
122
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
344 else: |
135
091e288838e1
plugin chat: use new Symbol widget to display encryption button
Goffi <goffi@goffi.org>
parents:
126
diff
changeset
|
345 return (0.4, 0.4, 0.4, 1) |
122
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
346 |
135
091e288838e1
plugin chat: use new Symbol widget to display encryption button
Goffi <goffi@goffi.org>
parents:
126
diff
changeset
|
347 def getSymbol(self): |
091e288838e1
plugin chat: use new Symbol widget to display encryption button
Goffi <goffi@goffi.org>
parents:
126
diff
changeset
|
348 if self.chat.otr_state_encryption == OTR_STATE_UNENCRYPTED: |
091e288838e1
plugin chat: use new Symbol widget to display encryption button
Goffi <goffi@goffi.org>
parents:
126
diff
changeset
|
349 return 'lock-open' |
091e288838e1
plugin chat: use new Symbol widget to display encryption button
Goffi <goffi@goffi.org>
parents:
126
diff
changeset
|
350 elif self.chat.otr_state_trust == OTR_STATE_TRUSTED: |
091e288838e1
plugin chat: use new Symbol widget to display encryption button
Goffi <goffi@goffi.org>
parents:
126
diff
changeset
|
351 return 'lock-filled' |
091e288838e1
plugin chat: use new Symbol widget to display encryption button
Goffi <goffi@goffi.org>
parents:
126
diff
changeset
|
352 else: |
091e288838e1
plugin chat: use new Symbol widget to display encryption button
Goffi <goffi@goffi.org>
parents:
126
diff
changeset
|
353 return 'lock' |
122
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
354 |
117 | 355 |
242
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
356 class TrustManagementButton(SymbolButton): |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
357 pass |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
358 |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
359 |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
360 class EncryptionButton(BoxLayout): |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
361 selected = properties.BooleanProperty(False) |
242
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
362 text = properties.StringProperty() |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
363 trust_button = properties.BooleanProperty(False) |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
364 best_width = properties.NumericProperty(0) |
312 | 365 bold = properties.BooleanProperty(True) |
242
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
366 |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
367 def __init__(self, **kwargs): |
312 | 368 super(EncryptionButton, self).__init__(**kwargs) |
242
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
369 self.register_event_type('on_release') |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
370 self.register_event_type('on_trust_release') |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
371 if self.trust_button: |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
372 self.add_widget(TrustManagementButton()) |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
373 |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
374 def on_release(self): |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
375 pass |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
376 |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
377 def on_trust_release(self): |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
378 pass |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
379 |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
380 |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
381 class EncryptionMenu(DropDown): |
242
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
382 # best with to display all algorithms buttons + trust buttons |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
383 best_width = properties.NumericProperty(0) |
117 | 384 |
385 def __init__(self, chat, **kwargs): | |
386 """ | |
387 @param chat(Chat): Chat instance | |
388 """ | |
389 self.chat = chat | |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
390 super(EncryptionMenu, self).__init__(**kwargs) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
391 btn = EncryptionButton( |
312 | 392 text=_("unencrypted (plain text)"), |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
393 on_release=self.unencrypted, |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
394 selected=True, |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
395 bold=False, |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
396 ) |
332
13bc00b9743a
chat: use `bind` for EncryptionButton events:
Goffi <goffi@goffi.org>
parents:
329
diff
changeset
|
397 btn.bind( |
13bc00b9743a
chat: use `bind` for EncryptionButton events:
Goffi <goffi@goffi.org>
parents:
329
diff
changeset
|
398 on_release=self.unencrypted, |
13bc00b9743a
chat: use `bind` for EncryptionButton events:
Goffi <goffi@goffi.org>
parents:
329
diff
changeset
|
399 ) |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
400 self.add_widget(btn) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
401 for plugin in G.host.encryption_plugins: |
339
63cdabdd032e
chat: show encryption button with group chats:
Goffi <goffi@goffi.org>
parents:
338
diff
changeset
|
402 if chat.type == C.CHAT_GROUP and plugin["directed"]: |
63cdabdd032e
chat: show encryption button with group chats:
Goffi <goffi@goffi.org>
parents:
338
diff
changeset
|
403 # directed plugins can't work with group chat |
63cdabdd032e
chat: show encryption button with group chats:
Goffi <goffi@goffi.org>
parents:
338
diff
changeset
|
404 continue |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
405 btn = EncryptionButton( |
312 | 406 text=plugin['name'], |
332
13bc00b9743a
chat: use `bind` for EncryptionButton events:
Goffi <goffi@goffi.org>
parents:
329
diff
changeset
|
407 trust_button=True, |
13bc00b9743a
chat: use `bind` for EncryptionButton events:
Goffi <goffi@goffi.org>
parents:
329
diff
changeset
|
408 ) |
13bc00b9743a
chat: use `bind` for EncryptionButton events:
Goffi <goffi@goffi.org>
parents:
329
diff
changeset
|
409 btn.bind( |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
410 on_release=partial(self.startEncryption, plugin=plugin), |
242
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
411 on_trust_release=partial(self.getTrustUI, plugin=plugin), |
332
13bc00b9743a
chat: use `bind` for EncryptionButton events:
Goffi <goffi@goffi.org>
parents:
329
diff
changeset
|
412 ) |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
413 self.add_widget(btn) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
414 log.info("added encryption: {}".format(plugin['name'])) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
415 |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
416 def messageEncryptionStopCb(self): |
312 | 417 log.info(_("Session with {destinee} is now in plain text").format( |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
418 destinee = self.chat.target)) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
419 |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
420 def messageEncryptionStopEb(self, failure_): |
312 | 421 msg = _("Error while stopping encryption with {destinee}: {reason}").format( |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
422 destinee = self.chat.target, |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
423 reason = failure_) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
424 log.warning(msg) |
312 | 425 G.host.addNote(_("encryption problem"), msg, C.XMLUI_DATA_LVL_ERROR) |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
426 |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
427 def unencrypted(self, button): |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
428 self.dismiss() |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
429 G.host.bridge.messageEncryptionStop( |
312 | 430 str(self.chat.target), |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
431 self.chat.profile, |
242
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
432 callback=self.messageEncryptionStopCb, |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
433 errback=self.messageEncryptionStopEb) |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
434 |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
435 def messageEncryptionStartCb(self, plugin): |
312 | 436 log.info(_("Session with {destinee} is now encrypted with {encr_name}").format( |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
437 destinee = self.chat.target, |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
438 encr_name = plugin['name'])) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
439 |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
440 def messageEncryptionStartEb(self, failure_): |
312 | 441 msg = _("Session can't be encrypted with {destinee}: {reason}").format( |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
442 destinee = self.chat.target, |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
443 reason = failure_) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
444 log.warning(msg) |
312 | 445 G.host.addNote(_("encryption problem"), msg, C.XMLUI_DATA_LVL_ERROR) |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
446 |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
447 def startEncryption(self, button, plugin): |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
448 """Request encryption with given plugin for this session |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
449 |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
450 @param button(EncryptionButton): button which has been pressed |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
451 @param plugin(dict): plugin data |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
452 """ |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
453 self.dismiss() |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
454 G.host.bridge.messageEncryptionStart( |
312 | 455 str(self.chat.target), |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
456 plugin['namespace'], |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
457 True, |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
458 self.chat.profile, |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
459 callback=partial(self.messageEncryptionStartCb, plugin=plugin), |
242
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
460 errback=self.messageEncryptionStartEb) |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
461 |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
462 def encryptionTrustUIGetCb(self, xmlui_raw): |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
463 xml_ui = xmlui.create( |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
464 G.host, xmlui_raw, profile=self.chat.profile) |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
465 xml_ui.show() |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
466 |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
467 def encryptionTrustUIGetEb(self, failure_): |
312 | 468 msg = _("Trust manager interface can't be retrieved: {reason}").format( |
242
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
469 reason = failure_) |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
470 log.warning(msg) |
312 | 471 G.host.addNote(_("encryption trust management problem"), msg, |
242
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
472 C.XMLUI_DATA_LVL_ERROR) |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
473 |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
474 def getTrustUI(self, button, plugin): |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
475 """Request and display trust management UI |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
476 |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
477 @param button(EncryptionButton): button which has been pressed |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
478 @param plugin(dict): plugin data |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
479 """ |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
480 self.dismiss() |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
481 G.host.bridge.encryptionTrustUIGet( |
312 | 482 str(self.chat.target), |
242
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
483 plugin['namespace'], |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
484 self.chat.profile, |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
485 callback=self.encryptionTrustUIGetCb, |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
486 errback=self.encryptionTrustUIGetEb) |
117 | 487 |
488 | |
22 | 489 class Chat(quick_chat.QuickChat, cagou_widget.CagouWidget): |
78 | 490 message_input = properties.ObjectProperty() |
86 | 491 messages_widget = properties.ObjectProperty() |
326 | 492 history_scroll = properties.ObjectProperty() |
412 | 493 attachments_to_send = properties.ObjectProperty() |
413
c466678c57b2
chat: control send button visibility in core.platform_, and show it when there are attachments
Goffi <goffi@goffi.org>
parents:
412
diff
changeset
|
494 send_button_visible = properties.BooleanProperty() |
387
d61bbbac4160
cagou widget: don't add header_input systematically anymore:
Goffi <goffi@goffi.org>
parents:
379
diff
changeset
|
495 use_header_input = True |
354 | 496 global_screen_manager = True |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
340
diff
changeset
|
497 collection_carousel = True |
22 | 498 |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
499 def __init__(self, host, target, type_=C.CHAT_ONE2ONE, nick=None, occupants=None, |
338
d4883f9576db
chat: handle room statuses following backend change
Goffi <goffi@goffi.org>
parents:
334
diff
changeset
|
500 subject=None, statuses=None, profiles=None): |
354 | 501 self.show_chat_selector = False |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
340
diff
changeset
|
502 if statuses is None: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
340
diff
changeset
|
503 statuses = {} |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
504 quick_chat.QuickChat.__init__( |
338
d4883f9576db
chat: handle room statuses following backend change
Goffi <goffi@goffi.org>
parents:
334
diff
changeset
|
505 self, host, target, type_, nick, occupants, subject, statuses, |
d4883f9576db
chat: handle room statuses following backend change
Goffi <goffi@goffi.org>
parents:
334
diff
changeset
|
506 profiles=profiles) |
122
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
507 self.otr_state_encryption = OTR_STATE_UNENCRYPTED |
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
508 self.otr_state_trust = OTR_STATE_UNTRUSTED |
225
a3162b29cda1
plugin chat: fixed AttributeError when message is receved and a corresponding ChatWidget is not created yet
Goffi <goffi@goffi.org>
parents:
193
diff
changeset
|
509 # completion attributes |
a3162b29cda1
plugin chat: fixed AttributeError when message is receved and a corresponding ChatWidget is not created yet
Goffi <goffi@goffi.org>
parents:
193
diff
changeset
|
510 self._hi_comp_data = None |
a3162b29cda1
plugin chat: fixed AttributeError when message is receved and a corresponding ChatWidget is not created yet
Goffi <goffi@goffi.org>
parents:
193
diff
changeset
|
511 self._hi_comp_last = None |
a3162b29cda1
plugin chat: fixed AttributeError when message is receved and a corresponding ChatWidget is not created yet
Goffi <goffi@goffi.org>
parents:
193
diff
changeset
|
512 self._hi_comp_dropdown = DropDown() |
a3162b29cda1
plugin chat: fixed AttributeError when message is receved and a corresponding ChatWidget is not created yet
Goffi <goffi@goffi.org>
parents:
193
diff
changeset
|
513 self._hi_comp_allowed = True |
22 | 514 cagou_widget.CagouWidget.__init__(self) |
278
444ba439530f
chat: moved transfer button to header_box
Goffi <goffi@goffi.org>
parents:
277
diff
changeset
|
515 transfer_btn = TransferButton(chat=self) |
444ba439530f
chat: moved transfer button to header_box
Goffi <goffi@goffi.org>
parents:
277
diff
changeset
|
516 self.headerInputAddExtra(transfer_btn) |
339
63cdabdd032e
chat: show encryption button with group chats:
Goffi <goffi@goffi.org>
parents:
338
diff
changeset
|
517 if (type_ == C.CHAT_ONE2ONE or "REALJID_PUBLIC" in statuses): |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
518 self.encryption_btn = EncryptionMainButton(self) |
122
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
519 self.headerInputAddExtra(self.encryption_btn) |
287
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
520 self.extra_menu = ExtraMenu(chat=self) |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
521 extra_btn = ExtraButton(chat=self) |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
522 self.headerInputAddExtra(extra_btn) |
325 | 523 self.header_input.hint_text = target |
326 | 524 self._history_prepend_lock = False |
525 self.history_count = 0 | |
22 | 526 |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
340
diff
changeset
|
527 def on_kv_post(self, __): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
340
diff
changeset
|
528 self.postInit() |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
340
diff
changeset
|
529 |
354 | 530 def screenManagerInit(self, screen_manager): |
531 screen_manager.transition = screenmanager.SlideTransition(direction='down') | |
532 sel_screen = Screen(name='chat_selector') | |
533 chat_selector = ChatSelector(profile=self.profile) | |
534 sel_screen.add_widget(chat_selector) | |
535 screen_manager.add_widget(sel_screen) | |
536 if self.show_chat_selector: | |
537 transition = screen_manager.transition | |
538 screen_manager.transition = NoTransition() | |
539 screen_manager.current = 'chat_selector' | |
540 screen_manager.transition = transition | |
541 | |
156
826e7b17a19b
chat: added __unicode__ and __str__
Goffi <goffi@goffi.org>
parents:
145
diff
changeset
|
542 def __str__(self): |
312 | 543 return "Chat({})".format(self.target) |
156
826e7b17a19b
chat: added __unicode__ and __str__
Goffi <goffi@goffi.org>
parents:
145
diff
changeset
|
544 |
826e7b17a19b
chat: added __unicode__ and __str__
Goffi <goffi@goffi.org>
parents:
145
diff
changeset
|
545 def __repr__(self): |
826e7b17a19b
chat: added __unicode__ and __str__
Goffi <goffi@goffi.org>
parents:
145
diff
changeset
|
546 return self.__str__() |
826e7b17a19b
chat: added __unicode__ and __str__
Goffi <goffi@goffi.org>
parents:
145
diff
changeset
|
547 |
22 | 548 @classmethod |
549 def factory(cls, plugin_info, target, profiles): | |
550 profiles = list(profiles) | |
551 if len(profiles) > 1: | |
312 | 552 raise NotImplementedError("Multi-profiles is not available yet for chat") |
22 | 553 if target is None: |
354 | 554 show_chat_selector = True |
22 | 555 target = G.host.profiles[profiles[0]].whoami |
354 | 556 else: |
557 show_chat_selector = False | |
558 wid = G.host.widgets.getOrCreateWidget(cls, target, on_new_widget=None, | |
559 on_existing_widget=G.host.getOrClone, | |
560 profiles=profiles) | |
561 wid.show_chat_selector = show_chat_selector | |
562 return wid | |
22 | 563 |
289
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
564 @property |
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
565 def message_widgets_rev(self): |
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
566 return self.messages_widget.children |
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
567 |
354 | 568 ## keyboard ## |
367
abb57182ebfb
chat: prepend nick to message input when occupant avatar is touched on group chat.
Goffi <goffi@goffi.org>
parents:
357
diff
changeset
|
569 |
354 | 570 def key_input(self, window, key, scancode, codepoint, modifier): |
571 if key == 27: | |
572 screen_manager = self.screen_manager | |
573 screen_manager.transition.direction = 'down' | |
574 screen_manager.current = 'chat_selector' | |
575 return True | |
576 | |
414 | 577 ## drop ## |
578 | |
579 def on_drop_file(self, path): | |
580 self.addAttachment(path) | |
354 | 581 |
109
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
582 ## header ## |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
583 |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
584 def changeWidget(self, jid_): |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
585 """change current widget for a new one with given jid |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
586 |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
587 @param jid_(jid.JID): jid of the widget to create |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
588 """ |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
589 plugin_info = G.host.getPluginInfo(main=Chat) |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
590 factory = plugin_info['factory'] |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
591 G.host.switchWidget(self, factory(plugin_info, jid_, profiles=[self.profile])) |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
592 self.header_input.text = '' |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
593 |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
594 def onHeaderInput(self): |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
595 text = self.header_input.text.strip() |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
596 try: |
312 | 597 if text.count('@') != 1 or text.count(' '): |
109
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
598 raise ValueError |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
599 jid_ = jid.JID(text) |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
600 except ValueError: |
312 | 601 log.info("entered text is not a jid") |
109
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
602 return |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
603 |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
604 def discoCb(disco): |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
605 # TODO: check if plugin XEP-0045 is activated |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
606 if "conference" in [i[0] for i in disco[1]]: |
312 | 607 G.host.bridge.mucJoin(str(jid_), "", "", self.profile, |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
608 callback=self._mucJoinCb, errback=self._mucJoinEb) |
109
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
609 else: |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
610 self.changeWidget(jid_) |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
611 |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
612 def discoEb(failure): |
312 | 613 log.warning("Disco failure, ignore this text: {}".format(failure)) |
109
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
614 |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
615 G.host.bridge.discoInfos(jid_.domain, self.profile, callback=discoCb, |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
616 errback=discoEb) |
109
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
617 |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
618 def onHeaderInputCompleted(self, input_wid, completed_text): |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
619 self._hi_comp_allowed = False |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
620 input_wid.text = completed_text |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
621 self._hi_comp_allowed = True |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
622 self._hi_comp_dropdown.dismiss() |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
623 self.onHeaderInput() |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
624 |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
625 def onHeaderInputComplete(self, wid, text): |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
626 if not self._hi_comp_allowed: |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
627 return |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
628 text = text.lstrip() |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
629 if not text: |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
630 self._hi_comp_data = None |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
631 self._hi_comp_last = None |
144 | 632 self._hi_comp_dropdown.dismiss() |
109
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
633 return |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
634 |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
635 profile = list(self.profiles)[0] |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
636 |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
637 if self._hi_comp_data is None: |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
638 # first completion, we build the initial list |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
639 comp_data = self._hi_comp_data = [] |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
640 self._hi_comp_last = '' |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
641 for jid_, jid_data in G.host.contact_lists[profile].all_iter: |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
642 comp_data.append((jid_, jid_data)) |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
643 comp_data.sort(key=lambda datum: datum[0]) |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
644 else: |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
645 comp_data = self._hi_comp_data |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
646 |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
647 # XXX: dropdown is rebuilt each time backspace is pressed or if the text is changed, |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
648 # it works OK, but some optimisation may be done here |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
649 dropdown = self._hi_comp_dropdown |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
650 |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
651 if not text.startswith(self._hi_comp_last) or not self._hi_comp_last: |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
652 # text has changed or backspace has been pressed, we restart |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
653 dropdown.clear_widgets() |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
654 |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
655 for jid_, jid_data in comp_data: |
312 | 656 nick = jid_data.get('nick', '') |
109
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
657 if text in jid_.bare or text in nick.lower(): |
193
284cb5c467b0
core (common): split JidItem in 3 classes:
Goffi <goffi@goffi.org>
parents:
186
diff
changeset
|
658 btn = JidButton( |
109
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
659 jid = jid_.bare, |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
660 profile = profile, |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
661 size_hint = (0.5, None), |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
662 nick = nick, |
284 | 663 on_release=lambda __, txt=jid_.bare: self.onHeaderInputCompleted(wid, txt) |
109
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
664 ) |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
665 dropdown.add_widget(btn) |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
666 else: |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
667 # more chars, we continue completion by removing unwanted widgets |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
668 to_remove = [] |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
669 for c in dropdown.children[0].children: |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
670 if text not in c.jid and text not in (c.nick or ''): |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
671 to_remove.append(c) |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
672 for c in to_remove: |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
673 dropdown.remove_widget(c) |
144 | 674 if dropdown.attach_to is None: |
675 dropdown.open(wid) | |
109
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
676 self._hi_comp_last = text |
7631325e11f4
chat: added completion of header's input, any entity in cache containing the entered text is shown
Goffi <goffi@goffi.org>
parents:
106
diff
changeset
|
677 |
22 | 678 def messageDataConverter(self, idx, mess_id): |
679 return {"mess_data": self.messages[mess_id]} | |
680 | |
681 def _onHistoryPrinted(self): | |
682 """Refresh or scroll down the focus after the history is printed""" | |
683 # self.adapter.data = self.messages | |
312 | 684 for mess_data in self.messages.values(): |
22 | 685 self.appendMessage(mess_data) |
686 super(Chat, self)._onHistoryPrinted() | |
687 | |
688 def createMessage(self, message): | |
689 self.appendMessage(message) | |
329
51520ce98154
common_widgets (DelayedBoxLayout), chat: don't delay layout on new message:
Goffi <goffi@goffi.org>
parents:
326
diff
changeset
|
690 # we need to render immediatly next 2 layouts to avoid an unpleasant flickering |
51520ce98154
common_widgets (DelayedBoxLayout), chat: don't delay layout on new message:
Goffi <goffi@goffi.org>
parents:
326
diff
changeset
|
691 # when sending or receiving a message |
51520ce98154
common_widgets (DelayedBoxLayout), chat: don't delay layout on new message:
Goffi <goffi@goffi.org>
parents:
326
diff
changeset
|
692 self.messages_widget.dont_delay_next_layouts = 2 |
22 | 693 |
694 def appendMessage(self, mess_data): | |
289
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
695 """Append a message Widget to the history |
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
696 |
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
697 @param mess_data(quick_chat.Message): message data |
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
698 """ |
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
699 if self.handleUserMoved(mess_data): |
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
700 return |
22 | 701 self.messages_widget.add_widget(MessageWidget(mess_data=mess_data)) |
184
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
702 self.notify(mess_data) |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
703 |
326 | 704 def prependMessage(self, mess_data): |
705 """Prepend a message Widget to the history | |
706 | |
707 @param mess_data(quick_chat.Message): message data | |
708 """ | |
709 mess_wid = self.messages_widget | |
710 last_idx = len(mess_wid.children) | |
711 mess_wid.add_widget(MessageWidget(mess_data=mess_data), index=last_idx) | |
712 | |
184
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
713 def _get_notif_msg(self, mess_data): |
312 | 714 return _("{nick}: {message}").format( |
184
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
715 nick=mess_data.nick, |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
716 message=mess_data.main_message) |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
717 |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
718 def notify(self, mess_data): |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
719 """Notify user when suitable |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
720 |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
721 For one2one chat, notification will happen when window has not focus |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
722 or when one2one chat is not visible. A note is also there when widget |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
723 is not visible. |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
724 For group chat, note will be added on mention, with a desktop notification if |
396
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
725 window has not focus or is not visible. |
184
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
726 """ |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
727 visible_clones = [w for w in G.host.getVisibleList(self.__class__) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
728 if w.target == self.target] |
186
a826c70beda2
chat: avoid multiple notifications when there are several cloned chats (i.e. with same target)
Goffi <goffi@goffi.org>
parents:
185
diff
changeset
|
729 if len(visible_clones) > 1 and visible_clones.index(self) > 0: |
a826c70beda2
chat: avoid multiple notifications when there are several cloned chats (i.e. with same target)
Goffi <goffi@goffi.org>
parents:
185
diff
changeset
|
730 # to avoid multiple notifications in case of multiple cloned widgets |
a826c70beda2
chat: avoid multiple notifications when there are several cloned chats (i.e. with same target)
Goffi <goffi@goffi.org>
parents:
185
diff
changeset
|
731 # we only handle first clone |
a826c70beda2
chat: avoid multiple notifications when there are several cloned chats (i.e. with same target)
Goffi <goffi@goffi.org>
parents:
185
diff
changeset
|
732 return |
a826c70beda2
chat: avoid multiple notifications when there are several cloned chats (i.e. with same target)
Goffi <goffi@goffi.org>
parents:
185
diff
changeset
|
733 is_visible = bool(visible_clones) |
184
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
734 if self.type == C.CHAT_ONE2ONE: |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
735 if (not Window.focus or not is_visible) and not mess_data.history: |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
736 notif_msg = self._get_notif_msg(mess_data) |
396
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
737 G.host.notify( |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
738 type_=C.NOTIFY_MESSAGE, |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
739 entity=mess_data.from_jid, |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
740 message=notif_msg, |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
741 subject=_("private message"), |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
742 widget=self, |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
743 profile=self.profile |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
744 ) |
184
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
745 if not is_visible: |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
746 G.host.addNote( |
312 | 747 _("private message"), |
250
ff1efdeff53f
core: notifs can now have a custom icon and be clickable:
Goffi <goffi@goffi.org>
parents:
244
diff
changeset
|
748 notif_msg, |
312 | 749 symbol = "chat", |
250
ff1efdeff53f
core: notifs can now have a custom icon and be clickable:
Goffi <goffi@goffi.org>
parents:
244
diff
changeset
|
750 action = { |
312 | 751 "action": 'chat', |
250
ff1efdeff53f
core: notifs can now have a custom icon and be clickable:
Goffi <goffi@goffi.org>
parents:
244
diff
changeset
|
752 "target": self.target, |
ff1efdeff53f
core: notifs can now have a custom icon and be clickable:
Goffi <goffi@goffi.org>
parents:
244
diff
changeset
|
753 "profiles": self.profiles} |
184
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
754 ) |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
755 else: |
396
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
756 if mess_data.mention: |
184
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
757 notif_msg = self._get_notif_msg(mess_data) |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
758 G.host.addNote( |
312 | 759 _("mention"), |
250
ff1efdeff53f
core: notifs can now have a custom icon and be clickable:
Goffi <goffi@goffi.org>
parents:
244
diff
changeset
|
760 notif_msg, |
312 | 761 symbol = "chat", |
250
ff1efdeff53f
core: notifs can now have a custom icon and be clickable:
Goffi <goffi@goffi.org>
parents:
244
diff
changeset
|
762 action = { |
312 | 763 "action": 'chat', |
250
ff1efdeff53f
core: notifs can now have a custom icon and be clickable:
Goffi <goffi@goffi.org>
parents:
244
diff
changeset
|
764 "target": self.target, |
ff1efdeff53f
core: notifs can now have a custom icon and be clickable:
Goffi <goffi@goffi.org>
parents:
244
diff
changeset
|
765 "profiles": self.profiles} |
184
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
766 ) |
396
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
767 if not is_visible or not Window.focus: |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
768 subject=_("mention ({room_jid})").format(room_jid=self.target) |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
769 G.host.notify( |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
770 type_=C.NOTIFY_MENTION, |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
771 entity=self.target, |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
772 message=notif_msg, |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
773 subject=subject, |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
774 widget=self, |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
775 profile=self.profile |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
776 ) |
22 | 777 |
367
abb57182ebfb
chat: prepend nick to message input when occupant avatar is touched on group chat.
Goffi <goffi@goffi.org>
parents:
357
diff
changeset
|
778 # message input |
abb57182ebfb
chat: prepend nick to message input when occupant avatar is touched on group chat.
Goffi <goffi@goffi.org>
parents:
357
diff
changeset
|
779 |
412 | 780 def _attachmentProgressCb(self, item, metadata, profile): |
781 item.parent.remove_widget(item) | |
782 log.info(f"item {item.data.get('path')} uploaded successfully") | |
783 | |
784 def _attachmentProgressEb(self, item, err_msg, profile): | |
785 item.parent.remove_widget(item) | |
786 path = item.data.get('path') | |
787 msg = _("item {path} could not be uploaded: {err_msg}").format( | |
788 path=path, err_msg=err_msg) | |
789 G.host.addNote(_("can't upload file"), msg, C.XMLUI_DATA_LVL_WARNING) | |
790 log.warning(msg) | |
791 | |
792 def _progressGetCb(self, item, metadata): | |
793 try: | |
794 position = int(metadata["position"]) | |
795 size = int(metadata["size"]) | |
796 except KeyError: | |
797 # we got empty metadata, the progression is either not yet started or | |
798 # finished | |
799 if item.progress: | |
800 # if progress is already started, receiving empty metadata means | |
801 # that progression is finished | |
802 item.progress = 100 | |
803 return | |
804 else: | |
805 item.progress = position/size*100 | |
806 | |
807 if item.parent is not None: | |
808 # the item is not yet fully received, we reschedule an update | |
809 Clock.schedule_once( | |
810 partial(self._attachmentProgressUpdate, item), | |
811 PROGRESS_UPDATE) | |
812 | |
813 def _attachmentProgressUpdate(self, item, __): | |
814 G.host.bridge.progressGet( | |
815 item.data["progress_id"], | |
816 self.profile, | |
817 callback=partial(self._progressGetCb, item), | |
818 errback=G.host.errback, | |
819 ) | |
820 | |
367
abb57182ebfb
chat: prepend nick to message input when occupant avatar is touched on group chat.
Goffi <goffi@goffi.org>
parents:
357
diff
changeset
|
821 def addNick(self, nick): |
abb57182ebfb
chat: prepend nick to message input when occupant avatar is touched on group chat.
Goffi <goffi@goffi.org>
parents:
357
diff
changeset
|
822 """Add a nickname to message_input if suitable""" |
abb57182ebfb
chat: prepend nick to message input when occupant avatar is touched on group chat.
Goffi <goffi@goffi.org>
parents:
357
diff
changeset
|
823 if (self.type == C.CHAT_GROUP and not self.message_input.text.startswith(nick)): |
abb57182ebfb
chat: prepend nick to message input when occupant avatar is touched on group chat.
Goffi <goffi@goffi.org>
parents:
357
diff
changeset
|
824 self.message_input.text = f'{nick}: {self.message_input.text}' |
abb57182ebfb
chat: prepend nick to message input when occupant avatar is touched on group chat.
Goffi <goffi@goffi.org>
parents:
357
diff
changeset
|
825 |
22 | 826 def onSend(self, input_widget): |
412 | 827 extra = {} |
828 for item in self.attachments_to_send.attachments.children: | |
829 if item.sending: | |
830 # the item is already being sent | |
831 continue | |
832 item.sending = True | |
833 progress_id = item.data["progress_id"] = str(uuid.uuid4()) | |
834 attachments = extra.setdefault(C.MESS_KEY_ATTACHMENTS, []) | |
835 attachment = { | |
836 "path": str(item.data["path"]), | |
837 "progress_id": progress_id, | |
838 } | |
839 attachments.append(attachment) | |
840 | |
841 Clock.schedule_once( | |
842 partial(self._attachmentProgressUpdate, item), | |
843 PROGRESS_UPDATE) | |
844 | |
845 G.host.registerProgressCbs( | |
846 progress_id, | |
847 callback=partial(self._attachmentProgressCb, item), | |
848 errback=partial(self._attachmentProgressEb, item) | |
849 ) | |
850 | |
851 | |
22 | 852 G.host.messageSend( |
853 self.target, | |
412 | 854 # TODO: handle language |
855 {'': input_widget.text}, | |
856 # TODO: put this in QuickChat | |
857 mess_type= | |
858 C.MESS_TYPE_GROUPCHAT if self.type == C.CHAT_GROUP else C.MESS_TYPE_CHAT, | |
859 extra=extra, | |
22 | 860 profile_key=self.profile |
861 ) | |
862 input_widget.text = '' | |
863 | |
412 | 864 def addAttachment(self, file_path): |
865 file_path = Path(file_path) | |
866 data = { | |
867 "path": file_path, | |
868 "name": file_path.name, | |
869 } | |
870 self.attachments_to_send.attachments.add_widget( | |
871 AttachmentToSendItem(data=data) | |
872 ) | |
283
c73a7cd36b54
chat: show warning note on failing fileUpload + added forgotten "profile" argument
Goffi <goffi@goffi.org>
parents:
282
diff
changeset
|
873 |
322
e2b51663d8b8
core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
874 def transferFile(self, file_path, transfer_type=C.TRANSFER_UPLOAD, cleaning_cb=None): |
412 | 875 # FIXME: cleaning_cb is not managed |
322
e2b51663d8b8
core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
876 if transfer_type == C.TRANSFER_UPLOAD: |
412 | 877 self.addAttachment(file_path) |
98
4d8c122b86a6
menu (upload): send transfer (i.e. P2P transfer) is now working
Goffi <goffi@goffi.org>
parents:
97
diff
changeset
|
878 elif transfer_type == C.TRANSFER_SEND: |
4d8c122b86a6
menu (upload): send transfer (i.e. P2P transfer) is now working
Goffi <goffi@goffi.org>
parents:
97
diff
changeset
|
879 if self.type == C.CHAT_GROUP: |
312 | 880 log.warning("P2P transfer is not possible for group chat") |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
881 # TODO: show an error dialog to user, or better hide the send button for |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
882 # MUC |
98
4d8c122b86a6
menu (upload): send transfer (i.e. P2P transfer) is now working
Goffi <goffi@goffi.org>
parents:
97
diff
changeset
|
883 else: |
4d8c122b86a6
menu (upload): send transfer (i.e. P2P transfer) is now working
Goffi <goffi@goffi.org>
parents:
97
diff
changeset
|
884 jid_ = self.target |
4d8c122b86a6
menu (upload): send transfer (i.e. P2P transfer) is now working
Goffi <goffi@goffi.org>
parents:
97
diff
changeset
|
885 if not jid_.resource: |
4d8c122b86a6
menu (upload): send transfer (i.e. P2P transfer) is now working
Goffi <goffi@goffi.org>
parents:
97
diff
changeset
|
886 jid_ = G.host.contact_lists[self.profile].getFullJid(jid_) |
322
e2b51663d8b8
core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
887 G.host.bridge.fileSend(str(jid_), str(file_path), "", "", {}, |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
888 profile=self.profile) |
98
4d8c122b86a6
menu (upload): send transfer (i.e. P2P transfer) is now working
Goffi <goffi@goffi.org>
parents:
97
diff
changeset
|
889 # TODO: notification of sending/failing |
4d8c122b86a6
menu (upload): send transfer (i.e. P2P transfer) is now working
Goffi <goffi@goffi.org>
parents:
97
diff
changeset
|
890 else: |
312 | 891 raise log.error("transfer of type {} are not handled".format(transfer_type)) |
98
4d8c122b86a6
menu (upload): send transfer (i.e. P2P transfer) is now working
Goffi <goffi@goffi.org>
parents:
97
diff
changeset
|
892 |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
893 def messageEncryptionStarted(self, plugin_data): |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
894 quick_chat.QuickChat.messageEncryptionStarted(self, plugin_data) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
895 self.encryption_btn.symbol = SYMBOL_ENCRYPTED |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
896 self.encryption_btn.color = COLOR_ENCRYPTED |
312 | 897 self.encryption_btn.selectAlgo(plugin_data['name']) |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
898 |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
899 def messageEncryptionStopped(self, plugin_data): |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
900 quick_chat.QuickChat.messageEncryptionStopped(self, plugin_data) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
901 self.encryption_btn.symbol = SYMBOL_UNENCRYPTED |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
902 self.encryption_btn.color = COLOR_UNENCRYPTED |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
903 self.encryption_btn.selectAlgo(None) |
78 | 904 |
46
d6a63942d5ad
chat: fixed MUC joining following changes in backend
Goffi <goffi@goffi.org>
parents:
45
diff
changeset
|
905 def _mucJoinCb(self, joined_data): |
338
d4883f9576db
chat: handle room statuses following backend change
Goffi <goffi@goffi.org>
parents:
334
diff
changeset
|
906 joined, room_jid_s, occupants, user_nick, subject, statuses, profile = joined_data |
46
d6a63942d5ad
chat: fixed MUC joining following changes in backend
Goffi <goffi@goffi.org>
parents:
45
diff
changeset
|
907 self.host.mucRoomJoinedHandler(*joined_data[1:]) |
d6a63942d5ad
chat: fixed MUC joining following changes in backend
Goffi <goffi@goffi.org>
parents:
45
diff
changeset
|
908 jid_ = jid.JID(room_jid_s) |
42
286865bc013a
chat: joining MUC using header input is now working:
Goffi <goffi@goffi.org>
parents:
41
diff
changeset
|
909 self.changeWidget(jid_) |
286865bc013a
chat: joining MUC using header input is now working:
Goffi <goffi@goffi.org>
parents:
41
diff
changeset
|
910 |
286865bc013a
chat: joining MUC using header input is now working:
Goffi <goffi@goffi.org>
parents:
41
diff
changeset
|
911 def _mucJoinEb(self, failure): |
312 | 912 log.warning("Can't join room: {}".format(failure)) |
42
286865bc013a
chat: joining MUC using header input is now working:
Goffi <goffi@goffi.org>
parents:
41
diff
changeset
|
913 |
122
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
914 def onOTRState(self, state, dest_jid, profile): |
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
915 assert profile in self.profiles |
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
916 if state in OTR_STATE_ENCRYPTION: |
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
917 self.otr_state_encryption = state |
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
918 elif state in OTR_STATE_TRUST: |
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
919 self.otr_state_trust = state |
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
920 else: |
312 | 921 log.error(_("Unknown OTR state received: {}".format(state))) |
122
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
922 return |
135
091e288838e1
plugin chat: use new Symbol widget to display encryption button
Goffi <goffi@goffi.org>
parents:
126
diff
changeset
|
923 self.encryption_btn.symbol = self.encryption_btn.getSymbol() |
091e288838e1
plugin chat: use new Symbol widget to display encryption button
Goffi <goffi@goffi.org>
parents:
126
diff
changeset
|
924 self.encryption_btn.color = self.encryption_btn.getColor() |
122
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
925 |
265
805c4103dac5
core: resync widgets only when they are visible:
Goffi <goffi@goffi.org>
parents:
261
diff
changeset
|
926 def onVisible(self): |
805c4103dac5
core: resync widgets only when they are visible:
Goffi <goffi@goffi.org>
parents:
261
diff
changeset
|
927 if not self.sync: |
805c4103dac5
core: resync widgets only when they are visible:
Goffi <goffi@goffi.org>
parents:
261
diff
changeset
|
928 self.resync() |
805c4103dac5
core: resync widgets only when they are visible:
Goffi <goffi@goffi.org>
parents:
261
diff
changeset
|
929 |
396
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
930 def onSelected(self): |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
931 G.host.clearNotifs(self.target, profile=self.profile) |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
932 |
356
307c2501d8b2
chat: keep as many instances of opened chat as there are active WHWrapper, instead of just one:
Goffi <goffi@goffi.org>
parents:
354
diff
changeset
|
933 def onDelete(self, **kwargs): |
393
e2f806779b53
chat: added a "close" item in menu, to leave MUC/close current chat widget.
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
934 if kwargs.get('explicit_close', False): |
e2f806779b53
chat: added a "close" item in menu, to leave MUC/close current chat widget.
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
935 wrapper = self.whwrapper |
e2f806779b53
chat: added a "close" item in menu, to leave MUC/close current chat widget.
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
936 if wrapper is not None: |
e2f806779b53
chat: added a "close" item in menu, to leave MUC/close current chat widget.
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
937 if len(wrapper.carousel.slides) == 1: |
e2f806779b53
chat: added a "close" item in menu, to leave MUC/close current chat widget.
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
938 # if we delete the last opened chat, we need to show the selector |
e2f806779b53
chat: added a "close" item in menu, to leave MUC/close current chat widget.
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
939 screen_manager = self.screen_manager |
e2f806779b53
chat: added a "close" item in menu, to leave MUC/close current chat widget.
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
940 screen_manager.transition.direction = 'down' |
e2f806779b53
chat: added a "close" item in menu, to leave MUC/close current chat widget.
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
941 screen_manager.current = 'chat_selector' |
e2f806779b53
chat: added a "close" item in menu, to leave MUC/close current chat widget.
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
942 wrapper.carousel.remove_widget(self) |
e2f806779b53
chat: added a "close" item in menu, to leave MUC/close current chat widget.
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
943 return True |
261
a579eda31f4f
chat: don't use "force" argument anymore
Goffi <goffi@goffi.org>
parents:
260
diff
changeset
|
944 # we always keep one widget, so it's available when swiping |
a579eda31f4f
chat: don't use "force" argument anymore
Goffi <goffi@goffi.org>
parents:
260
diff
changeset
|
945 # TODO: delete all widgets when chat is closed |
a579eda31f4f
chat: don't use "force" argument anymore
Goffi <goffi@goffi.org>
parents:
260
diff
changeset
|
946 nb_instances = sum(1 for _ in self.host.widgets.getWidgetInstances(self)) |
356
307c2501d8b2
chat: keep as many instances of opened chat as there are active WHWrapper, instead of just one:
Goffi <goffi@goffi.org>
parents:
354
diff
changeset
|
947 # we want to keep at least one instance of Chat by WHWrapper |
307c2501d8b2
chat: keep as many instances of opened chat as there are active WHWrapper, instead of just one:
Goffi <goffi@goffi.org>
parents:
354
diff
changeset
|
948 nb_to_keep = len(G.host.widgets_handler.children) |
307c2501d8b2
chat: keep as many instances of opened chat as there are active WHWrapper, instead of just one:
Goffi <goffi@goffi.org>
parents:
354
diff
changeset
|
949 if nb_instances <= nb_to_keep: |
261
a579eda31f4f
chat: don't use "force" argument anymore
Goffi <goffi@goffi.org>
parents:
260
diff
changeset
|
950 return False |
22 | 951 |
326 | 952 def _history_unlock(self, __): |
953 self._history_prepend_lock = False | |
954 log.debug("history prepend unlocked") | |
955 # we call manually onScroll, to check if we are still in the scrolling zone | |
956 self.onScroll(self.history_scroll, self.history_scroll.scroll_y) | |
957 | |
958 def _history_scroll_adjust(self, __, scroll_start_height): | |
959 # history scroll position must correspond to where it was before new messages | |
960 # have been appended | |
961 self.history_scroll.scroll_y = ( | |
962 scroll_start_height / self.messages_widget.height | |
963 ) | |
964 | |
965 # we want a small delay before unlocking, to avoid re-fetching history | |
966 # again | |
967 Clock.schedule_once(self._history_unlock, 1.5) | |
968 | |
969 def _backHistoryGetCb_post(self, __, history, scroll_start_height): | |
970 if len(history) == 0: | |
971 # we don't unlock self._history_prepend_lock if there is no history, as there | |
972 # is no sense to try to retrieve more in this case. | |
973 log.debug(f"we've reached top of history for {self.target.bare} chat") | |
974 else: | |
975 # we have to schedule again for _history_scroll_adjust, else messages_widget | |
976 # is not resized (self.messages_widget.height is not yet updated) | |
977 # as a result, the scroll_to can't work correctly | |
978 Clock.schedule_once(partial( | |
979 self._history_scroll_adjust, | |
980 scroll_start_height=scroll_start_height)) | |
981 log.debug( | |
982 f"{len(history)} messages prepended to history (last: {history[0][0]})") | |
983 | |
984 def _backHistoryGetCb(self, history): | |
985 # TODO: factorise with QuickChat._historyGetCb | |
986 scroll_start_height = self.messages_widget.height * self.history_scroll.scroll_y | |
987 for data in reversed(history): | |
409
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
988 uid, timestamp, from_jid, to_jid, message, subject, type_, extra_s = data |
326 | 989 from_jid = jid.JID(from_jid) |
990 to_jid = jid.JID(to_jid) | |
409
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
991 extra = data_format.deserialise(extra_s) |
326 | 992 extra["history"] = True |
993 self.messages[uid] = message = quick_chat.Message( | |
994 self, | |
995 uid, | |
996 timestamp, | |
997 from_jid, | |
998 to_jid, | |
999 message, | |
1000 subject, | |
1001 type_, | |
1002 extra, | |
1003 self.profile, | |
1004 ) | |
1005 self.messages.move_to_end(uid, last=False) | |
1006 self.prependMessage(message) | |
1007 Clock.schedule_once(partial( | |
1008 self._backHistoryGetCb_post, | |
1009 history=history, | |
1010 scroll_start_height=scroll_start_height)) | |
1011 | |
1012 def _backHistoryGetEb(self, failure_): | |
1013 G.host.addNote( | |
1014 _("Problem while getting back history"), | |
1015 _("Can't back history for {target}: {problem}").format( | |
1016 target=self.target, problem=failure_), | |
1017 C.XMLUI_DATA_LVL_ERROR) | |
1018 # we don't unlock self._history_prepend_lock on purpose, no need | |
1019 # to try to get more history if something is wrong | |
1020 | |
1021 def onScroll(self, scroll_view, scroll_y): | |
1022 if self._history_prepend_lock: | |
1023 return | |
1024 if (1-scroll_y) * self.messages_widget.height < INFINITE_SCROLL_LIMIT: | |
1025 self._history_prepend_lock = True | |
1026 log.debug(f"Retrieving back history for {self} [{self.history_count}]") | |
1027 self.history_count += 1 | |
1028 first_uid = next(iter(self.messages.keys())) | |
1029 filters = self.history_filters.copy() | |
1030 filters['before_uid'] = first_uid | |
1031 self.host.bridge.historyGet( | |
1032 str(self.host.profiles[self.profile].whoami.bare), | |
1033 str(self.target), | |
1034 30, | |
1035 True, | |
1036 {k: str(v) for k,v in filters.items()}, | |
1037 self.profile, | |
1038 callback=self._backHistoryGetCb, | |
1039 errback=self._backHistoryGetEb, | |
1040 ) | |
1041 | |
22 | 1042 |
395
c04c3b167cb0
chat: use header input to filter entities + open a new chat with unknown jid.
Goffi <goffi@goffi.org>
parents:
394
diff
changeset
|
1043 class ChatSelector(cagou_widget.CagouWidget, FilterBehavior): |
394
d15828ca9d86
chat: use the new "implicit_update" and "to_show" properties for ChatSelector.jid_selector:
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
1044 jid_selector = properties.ObjectProperty() |
354 | 1045 profile = properties.StringProperty() |
1046 plugin_info_class = Chat | |
395
c04c3b167cb0
chat: use header input to filter entities + open a new chat with unknown jid.
Goffi <goffi@goffi.org>
parents:
394
diff
changeset
|
1047 use_header_input = True |
354 | 1048 |
1049 def on_select(self, contact_button): | |
1050 contact_jid = jid.JID(contact_button.jid) | |
1051 plugin_info = G.host.getPluginInfo(main=Chat) | |
1052 factory = plugin_info['factory'] | |
1053 self.screen_manager.transition.direction = 'up' | |
1054 carousel = self.whwrapper.carousel | |
1055 current_slides = {w.target: w for w in carousel.slides} | |
1056 if contact_jid in current_slides: | |
1057 slide = current_slides[contact_jid] | |
1058 idx = carousel.slides.index(slide) | |
1059 carousel.index = idx | |
1060 self.screen_manager.current = '' | |
1061 else: | |
1062 G.host.switchWidget( | |
1063 self, factory(plugin_info, contact_jid, profiles=[self.profile])) | |
1064 | |
1065 | |
395
c04c3b167cb0
chat: use header input to filter entities + open a new chat with unknown jid.
Goffi <goffi@goffi.org>
parents:
394
diff
changeset
|
1066 def onHeaderInput(self): |
c04c3b167cb0
chat: use header input to filter entities + open a new chat with unknown jid.
Goffi <goffi@goffi.org>
parents:
394
diff
changeset
|
1067 text = self.header_input.text.strip() |
c04c3b167cb0
chat: use header input to filter entities + open a new chat with unknown jid.
Goffi <goffi@goffi.org>
parents:
394
diff
changeset
|
1068 try: |
c04c3b167cb0
chat: use header input to filter entities + open a new chat with unknown jid.
Goffi <goffi@goffi.org>
parents:
394
diff
changeset
|
1069 if text.count('@') != 1 or text.count(' '): |
c04c3b167cb0
chat: use header input to filter entities + open a new chat with unknown jid.
Goffi <goffi@goffi.org>
parents:
394
diff
changeset
|
1070 raise ValueError |
c04c3b167cb0
chat: use header input to filter entities + open a new chat with unknown jid.
Goffi <goffi@goffi.org>
parents:
394
diff
changeset
|
1071 jid_ = jid.JID(text) |
c04c3b167cb0
chat: use header input to filter entities + open a new chat with unknown jid.
Goffi <goffi@goffi.org>
parents:
394
diff
changeset
|
1072 except ValueError: |
c04c3b167cb0
chat: use header input to filter entities + open a new chat with unknown jid.
Goffi <goffi@goffi.org>
parents:
394
diff
changeset
|
1073 log.info("entered text is not a jid") |
c04c3b167cb0
chat: use header input to filter entities + open a new chat with unknown jid.
Goffi <goffi@goffi.org>
parents:
394
diff
changeset
|
1074 return |
c04c3b167cb0
chat: use header input to filter entities + open a new chat with unknown jid.
Goffi <goffi@goffi.org>
parents:
394
diff
changeset
|
1075 G.host.doAction("chat", jid_, [self.profile]) |
c04c3b167cb0
chat: use header input to filter entities + open a new chat with unknown jid.
Goffi <goffi@goffi.org>
parents:
394
diff
changeset
|
1076 |
c04c3b167cb0
chat: use header input to filter entities + open a new chat with unknown jid.
Goffi <goffi@goffi.org>
parents:
394
diff
changeset
|
1077 def onHeaderInputComplete(self, wid, text, **kwargs): |
c04c3b167cb0
chat: use header input to filter entities + open a new chat with unknown jid.
Goffi <goffi@goffi.org>
parents:
394
diff
changeset
|
1078 """we filter items when text is entered in input box""" |
404
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
1079 for layout in self.jid_selector.items_layouts: |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
1080 self.do_filter( |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
1081 layout, |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
1082 text, |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
1083 # we append nick to jid to filter on both |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
1084 lambda c: c.jid + c.data.get('nick', ''), |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
1085 width_cb=lambda c: c.base_width, |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
1086 height_cb=lambda c: c.minimum_height, |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
1087 continue_tests=[lambda c: not isinstance(c, ContactButton)]) |
395
c04c3b167cb0
chat: use header input to filter entities + open a new chat with unknown jid.
Goffi <goffi@goffi.org>
parents:
394
diff
changeset
|
1088 |
c04c3b167cb0
chat: use header input to filter entities + open a new chat with unknown jid.
Goffi <goffi@goffi.org>
parents:
394
diff
changeset
|
1089 |
22 | 1090 PLUGIN_INFO["factory"] = Chat.factory |
1091 quick_widgets.register(quick_chat.QuickChat, Chat) |