Mercurial > libervia-desktop-kivy
annotate cagou/plugins/plugin_wid_chat.py @ 448:20a807443c3f
chat: resize attachments (images only for now):
if attachments to send contain oversized image, a checkbox will be shown (activated by
default) to reduce automatically the size.
The background color now cover the whole attachments to send widget.
If not already specified, media type is guessed from filename when adding an attachment.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 22 Mar 2020 14:10:59 +0100 |
parents | ffdf2390ea56 |
children | 642cd2435e26 |
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 |
448
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
24 import mimetypes |
425 | 25 from urllib.parse import urlparse |
78 | 26 from kivy.uix.boxlayout import BoxLayout |
426
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
27 from kivy.uix.gridlayout import GridLayout |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
28 from kivy.uix.screenmanager import Screen, NoTransition |
22 | 29 from kivy.uix.textinput import TextInput |
426
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
30 from kivy.uix.label import Label |
354 | 31 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
|
32 from kivy.uix.behaviors import ButtonBehavior |
185
ab3f5173ef5c
chat, simple XHTML: font size adjustement
Goffi <goffi@goffi.org>
parents:
184
diff
changeset
|
33 from kivy.metrics import sp, dp |
276 | 34 from kivy.clock import Clock |
22 | 35 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
|
36 from kivy.uix.stacklayout import StackLayout |
325 | 37 from kivy.uix.dropdown import DropDown |
38 from kivy.core.window import Window | |
39 from sat.core import log as logging | |
40 from sat.core.i18n import _ | |
41 from sat.core import exceptions | |
333
69d2a96ce26f
chat: serialise `options` in `fileUpload` following change in backend
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
42 from sat.tools.common import data_format |
22 | 43 from sat_frontends.quick_frontend import quick_widgets |
44 from sat_frontends.quick_frontend import quick_chat | |
106
9909ed7a7a20
moved SimpleXHTMLWidget to a dedicated module
Goffi <goffi@goffi.org>
parents:
105
diff
changeset
|
45 from sat_frontends.tools import jid |
325 | 46 from cagou import G |
404
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
47 from ..core.constants import Const as C |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
48 from ..core import cagou_widget |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
49 from ..core import xmlui |
426
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
50 from ..core.image import Image, AsyncImage |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
51 from ..core.common import Symbol, SymbolButton, JidButton, ContactButton |
404
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
52 from ..core.behaviors import FilterBehavior |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
53 from ..core import menu |
425 | 54 from ..core.common_widgets import ImagesGallery |
22 | 55 |
276 | 56 log = logging.getLogger(__name__) |
22 | 57 |
58 PLUGIN_INFO = { | |
312 | 59 "name": _("chat"), |
22 | 60 "main": "Chat", |
312 | 61 "description": _("instant messaging with one person or a group"), |
62 "icon_symbol": "chat", | |
22 | 63 } |
64 | |
244
5bd94bc08f5c
plugin chat: fixed OTR State filtering + removed some legacy code
Goffi <goffi@goffi.org>
parents:
242
diff
changeset
|
65 # 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
|
66 # 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
|
67 OTR_STATE_UNTRUSTED = 'untrusted' |
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
68 OTR_STATE_TRUSTED = 'trusted' |
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
69 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
|
70 OTR_STATE_UNENCRYPTED = 'unencrypted' |
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
71 OTR_STATE_ENCRYPTED = 'encrypted' |
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
72 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
|
73 |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
74 SYMBOL_UNENCRYPTED = 'lock-open' |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
75 SYMBOL_ENCRYPTED = 'lock' |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
76 SYMBOL_ENCRYPTED_TRUSTED = 'lock-filled' |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
77 COLOR_UNENCRYPTED = (0.4, 0.4, 0.4, 1) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
78 COLOR_ENCRYPTED = (0.4, 0.4, 0.4, 1) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
79 COLOR_ENCRYPTED_TRUSTED = (0.29,0.87,0.0,1) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
80 |
326 | 81 # below this limit, new messages will be prepended |
82 INFINITE_SCROLL_LIMIT = dp(600) | |
83 | |
412 | 84 # File sending progress |
85 PROGRESS_UPDATE = 0.2 # number of seconds before next progress update | |
86 | |
22 | 87 |
411
b018386653c2
chat: work around ScrollView bug in attachments by using a StackLayout instead:
Goffi <goffi@goffi.org>
parents:
409
diff
changeset
|
88 # 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
|
89 # 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
|
90 class AttachmentsLayout(StackLayout): |
412 | 91 """Layout for attachments in a received message""" |
92 padding = properties.VariableListProperty([dp(5), dp(5), 0, dp(5)]) | |
93 attachments = properties.ObjectProperty() | |
94 | |
95 | |
96 class AttachmentsToSend(BoxLayout): | |
97 """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
|
98 attachments = properties.ObjectProperty() |
448
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
99 reduce_checkbox = properties.ObjectProperty() |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
100 show_resize = properties.BooleanProperty(False) |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
101 |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
102 def on_kv_post(self, __): |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
103 self.attachments.bind(children=self.onAttachment) |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
104 |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
105 def onAttachment(self, __, attachments): |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
106 if len(attachments) == 0: |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
107 self.show_resize = False |
409
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
108 |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
109 |
425 | 110 class BaseAttachmentItem(BoxLayout): |
409
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
111 data = properties.DictProperty() |
412 | 112 progress = properties.NumericProperty(0) |
409
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
113 |
425 | 114 |
115 class AttachmentItem(BaseAttachmentItem): | |
116 | |
409
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
117 def get_symbol(self, data): |
432
36c3f1c02d33
chat: renamed `MESS_KEY_MEDIA_TYPE` to `MESS_KEY_ATTACHMENTS_MEDIA_TYPE` following backend change
Goffi <goffi@goffi.org>
parents:
426
diff
changeset
|
118 media_type = data.get(C.MESS_KEY_ATTACHMENTS_MEDIA_TYPE, '') |
409
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
119 main_type = media_type.split('/', 1)[0] |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
120 if main_type == 'image': |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
121 return "file-image" |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
122 elif main_type == 'video': |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
123 return "file-video" |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
124 elif main_type == 'audio': |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
125 return "file-audio" |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
126 else: |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
127 return "doc" |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
128 |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
129 def on_press(self): |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
130 url = self.data.get('url') |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
131 if url: |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
132 G.local_platform.open_url(url, self) |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
133 else: |
412 | 134 log.warning(f"can't find URL in {self.data}") |
135 | |
136 | |
425 | 137 class AttachmentImageItem(ButtonBehavior, BaseAttachmentItem): |
138 image = properties.ObjectProperty() | |
139 | |
140 def on_press(self): | |
433 | 141 full_size_source = self.data.get('path', self.data.get('url')) |
142 gallery = ImagesGallery(sources=[full_size_source]) | |
425 | 143 G.host.showExtraUI(gallery) |
144 | |
446
ffdf2390ea56
chat: fixed `source` assignment for `AttachmentImageItem`
Goffi <goffi@goffi.org>
parents:
443
diff
changeset
|
145 def on_kv_post(self, __): |
ffdf2390ea56
chat: fixed `source` assignment for `AttachmentImageItem`
Goffi <goffi@goffi.org>
parents:
443
diff
changeset
|
146 self.on_data(None, self.data) |
ffdf2390ea56
chat: fixed `source` assignment for `AttachmentImageItem`
Goffi <goffi@goffi.org>
parents:
443
diff
changeset
|
147 |
437
b5e6d36fbf9c
chat: set AttachmentImageItem in python instead of kv:
Goffi <goffi@goffi.org>
parents:
435
diff
changeset
|
148 def on_data(self, __, data): |
446
ffdf2390ea56
chat: fixed `source` assignment for `AttachmentImageItem`
Goffi <goffi@goffi.org>
parents:
443
diff
changeset
|
149 if self.image is None: |
ffdf2390ea56
chat: fixed `source` assignment for `AttachmentImageItem`
Goffi <goffi@goffi.org>
parents:
443
diff
changeset
|
150 return |
437
b5e6d36fbf9c
chat: set AttachmentImageItem in python instead of kv:
Goffi <goffi@goffi.org>
parents:
435
diff
changeset
|
151 source = data.get('preview') or data.get('path') or data.get('url') |
b5e6d36fbf9c
chat: set AttachmentImageItem in python instead of kv:
Goffi <goffi@goffi.org>
parents:
435
diff
changeset
|
152 if source: |
446
ffdf2390ea56
chat: fixed `source` assignment for `AttachmentImageItem`
Goffi <goffi@goffi.org>
parents:
443
diff
changeset
|
153 self.image.source = source |
437
b5e6d36fbf9c
chat: set AttachmentImageItem in python instead of kv:
Goffi <goffi@goffi.org>
parents:
435
diff
changeset
|
154 |
425 | 155 |
426
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
156 class AttachmentImagesCollectionItem(ButtonBehavior, GridLayout): |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
157 attachments = properties.ListProperty([]) |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
158 chat = properties.ObjectProperty() |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
159 mess_data = properties.ObjectProperty() |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
160 |
433 | 161 def _setPreview(self, attachment, wid, preview_path): |
162 attachment['preview'] = preview_path | |
163 wid.source = preview_path | |
164 | |
435
53bb3886b408
chat: generate preview if there is not one already for non encrypted attachments
Goffi <goffi@goffi.org>
parents:
433
diff
changeset
|
165 def _setPath(self, attachment, wid, path): |
426
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
166 attachment['path'] = path |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
167 if wid is not None: |
433 | 168 # we also need a preview for the widget |
169 if 'preview' in attachment: | |
170 wid.source = attachment['preview'] | |
171 else: | |
172 G.host.bridge.imageGeneratePreview( | |
173 path, | |
174 self.chat.profile, | |
175 callback=partial(self._setPreview, attachment, wid), | |
176 ) | |
426
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
177 |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
178 def on_kv_post(self, __): |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
179 attachments = self.attachments |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
180 self.clear_widgets() |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
181 for idx, attachment in enumerate(attachments): |
443
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
182 try: |
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
183 url = attachment['url'] |
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
184 except KeyError: |
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
185 url = None |
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
186 to_download = False |
435
53bb3886b408
chat: generate preview if there is not one already for non encrypted attachments
Goffi <goffi@goffi.org>
parents:
433
diff
changeset
|
187 else: |
443
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
188 if url.startswith("aesgcm:"): |
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
189 del attachment['url'] |
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
190 # if the file is encrypted, we need to download it for decryption |
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
191 to_download = True |
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
192 else: |
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
193 to_download = False |
426
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
194 |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
195 if idx < 3 or len(attachments) <= 4: |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
196 if ((self.mess_data.own_mess |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
197 or self.chat.contact_list.isInRoster(self.mess_data.from_jid))): |
441
ff548846df91
chat: use `image-loading` as source by default:
Goffi <goffi@goffi.org>
parents:
437
diff
changeset
|
198 wid = AsyncImage(size_hint=(1, 1), source="data/images/image-loading.gif") |
435
53bb3886b408
chat: generate preview if there is not one already for non encrypted attachments
Goffi <goffi@goffi.org>
parents:
433
diff
changeset
|
199 if 'preview' in attachment: |
53bb3886b408
chat: generate preview if there is not one already for non encrypted attachments
Goffi <goffi@goffi.org>
parents:
433
diff
changeset
|
200 wid.source = attachment["preview"] |
53bb3886b408
chat: generate preview if there is not one already for non encrypted attachments
Goffi <goffi@goffi.org>
parents:
433
diff
changeset
|
201 elif 'path' in attachment: |
53bb3886b408
chat: generate preview if there is not one already for non encrypted attachments
Goffi <goffi@goffi.org>
parents:
433
diff
changeset
|
202 G.host.bridge.imageGeneratePreview( |
53bb3886b408
chat: generate preview if there is not one already for non encrypted attachments
Goffi <goffi@goffi.org>
parents:
433
diff
changeset
|
203 attachment['path'], |
53bb3886b408
chat: generate preview if there is not one already for non encrypted attachments
Goffi <goffi@goffi.org>
parents:
433
diff
changeset
|
204 self.chat.profile, |
53bb3886b408
chat: generate preview if there is not one already for non encrypted attachments
Goffi <goffi@goffi.org>
parents:
433
diff
changeset
|
205 callback=partial(self._setPreview, attachment, wid), |
53bb3886b408
chat: generate preview if there is not one already for non encrypted attachments
Goffi <goffi@goffi.org>
parents:
433
diff
changeset
|
206 ) |
443
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
207 elif url is None: |
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
208 log.warning(f"Can't find any source for {attachment}") |
435
53bb3886b408
chat: generate preview if there is not one already for non encrypted attachments
Goffi <goffi@goffi.org>
parents:
433
diff
changeset
|
209 else: |
53bb3886b408
chat: generate preview if there is not one already for non encrypted attachments
Goffi <goffi@goffi.org>
parents:
433
diff
changeset
|
210 # we'll download the file, the preview will then be generated |
53bb3886b408
chat: generate preview if there is not one already for non encrypted attachments
Goffi <goffi@goffi.org>
parents:
433
diff
changeset
|
211 to_download = True |
426
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
212 else: |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
213 # we don't download automatically the image if the contact is not |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
214 # in roster, to avoid leaking the ip |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
215 wid = Symbol(symbol="file-image") |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
216 self.add_widget(wid) |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
217 else: |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
218 wid = None |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
219 |
435
53bb3886b408
chat: generate preview if there is not one already for non encrypted attachments
Goffi <goffi@goffi.org>
parents:
433
diff
changeset
|
220 if to_download: |
53bb3886b408
chat: generate preview if there is not one already for non encrypted attachments
Goffi <goffi@goffi.org>
parents:
433
diff
changeset
|
221 # the file needs to be downloaded, the widget source, |
53bb3886b408
chat: generate preview if there is not one already for non encrypted attachments
Goffi <goffi@goffi.org>
parents:
433
diff
changeset
|
222 # attachment path, and preview will then be completed |
426
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
223 G.host.downloadURL( |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
224 url, |
435
53bb3886b408
chat: generate preview if there is not one already for non encrypted attachments
Goffi <goffi@goffi.org>
parents:
433
diff
changeset
|
225 callback=partial(self._setPath, attachment, wid), |
426
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
226 dest=C.FILE_DEST_CACHE, |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
227 profile=self.chat.profile, |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
228 ) |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
229 |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
230 if len(attachments) > 4: |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
231 counter = Label( |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
232 bold=True, |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
233 text=f"+{len(attachments) - 3}", |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
234 ) |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
235 self.add_widget(counter) |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
236 |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
237 def on_press(self): |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
238 sources = [] |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
239 for attachment in self.attachments: |
435
53bb3886b408
chat: generate preview if there is not one already for non encrypted attachments
Goffi <goffi@goffi.org>
parents:
433
diff
changeset
|
240 source = attachment.get('path') or attachment.get('url') |
426
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
241 if not source: |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
242 log.warning(f"no source for {attachment}") |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
243 else: |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
244 sources.append(source) |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
245 gallery = ImagesGallery(sources=sources) |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
246 G.host.showExtraUI(gallery) |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
247 |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
248 |
412 | 249 class AttachmentToSendItem(AttachmentItem): |
250 # True when the item is being sent | |
251 sending = properties.BooleanProperty(False) | |
409
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
252 |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
253 |
367
abb57182ebfb
chat: prepend nick to message input when occupant avatar is touched on group chat.
Goffi <goffi@goffi.org>
parents:
357
diff
changeset
|
254 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
|
255 pass |
7819e9efa250
chat: avatar and nick are now displayed, need further aesthetic improvments
Goffi <goffi@goffi.org>
parents:
42
diff
changeset
|
256 |
7819e9efa250
chat: avatar and nick are now displayed, need further aesthetic improvments
Goffi <goffi@goffi.org>
parents:
42
diff
changeset
|
257 |
325 | 258 class MessageWidget(quick_chat.MessageWidget, BoxLayout): |
22 | 259 mess_data = properties.ObjectProperty() |
57 | 260 mess_xhtml = properties.ObjectProperty() |
45 | 261 mess_padding = (dp(5), dp(5)) |
47
abb81efef3bb
chat: update avatar following quick frontend improvments
Goffi <goffi@goffi.org>
parents:
46
diff
changeset
|
262 avatar = properties.ObjectProperty() |
103
c601e3d40342
chat: display delivery receipt (with a green check mark)
Goffi <goffi@goffi.org>
parents:
102
diff
changeset
|
263 delivery = properties.ObjectProperty() |
185
ab3f5173ef5c
chat, simple XHTML: font size adjustement
Goffi <goffi@goffi.org>
parents:
184
diff
changeset
|
264 font_size = properties.NumericProperty(sp(12)) |
325 | 265 right_part = properties.ObjectProperty() |
266 header_box = properties.ObjectProperty() | |
47
abb81efef3bb
chat: update avatar following quick frontend improvments
Goffi <goffi@goffi.org>
parents:
46
diff
changeset
|
267 |
409
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
268 def on_kv_post(self, __): |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
269 if not self.mess_data: |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
270 raise exceptions.InternalError( |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
271 "mess_data must always be set in MessageWidget") |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
272 |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
273 self.mess_data.widgets.add(self) |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
274 self.add_attachments() |
44
7819e9efa250
chat: avatar and nick are now displayed, need further aesthetic improvments
Goffi <goffi@goffi.org>
parents:
42
diff
changeset
|
275 |
7819e9efa250
chat: avatar and nick are now displayed, need further aesthetic improvments
Goffi <goffi@goffi.org>
parents:
42
diff
changeset
|
276 @property |
7819e9efa250
chat: avatar and nick are now displayed, need further aesthetic improvments
Goffi <goffi@goffi.org>
parents:
42
diff
changeset
|
277 def chat(self): |
7819e9efa250
chat: avatar and nick are now displayed, need further aesthetic improvments
Goffi <goffi@goffi.org>
parents:
42
diff
changeset
|
278 """return parent Chat instance""" |
7819e9efa250
chat: avatar and nick are now displayed, need further aesthetic improvments
Goffi <goffi@goffi.org>
parents:
42
diff
changeset
|
279 return self.mess_data.parent |
22 | 280 |
325 | 281 def _get_from_mess_data(self, name, default): |
282 if self.mess_data is None: | |
283 return default | |
284 return getattr(self.mess_data, name) | |
285 | |
289
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
286 def _get_message(self): |
22 | 287 """Return currently displayed message""" |
325 | 288 if self.mess_data is None: |
289 return "" | |
22 | 290 return self.mess_data.main_message |
291 | |
289
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
292 def _set_message(self, message): |
325 | 293 if self.mess_data is None: |
294 return False | |
312 | 295 if message == self.mess_data.message.get(""): |
289
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
296 return False |
312 | 297 self.mess_data.message = {"": message} |
289
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
298 return True |
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
299 |
325 | 300 message = properties.AliasProperty( |
301 partial(_get_from_mess_data, name="main_message", default=""), | |
302 _set_message, | |
303 bind=['mess_data'], | |
304 ) | |
305 message_xhtml = properties.AliasProperty( | |
306 partial(_get_from_mess_data, name="main_message_xhtml", default=""), | |
307 bind=['mess_data']) | |
308 mess_type = properties.AliasProperty( | |
309 partial(_get_from_mess_data, name="type", default=""), bind=['mess_data']) | |
310 own_mess = properties.AliasProperty( | |
311 partial(_get_from_mess_data, name="own_mess", default=False), bind=['mess_data']) | |
312 nick = properties.AliasProperty( | |
313 partial(_get_from_mess_data, name="nick", default=""), bind=['mess_data']) | |
314 time_text = properties.AliasProperty( | |
315 partial(_get_from_mess_data, name="time_text", default=""), bind=['mess_data']) | |
57 | 316 |
289
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
317 @property |
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
318 def info_type(self): |
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
319 return self.mess_data.info_type |
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
320 |
54
514c187afebc
chat: changed udpate to use dict instead of single key/value
Goffi <goffi@goffi.org>
parents:
47
diff
changeset
|
321 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
|
322 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
|
323 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
|
324 if 'status' in update_dict: |
c601e3d40342
chat: display delivery receipt (with a green check mark)
Goffi <goffi@goffi.org>
parents:
102
diff
changeset
|
325 status = update_dict['status'] |
312 | 326 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
|
327 |
426
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
328 def _setPath(self, data, path): |
425 | 329 """Set path of decrypted file to an item""" |
426
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
330 data['path'] = path |
425 | 331 |
409
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
332 def add_attachments(self): |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
333 """Add attachments layout + attachments item""" |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
334 attachments = self.mess_data.attachments |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
335 if not attachments: |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
336 return |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
337 root_layout = AttachmentsLayout() |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
338 self.right_part.add_widget(root_layout) |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
339 layout = root_layout.attachments |
426
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
340 |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
341 image_attachments = [] |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
342 other_attachments = [] |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
343 # we first separate images and other attachments, so we know if we need |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
344 # to use an image collection |
409
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
345 for attachment in attachments: |
432
36c3f1c02d33
chat: renamed `MESS_KEY_MEDIA_TYPE` to `MESS_KEY_ATTACHMENTS_MEDIA_TYPE` following backend change
Goffi <goffi@goffi.org>
parents:
426
diff
changeset
|
346 media_type = attachment.get(C.MESS_KEY_ATTACHMENTS_MEDIA_TYPE, '') |
425 | 347 main_type = media_type.split('/', 1)[0] |
426
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
348 # GIF images are really badly handled by Kivy, the memory |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
349 # consumption explode, and the images frequencies are not handled |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
350 # correctly, thus we can't display them and we consider them as |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
351 # other attachment, so user can open the item with appropriate |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
352 # software. |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
353 if main_type == 'image' and media_type != "image/gif": |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
354 image_attachments.append(attachment) |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
355 else: |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
356 other_attachments.append(attachment) |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
357 |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
358 if len(image_attachments) > 1: |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
359 collection = AttachmentImagesCollectionItem( |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
360 attachments=image_attachments, |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
361 chat=self.chat, |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
362 mess_data=self.mess_data, |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
363 ) |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
364 layout.add_widget(collection) |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
365 elif image_attachments: |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
366 attachment = image_attachments[0] |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
367 # to avoid leaking IP address, we only display image if the contact is in |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
368 # roster |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
369 if ((self.mess_data.own_mess |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
370 or self.chat.contact_list.isInRoster(self.mess_data.from_jid))): |
443
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
371 try: |
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
372 url = urlparse(attachment['url']) |
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
373 except KeyError: |
425 | 374 item = AttachmentImageItem(data=attachment) |
375 else: | |
443
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
376 if url.scheme == "aesgcm": |
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
377 # we remove the URL now, we'll replace it by |
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
378 # the local decrypted version |
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
379 del attachment['url'] |
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
380 item = AttachmentImageItem(data=attachment) |
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
381 G.host.downloadURL( |
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
382 url.geturl(), |
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
383 callback=partial(self._setPath, item.data), |
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
384 dest=C.FILE_DEST_CACHE, |
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
385 profile=self.chat.profile, |
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
386 ) |
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
387 else: |
61322ff8090b
chat: fixed handling of attachments without URL
Goffi <goffi@goffi.org>
parents:
442
diff
changeset
|
388 item = AttachmentImageItem(data=attachment) |
425 | 389 else: |
390 item = AttachmentItem(data=attachment) | |
426
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
391 |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
392 layout.add_widget(item) |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
393 |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
394 for attachment in other_attachments: |
d3a6ae859556
chat: image attachments collection, first draft:
Goffi <goffi@goffi.org>
parents:
425
diff
changeset
|
395 item = AttachmentItem(data=attachment) |
409
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
396 layout.add_widget(item) |
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
397 |
22 | 398 |
78 | 399 class MessageInputBox(BoxLayout): |
276 | 400 message_input = properties.ObjectProperty() |
401 | |
402 def send_text(self): | |
403 self.message_input.send_text() | |
78 | 404 |
405 | |
22 | 406 class MessageInputWidget(TextInput): |
407 | |
276 | 408 def keyboard_on_key_down(self, window, keycode, text, modifiers): |
409 # We don't send text when shift is pressed to be able to add line feeds | |
410 # (i.e. multi-lines messages). We don't send on Android either as the | |
411 # send button appears on this platform. | |
412 if (keycode[-1] == "enter" | |
413 and "shift" not in modifiers | |
414 and sys.platform != 'android'): | |
415 self.send_text() | |
22 | 416 else: |
276 | 417 return super(MessageInputWidget, self).keyboard_on_key_down( |
418 window, keycode, text, modifiers) | |
419 | |
420 def send_text(self): | |
421 self.dispatch('on_text_validate') | |
22 | 422 |
423 | |
278
444ba439530f
chat: moved transfer button to header_box
Goffi <goffi@goffi.org>
parents:
277
diff
changeset
|
424 class TransferButton(SymbolButton): |
444ba439530f
chat: moved transfer button to header_box
Goffi <goffi@goffi.org>
parents:
277
diff
changeset
|
425 chat = properties.ObjectProperty() |
444ba439530f
chat: moved transfer button to header_box
Goffi <goffi@goffi.org>
parents:
277
diff
changeset
|
426 |
444ba439530f
chat: moved transfer button to header_box
Goffi <goffi@goffi.org>
parents:
277
diff
changeset
|
427 def on_release(self, *args): |
417
5b50b7ef2617
menu (TransferMenu): UI improvments:
Goffi <goffi@goffi.org>
parents:
414
diff
changeset
|
428 menu.TransferMenu( |
5b50b7ef2617
menu (TransferMenu): UI improvments:
Goffi <goffi@goffi.org>
parents:
414
diff
changeset
|
429 encrypted=self.chat.encrypted, |
5b50b7ef2617
menu (TransferMenu): UI improvments:
Goffi <goffi@goffi.org>
parents:
414
diff
changeset
|
430 callback=self.chat.transferFile, |
5b50b7ef2617
menu (TransferMenu): UI improvments:
Goffi <goffi@goffi.org>
parents:
414
diff
changeset
|
431 ).show(self) |
278
444ba439530f
chat: moved transfer button to header_box
Goffi <goffi@goffi.org>
parents:
277
diff
changeset
|
432 |
444ba439530f
chat: moved transfer button to header_box
Goffi <goffi@goffi.org>
parents:
277
diff
changeset
|
433 |
287
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
434 class ExtraMenu(DropDown): |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
435 chat = properties.ObjectProperty() |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
436 |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
437 def on_select(self, menu): |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
438 if menu == 'bookmark': |
312 | 439 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
|
440 {}, C.NO_SECURITY_LIMIT, self.chat.profile, |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
441 callback=partial( |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
442 G.host.actionManager, profile=self.chat.profile), |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
443 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
|
444 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
|
445 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
|
446 # 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
|
447 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
|
448 else: |
e2f806779b53
chat: added a "close" item in menu, to leave MUC/close current chat widget.
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
449 # 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
|
450 # 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
|
451 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
|
452 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
|
453 else: |
312 | 454 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
|
455 |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
456 |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
457 class ExtraButton(SymbolButton): |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
458 chat = properties.ObjectProperty() |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
459 |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
460 |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
461 class EncryptionMainButton(SymbolButton): |
117 | 462 |
463 def __init__(self, chat, **kwargs): | |
464 """ | |
465 @param chat(Chat): Chat instance | |
466 """ | |
122
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
467 self.chat = chat |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
468 self.encryption_menu = EncryptionMenu(chat) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
469 super(EncryptionMainButton, self).__init__(**kwargs) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
470 self.bind(on_release=self.encryption_menu.open) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
471 |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
472 def selectAlgo(self, name): |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
473 """Mark an encryption algorithm as selected. |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
474 |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
475 This will also deselect all other button |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
476 @param name(unicode, None): encryption plugin name |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
477 None for plain text |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
478 """ |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
479 buttons = self.encryption_menu.container.children |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
480 buttons[-1].selected = name is None |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
481 for button in buttons[:-1]: |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
482 button.selected = button.text == name |
117 | 483 |
135
091e288838e1
plugin chat: use new Symbol widget to display encryption button
Goffi <goffi@goffi.org>
parents:
126
diff
changeset
|
484 def getColor(self): |
122
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
485 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
|
486 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
|
487 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
|
488 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
|
489 else: |
135
091e288838e1
plugin chat: use new Symbol widget to display encryption button
Goffi <goffi@goffi.org>
parents:
126
diff
changeset
|
490 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
|
491 |
135
091e288838e1
plugin chat: use new Symbol widget to display encryption button
Goffi <goffi@goffi.org>
parents:
126
diff
changeset
|
492 def getSymbol(self): |
091e288838e1
plugin chat: use new Symbol widget to display encryption button
Goffi <goffi@goffi.org>
parents:
126
diff
changeset
|
493 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
|
494 return 'lock-open' |
091e288838e1
plugin chat: use new Symbol widget to display encryption button
Goffi <goffi@goffi.org>
parents:
126
diff
changeset
|
495 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
|
496 return 'lock-filled' |
091e288838e1
plugin chat: use new Symbol widget to display encryption button
Goffi <goffi@goffi.org>
parents:
126
diff
changeset
|
497 else: |
091e288838e1
plugin chat: use new Symbol widget to display encryption button
Goffi <goffi@goffi.org>
parents:
126
diff
changeset
|
498 return 'lock' |
122
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
499 |
117 | 500 |
242
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
501 class TrustManagementButton(SymbolButton): |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
502 pass |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
503 |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
504 |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
505 class EncryptionButton(BoxLayout): |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
506 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
|
507 text = properties.StringProperty() |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
508 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
|
509 best_width = properties.NumericProperty(0) |
312 | 510 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
|
511 |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
512 def __init__(self, **kwargs): |
312 | 513 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
|
514 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
|
515 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
|
516 if self.trust_button: |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
517 self.add_widget(TrustManagementButton()) |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
518 |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
519 def on_release(self): |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
520 pass |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
521 |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
522 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
|
523 pass |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
524 |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
525 |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
526 class EncryptionMenu(DropDown): |
242
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
527 # 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
|
528 best_width = properties.NumericProperty(0) |
117 | 529 |
530 def __init__(self, chat, **kwargs): | |
531 """ | |
532 @param chat(Chat): Chat instance | |
533 """ | |
534 self.chat = chat | |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
535 super(EncryptionMenu, self).__init__(**kwargs) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
536 btn = EncryptionButton( |
312 | 537 text=_("unencrypted (plain text)"), |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
538 on_release=self.unencrypted, |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
539 selected=True, |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
540 bold=False, |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
541 ) |
332
13bc00b9743a
chat: use `bind` for EncryptionButton events:
Goffi <goffi@goffi.org>
parents:
329
diff
changeset
|
542 btn.bind( |
13bc00b9743a
chat: use `bind` for EncryptionButton events:
Goffi <goffi@goffi.org>
parents:
329
diff
changeset
|
543 on_release=self.unencrypted, |
13bc00b9743a
chat: use `bind` for EncryptionButton events:
Goffi <goffi@goffi.org>
parents:
329
diff
changeset
|
544 ) |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
545 self.add_widget(btn) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
546 for plugin in G.host.encryption_plugins: |
339
63cdabdd032e
chat: show encryption button with group chats:
Goffi <goffi@goffi.org>
parents:
338
diff
changeset
|
547 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
|
548 # directed plugins can't work with group chat |
63cdabdd032e
chat: show encryption button with group chats:
Goffi <goffi@goffi.org>
parents:
338
diff
changeset
|
549 continue |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
550 btn = EncryptionButton( |
312 | 551 text=plugin['name'], |
332
13bc00b9743a
chat: use `bind` for EncryptionButton events:
Goffi <goffi@goffi.org>
parents:
329
diff
changeset
|
552 trust_button=True, |
13bc00b9743a
chat: use `bind` for EncryptionButton events:
Goffi <goffi@goffi.org>
parents:
329
diff
changeset
|
553 ) |
13bc00b9743a
chat: use `bind` for EncryptionButton events:
Goffi <goffi@goffi.org>
parents:
329
diff
changeset
|
554 btn.bind( |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
555 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
|
556 on_trust_release=partial(self.getTrustUI, plugin=plugin), |
332
13bc00b9743a
chat: use `bind` for EncryptionButton events:
Goffi <goffi@goffi.org>
parents:
329
diff
changeset
|
557 ) |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
558 self.add_widget(btn) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
559 log.info("added encryption: {}".format(plugin['name'])) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
560 |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
561 def messageEncryptionStopCb(self): |
312 | 562 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
|
563 destinee = self.chat.target)) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
564 |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
565 def messageEncryptionStopEb(self, failure_): |
312 | 566 msg = _("Error while stopping encryption with {destinee}: {reason}").format( |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
567 destinee = self.chat.target, |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
568 reason = failure_) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
569 log.warning(msg) |
312 | 570 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
|
571 |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
572 def unencrypted(self, button): |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
573 self.dismiss() |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
574 G.host.bridge.messageEncryptionStop( |
312 | 575 str(self.chat.target), |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
576 self.chat.profile, |
242
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
577 callback=self.messageEncryptionStopCb, |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
578 errback=self.messageEncryptionStopEb) |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
579 |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
580 def messageEncryptionStartCb(self, plugin): |
312 | 581 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
|
582 destinee = self.chat.target, |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
583 encr_name = plugin['name'])) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
584 |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
585 def messageEncryptionStartEb(self, failure_): |
312 | 586 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
|
587 destinee = self.chat.target, |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
588 reason = failure_) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
589 log.warning(msg) |
312 | 590 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
|
591 |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
592 def startEncryption(self, button, plugin): |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
593 """Request encryption with given plugin for this session |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
594 |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
595 @param button(EncryptionButton): button which has been pressed |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
596 @param plugin(dict): plugin data |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
597 """ |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
598 self.dismiss() |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
599 G.host.bridge.messageEncryptionStart( |
312 | 600 str(self.chat.target), |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
601 plugin['namespace'], |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
602 True, |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
603 self.chat.profile, |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
604 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
|
605 errback=self.messageEncryptionStartEb) |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
606 |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
607 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
|
608 xml_ui = xmlui.create( |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
609 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
|
610 xml_ui.show() |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
611 |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
612 def encryptionTrustUIGetEb(self, failure_): |
312 | 613 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
|
614 reason = failure_) |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
615 log.warning(msg) |
312 | 616 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
|
617 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
|
618 |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
619 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
|
620 """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
|
621 |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
622 @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
|
623 @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
|
624 """ |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
625 self.dismiss() |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
626 G.host.bridge.encryptionTrustUIGet( |
312 | 627 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
|
628 plugin['namespace'], |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
629 self.chat.profile, |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
630 callback=self.encryptionTrustUIGetCb, |
c2503168fab7
plugin chat (encryption): added a button to display trust management UI.
Goffi <goffi@goffi.org>
parents:
233
diff
changeset
|
631 errback=self.encryptionTrustUIGetEb) |
117 | 632 |
633 | |
22 | 634 class Chat(quick_chat.QuickChat, cagou_widget.CagouWidget): |
78 | 635 message_input = properties.ObjectProperty() |
86 | 636 messages_widget = properties.ObjectProperty() |
326 | 637 history_scroll = properties.ObjectProperty() |
412 | 638 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
|
639 send_button_visible = properties.BooleanProperty() |
387
d61bbbac4160
cagou widget: don't add header_input systematically anymore:
Goffi <goffi@goffi.org>
parents:
379
diff
changeset
|
640 use_header_input = True |
354 | 641 global_screen_manager = True |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
340
diff
changeset
|
642 collection_carousel = True |
22 | 643 |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
644 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
|
645 subject=None, statuses=None, profiles=None): |
354 | 646 self.show_chat_selector = False |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
340
diff
changeset
|
647 if statuses is None: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
340
diff
changeset
|
648 statuses = {} |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
649 quick_chat.QuickChat.__init__( |
338
d4883f9576db
chat: handle room statuses following backend change
Goffi <goffi@goffi.org>
parents:
334
diff
changeset
|
650 self, host, target, type_, nick, occupants, subject, statuses, |
d4883f9576db
chat: handle room statuses following backend change
Goffi <goffi@goffi.org>
parents:
334
diff
changeset
|
651 profiles=profiles) |
122
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
652 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
|
653 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
|
654 # 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
|
655 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
|
656 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
|
657 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
|
658 self._hi_comp_allowed = True |
22 | 659 cagou_widget.CagouWidget.__init__(self) |
278
444ba439530f
chat: moved transfer button to header_box
Goffi <goffi@goffi.org>
parents:
277
diff
changeset
|
660 transfer_btn = TransferButton(chat=self) |
444ba439530f
chat: moved transfer button to header_box
Goffi <goffi@goffi.org>
parents:
277
diff
changeset
|
661 self.headerInputAddExtra(transfer_btn) |
339
63cdabdd032e
chat: show encryption button with group chats:
Goffi <goffi@goffi.org>
parents:
338
diff
changeset
|
662 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
|
663 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
|
664 self.headerInputAddExtra(self.encryption_btn) |
287
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
665 self.extra_menu = ExtraMenu(chat=self) |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
666 extra_btn = ExtraButton(chat=self) |
5d96bcd3bfec
chat: added an extra menu (3 dots menu):
Goffi <goffi@goffi.org>
parents:
284
diff
changeset
|
667 self.headerInputAddExtra(extra_btn) |
325 | 668 self.header_input.hint_text = target |
326 | 669 self._history_prepend_lock = False |
670 self.history_count = 0 | |
22 | 671 |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
340
diff
changeset
|
672 def on_kv_post(self, __): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
340
diff
changeset
|
673 self.postInit() |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
340
diff
changeset
|
674 |
354 | 675 def screenManagerInit(self, screen_manager): |
676 screen_manager.transition = screenmanager.SlideTransition(direction='down') | |
677 sel_screen = Screen(name='chat_selector') | |
678 chat_selector = ChatSelector(profile=self.profile) | |
679 sel_screen.add_widget(chat_selector) | |
680 screen_manager.add_widget(sel_screen) | |
681 if self.show_chat_selector: | |
682 transition = screen_manager.transition | |
683 screen_manager.transition = NoTransition() | |
684 screen_manager.current = 'chat_selector' | |
685 screen_manager.transition = transition | |
686 | |
156
826e7b17a19b
chat: added __unicode__ and __str__
Goffi <goffi@goffi.org>
parents:
145
diff
changeset
|
687 def __str__(self): |
312 | 688 return "Chat({})".format(self.target) |
156
826e7b17a19b
chat: added __unicode__ and __str__
Goffi <goffi@goffi.org>
parents:
145
diff
changeset
|
689 |
826e7b17a19b
chat: added __unicode__ and __str__
Goffi <goffi@goffi.org>
parents:
145
diff
changeset
|
690 def __repr__(self): |
826e7b17a19b
chat: added __unicode__ and __str__
Goffi <goffi@goffi.org>
parents:
145
diff
changeset
|
691 return self.__str__() |
826e7b17a19b
chat: added __unicode__ and __str__
Goffi <goffi@goffi.org>
parents:
145
diff
changeset
|
692 |
22 | 693 @classmethod |
694 def factory(cls, plugin_info, target, profiles): | |
695 profiles = list(profiles) | |
696 if len(profiles) > 1: | |
312 | 697 raise NotImplementedError("Multi-profiles is not available yet for chat") |
22 | 698 if target is None: |
354 | 699 show_chat_selector = True |
22 | 700 target = G.host.profiles[profiles[0]].whoami |
354 | 701 else: |
702 show_chat_selector = False | |
703 wid = G.host.widgets.getOrCreateWidget(cls, target, on_new_widget=None, | |
704 on_existing_widget=G.host.getOrClone, | |
705 profiles=profiles) | |
706 wid.show_chat_selector = show_chat_selector | |
707 return wid | |
22 | 708 |
289
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
709 @property |
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
710 def message_widgets_rev(self): |
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
711 return self.messages_widget.children |
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
712 |
354 | 713 ## 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
|
714 |
354 | 715 def key_input(self, window, key, scancode, codepoint, modifier): |
716 if key == 27: | |
717 screen_manager = self.screen_manager | |
718 screen_manager.transition.direction = 'down' | |
719 screen_manager.current = 'chat_selector' | |
720 return True | |
721 | |
414 | 722 ## drop ## |
723 | |
724 def on_drop_file(self, path): | |
725 self.addAttachment(path) | |
354 | 726 |
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
|
727 ## 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
|
728 |
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
|
729 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
|
730 """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
|
731 |
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
|
732 @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
|
733 """ |
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
|
734 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
|
735 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
|
736 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
|
737 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
|
738 |
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
|
739 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
|
740 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
|
741 try: |
312 | 742 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
|
743 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
|
744 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
|
745 except ValueError: |
312 | 746 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
|
747 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
|
748 |
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
|
749 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
|
750 # 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
|
751 if "conference" in [i[0] for i in disco[1]]: |
312 | 752 G.host.bridge.mucJoin(str(jid_), "", "", self.profile, |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
753 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
|
754 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
|
755 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
|
756 |
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
|
757 def discoEb(failure): |
312 | 758 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
|
759 |
442 | 760 G.host.bridge.discoInfos( |
761 jid_.domain, | |
762 profile_key=self.profile, | |
763 callback=discoCb, | |
764 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
|
765 |
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
|
766 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
|
767 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
|
768 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
|
769 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
|
770 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
|
771 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
|
772 |
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
|
773 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
|
774 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
|
775 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
|
776 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
|
777 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
|
778 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
|
779 self._hi_comp_last = None |
144 | 780 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
|
781 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
|
782 |
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
|
783 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
|
784 |
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
|
785 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
|
786 # 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
|
787 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
|
788 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
|
789 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
|
790 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
|
791 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
|
792 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
|
793 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
|
794 |
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
|
795 # 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
|
796 # 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
|
797 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
|
798 |
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
|
799 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
|
800 # 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
|
801 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
|
802 |
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
|
803 for jid_, jid_data in comp_data: |
312 | 804 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
|
805 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
|
806 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
|
807 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
|
808 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
|
809 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
|
810 nick = nick, |
284 | 811 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
|
812 ) |
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
|
813 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
|
814 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
|
815 # 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
|
816 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
|
817 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
|
818 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
|
819 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
|
820 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
|
821 dropdown.remove_widget(c) |
144 | 822 if dropdown.attach_to is None: |
823 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
|
824 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
|
825 |
22 | 826 def messageDataConverter(self, idx, mess_id): |
827 return {"mess_data": self.messages[mess_id]} | |
828 | |
829 def _onHistoryPrinted(self): | |
830 """Refresh or scroll down the focus after the history is printed""" | |
831 # self.adapter.data = self.messages | |
312 | 832 for mess_data in self.messages.values(): |
22 | 833 self.appendMessage(mess_data) |
834 super(Chat, self)._onHistoryPrinted() | |
835 | |
836 def createMessage(self, message): | |
837 self.appendMessage(message) | |
329
51520ce98154
common_widgets (DelayedBoxLayout), chat: don't delay layout on new message:
Goffi <goffi@goffi.org>
parents:
326
diff
changeset
|
838 # 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
|
839 # 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
|
840 self.messages_widget.dont_delay_next_layouts = 2 |
22 | 841 |
842 def appendMessage(self, mess_data): | |
289
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
843 """Append a message Widget to the history |
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
844 |
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
845 @param mess_data(quick_chat.Message): message data |
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
846 """ |
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
847 if self.handleUserMoved(mess_data): |
717c6c368f70
chat: merge user moved info messages:
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
848 return |
22 | 849 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
|
850 self.notify(mess_data) |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
851 |
326 | 852 def prependMessage(self, mess_data): |
853 """Prepend a message Widget to the history | |
854 | |
855 @param mess_data(quick_chat.Message): message data | |
856 """ | |
857 mess_wid = self.messages_widget | |
858 last_idx = len(mess_wid.children) | |
859 mess_wid.add_widget(MessageWidget(mess_data=mess_data), index=last_idx) | |
860 | |
184
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
861 def _get_notif_msg(self, mess_data): |
312 | 862 return _("{nick}: {message}").format( |
184
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
863 nick=mess_data.nick, |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
864 message=mess_data.main_message) |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
865 |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
866 def notify(self, mess_data): |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
867 """Notify user when suitable |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
868 |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
869 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
|
870 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
|
871 is not visible. |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
872 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
|
873 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
|
874 """ |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
875 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
|
876 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
|
877 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
|
878 # 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
|
879 # 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
|
880 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
|
881 is_visible = bool(visible_clones) |
184
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
882 if self.type == C.CHAT_ONE2ONE: |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
883 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
|
884 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
|
885 G.host.notify( |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
886 type_=C.NOTIFY_MESSAGE, |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
887 entity=mess_data.from_jid, |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
888 message=notif_msg, |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
889 subject=_("private message"), |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
890 widget=self, |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
891 profile=self.profile |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
892 ) |
184
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
893 if not is_visible: |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
894 G.host.addNote( |
312 | 895 _("private message"), |
250
ff1efdeff53f
core: notifs can now have a custom icon and be clickable:
Goffi <goffi@goffi.org>
parents:
244
diff
changeset
|
896 notif_msg, |
312 | 897 symbol = "chat", |
250
ff1efdeff53f
core: notifs can now have a custom icon and be clickable:
Goffi <goffi@goffi.org>
parents:
244
diff
changeset
|
898 action = { |
312 | 899 "action": 'chat', |
250
ff1efdeff53f
core: notifs can now have a custom icon and be clickable:
Goffi <goffi@goffi.org>
parents:
244
diff
changeset
|
900 "target": self.target, |
ff1efdeff53f
core: notifs can now have a custom icon and be clickable:
Goffi <goffi@goffi.org>
parents:
244
diff
changeset
|
901 "profiles": self.profiles} |
184
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
902 ) |
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
903 else: |
396
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
904 if mess_data.mention: |
184
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
905 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
|
906 G.host.addNote( |
312 | 907 _("mention"), |
250
ff1efdeff53f
core: notifs can now have a custom icon and be clickable:
Goffi <goffi@goffi.org>
parents:
244
diff
changeset
|
908 notif_msg, |
312 | 909 symbol = "chat", |
250
ff1efdeff53f
core: notifs can now have a custom icon and be clickable:
Goffi <goffi@goffi.org>
parents:
244
diff
changeset
|
910 action = { |
312 | 911 "action": 'chat', |
250
ff1efdeff53f
core: notifs can now have a custom icon and be clickable:
Goffi <goffi@goffi.org>
parents:
244
diff
changeset
|
912 "target": self.target, |
ff1efdeff53f
core: notifs can now have a custom icon and be clickable:
Goffi <goffi@goffi.org>
parents:
244
diff
changeset
|
913 "profiles": self.profiles} |
184
c63922860f80
chat: show desktop notification and/or note when suitable
Goffi <goffi@goffi.org>
parents:
180
diff
changeset
|
914 ) |
396
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
915 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
|
916 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
|
917 G.host.notify( |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
918 type_=C.NOTIFY_MENTION, |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
919 entity=self.target, |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
920 message=notif_msg, |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
921 subject=subject, |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
922 widget=self, |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
923 profile=self.profile |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
924 ) |
22 | 925 |
367
abb57182ebfb
chat: prepend nick to message input when occupant avatar is touched on group chat.
Goffi <goffi@goffi.org>
parents:
357
diff
changeset
|
926 # 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
|
927 |
412 | 928 def _attachmentProgressCb(self, item, metadata, profile): |
929 item.parent.remove_widget(item) | |
930 log.info(f"item {item.data.get('path')} uploaded successfully") | |
931 | |
932 def _attachmentProgressEb(self, item, err_msg, profile): | |
933 item.parent.remove_widget(item) | |
934 path = item.data.get('path') | |
935 msg = _("item {path} could not be uploaded: {err_msg}").format( | |
936 path=path, err_msg=err_msg) | |
937 G.host.addNote(_("can't upload file"), msg, C.XMLUI_DATA_LVL_WARNING) | |
938 log.warning(msg) | |
939 | |
940 def _progressGetCb(self, item, metadata): | |
941 try: | |
942 position = int(metadata["position"]) | |
943 size = int(metadata["size"]) | |
944 except KeyError: | |
945 # we got empty metadata, the progression is either not yet started or | |
946 # finished | |
947 if item.progress: | |
948 # if progress is already started, receiving empty metadata means | |
949 # that progression is finished | |
950 item.progress = 100 | |
951 return | |
952 else: | |
953 item.progress = position/size*100 | |
954 | |
955 if item.parent is not None: | |
956 # the item is not yet fully received, we reschedule an update | |
957 Clock.schedule_once( | |
958 partial(self._attachmentProgressUpdate, item), | |
959 PROGRESS_UPDATE) | |
960 | |
961 def _attachmentProgressUpdate(self, item, __): | |
962 G.host.bridge.progressGet( | |
963 item.data["progress_id"], | |
964 self.profile, | |
965 callback=partial(self._progressGetCb, item), | |
966 errback=G.host.errback, | |
967 ) | |
968 | |
367
abb57182ebfb
chat: prepend nick to message input when occupant avatar is touched on group chat.
Goffi <goffi@goffi.org>
parents:
357
diff
changeset
|
969 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
|
970 """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
|
971 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
|
972 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
|
973 |
22 | 974 def onSend(self, input_widget): |
412 | 975 extra = {} |
976 for item in self.attachments_to_send.attachments.children: | |
977 if item.sending: | |
978 # the item is already being sent | |
979 continue | |
980 item.sending = True | |
981 progress_id = item.data["progress_id"] = str(uuid.uuid4()) | |
982 attachments = extra.setdefault(C.MESS_KEY_ATTACHMENTS, []) | |
983 attachment = { | |
984 "path": str(item.data["path"]), | |
985 "progress_id": progress_id, | |
986 } | |
448
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
987 if 'media_type' in item.data: |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
988 attachment[C.MESS_KEY_ATTACHMENTS_MEDIA_TYPE] = item.data['media_type'] |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
989 |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
990 if ((self.attachments_to_send.reduce_checkbox.active |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
991 and attachment.get('media_type', '').split('/')[0] == 'image')): |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
992 attachment[C.MESS_KEY_ATTACHMENTS_RESIZE] = True |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
993 |
412 | 994 attachments.append(attachment) |
995 | |
996 Clock.schedule_once( | |
997 partial(self._attachmentProgressUpdate, item), | |
998 PROGRESS_UPDATE) | |
999 | |
1000 G.host.registerProgressCbs( | |
1001 progress_id, | |
1002 callback=partial(self._attachmentProgressCb, item), | |
1003 errback=partial(self._attachmentProgressEb, item) | |
1004 ) | |
1005 | |
1006 | |
22 | 1007 G.host.messageSend( |
1008 self.target, | |
412 | 1009 # TODO: handle language |
1010 {'': input_widget.text}, | |
1011 # TODO: put this in QuickChat | |
1012 mess_type= | |
1013 C.MESS_TYPE_GROUPCHAT if self.type == C.CHAT_GROUP else C.MESS_TYPE_CHAT, | |
1014 extra=extra, | |
22 | 1015 profile_key=self.profile |
1016 ) | |
1017 input_widget.text = '' | |
1018 | |
448
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1019 def _imageCheckCb(self, report_raw): |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1020 report = data_format.deserialise(report_raw) |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1021 if report['too_large']: |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1022 self.attachments_to_send.show_resize=True |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1023 self.attachments_to_send.reduce_checkbox.active=True |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1024 |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1025 def addAttachment(self, file_path, media_type=None): |
412 | 1026 file_path = Path(file_path) |
448
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1027 if media_type is None: |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1028 media_type = mimetypes.guess_type(file_path, strict=False)[0] |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1029 if not self.attachments_to_send.show_resize and media_type is not None: |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1030 # we check if the attachment is an image and if it's too large. |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1031 # If too large, the reduce size check box will be displayed, and checked by |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1032 # default. |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1033 main_type = media_type.split('/')[0] |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1034 if main_type == "image": |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1035 G.host.bridge.imageCheck( |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1036 str(file_path), |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1037 callback=self._imageCheckCb, |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1038 errback=partial( |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1039 G.host.errback, |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1040 title=_("Can't check image size"), |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1041 message=_("Can't check image at {path}: {{msg}}").format( |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1042 path=file_path), |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1043 ) |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1044 ) |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1045 |
412 | 1046 data = { |
1047 "path": file_path, | |
1048 "name": file_path.name, | |
1049 } | |
448
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1050 |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1051 if media_type is not None: |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1052 data['media_type'] = media_type |
20a807443c3f
chat: resize attachments (images only for now):
Goffi <goffi@goffi.org>
parents:
446
diff
changeset
|
1053 |
412 | 1054 self.attachments_to_send.attachments.add_widget( |
1055 AttachmentToSendItem(data=data) | |
1056 ) | |
283
c73a7cd36b54
chat: show warning note on failing fileUpload + added forgotten "profile" argument
Goffi <goffi@goffi.org>
parents:
282
diff
changeset
|
1057 |
322
e2b51663d8b8
core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
1058 def transferFile(self, file_path, transfer_type=C.TRANSFER_UPLOAD, cleaning_cb=None): |
412 | 1059 # 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
|
1060 if transfer_type == C.TRANSFER_UPLOAD: |
412 | 1061 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
|
1062 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
|
1063 if self.type == C.CHAT_GROUP: |
312 | 1064 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
|
1065 # 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
|
1066 # MUC |
98
4d8c122b86a6
menu (upload): send transfer (i.e. P2P transfer) is now working
Goffi <goffi@goffi.org>
parents:
97
diff
changeset
|
1067 else: |
4d8c122b86a6
menu (upload): send transfer (i.e. P2P transfer) is now working
Goffi <goffi@goffi.org>
parents:
97
diff
changeset
|
1068 jid_ = self.target |
4d8c122b86a6
menu (upload): send transfer (i.e. P2P transfer) is now working
Goffi <goffi@goffi.org>
parents:
97
diff
changeset
|
1069 if not jid_.resource: |
4d8c122b86a6
menu (upload): send transfer (i.e. P2P transfer) is now working
Goffi <goffi@goffi.org>
parents:
97
diff
changeset
|
1070 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
|
1071 G.host.bridge.fileSend(str(jid_), str(file_path), "", "", {}, |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
1072 profile=self.profile) |
98
4d8c122b86a6
menu (upload): send transfer (i.e. P2P transfer) is now working
Goffi <goffi@goffi.org>
parents:
97
diff
changeset
|
1073 # 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
|
1074 else: |
312 | 1075 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
|
1076 |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
1077 def messageEncryptionStarted(self, plugin_data): |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
1078 quick_chat.QuickChat.messageEncryptionStarted(self, plugin_data) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
1079 self.encryption_btn.symbol = SYMBOL_ENCRYPTED |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
1080 self.encryption_btn.color = COLOR_ENCRYPTED |
312 | 1081 self.encryption_btn.selectAlgo(plugin_data['name']) |
233
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
1082 |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
1083 def messageEncryptionStopped(self, plugin_data): |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
1084 quick_chat.QuickChat.messageEncryptionStopped(self, plugin_data) |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
1085 self.encryption_btn.symbol = SYMBOL_UNENCRYPTED |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
1086 self.encryption_btn.color = COLOR_UNENCRYPTED |
ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
Goffi <goffi@goffi.org>
parents:
225
diff
changeset
|
1087 self.encryption_btn.selectAlgo(None) |
78 | 1088 |
46
d6a63942d5ad
chat: fixed MUC joining following changes in backend
Goffi <goffi@goffi.org>
parents:
45
diff
changeset
|
1089 def _mucJoinCb(self, joined_data): |
338
d4883f9576db
chat: handle room statuses following backend change
Goffi <goffi@goffi.org>
parents:
334
diff
changeset
|
1090 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
|
1091 self.host.mucRoomJoinedHandler(*joined_data[1:]) |
d6a63942d5ad
chat: fixed MUC joining following changes in backend
Goffi <goffi@goffi.org>
parents:
45
diff
changeset
|
1092 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
|
1093 self.changeWidget(jid_) |
286865bc013a
chat: joining MUC using header input is now working:
Goffi <goffi@goffi.org>
parents:
41
diff
changeset
|
1094 |
286865bc013a
chat: joining MUC using header input is now working:
Goffi <goffi@goffi.org>
parents:
41
diff
changeset
|
1095 def _mucJoinEb(self, failure): |
312 | 1096 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
|
1097 |
122
dcd6fbb3f010
chat: handle new OTR state signal and change encryption icon consequently
Goffi <goffi@goffi.org>
parents:
121
diff
changeset
|
1098 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
|
1099 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
|
1100 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
|
1101 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
|
1102 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
|
1103 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
|
1104 else: |
312 | 1105 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
|
1106 return |
135
091e288838e1
plugin chat: use new Symbol widget to display encryption button
Goffi <goffi@goffi.org>
parents:
126
diff
changeset
|
1107 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
|
1108 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
|
1109 |
265
805c4103dac5
core: resync widgets only when they are visible:
Goffi <goffi@goffi.org>
parents:
261
diff
changeset
|
1110 def onVisible(self): |
805c4103dac5
core: resync widgets only when they are visible:
Goffi <goffi@goffi.org>
parents:
261
diff
changeset
|
1111 if not self.sync: |
805c4103dac5
core: resync widgets only when they are visible:
Goffi <goffi@goffi.org>
parents:
261
diff
changeset
|
1112 self.resync() |
805c4103dac5
core: resync widgets only when they are visible:
Goffi <goffi@goffi.org>
parents:
261
diff
changeset
|
1113 |
396
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
1114 def onSelected(self): |
ae6f7fd1cb0e
chat: use QuickApp.notify and clear notifications when selected.
Goffi <goffi@goffi.org>
parents:
395
diff
changeset
|
1115 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
|
1116 |
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
|
1117 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
|
1118 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
|
1119 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
|
1120 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
|
1121 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
|
1122 # 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
|
1123 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
|
1124 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
|
1125 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
|
1126 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
|
1127 return True |
261
a579eda31f4f
chat: don't use "force" argument anymore
Goffi <goffi@goffi.org>
parents:
260
diff
changeset
|
1128 # 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
|
1129 # TODO: delete all widgets when chat is closed |
a579eda31f4f
chat: don't use "force" argument anymore
Goffi <goffi@goffi.org>
parents:
260
diff
changeset
|
1130 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
|
1131 # 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
|
1132 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
|
1133 if nb_instances <= nb_to_keep: |
261
a579eda31f4f
chat: don't use "force" argument anymore
Goffi <goffi@goffi.org>
parents:
260
diff
changeset
|
1134 return False |
22 | 1135 |
326 | 1136 def _history_unlock(self, __): |
1137 self._history_prepend_lock = False | |
1138 log.debug("history prepend unlocked") | |
1139 # we call manually onScroll, to check if we are still in the scrolling zone | |
1140 self.onScroll(self.history_scroll, self.history_scroll.scroll_y) | |
1141 | |
1142 def _history_scroll_adjust(self, __, scroll_start_height): | |
1143 # history scroll position must correspond to where it was before new messages | |
1144 # have been appended | |
1145 self.history_scroll.scroll_y = ( | |
1146 scroll_start_height / self.messages_widget.height | |
1147 ) | |
1148 | |
1149 # we want a small delay before unlocking, to avoid re-fetching history | |
1150 # again | |
1151 Clock.schedule_once(self._history_unlock, 1.5) | |
1152 | |
1153 def _backHistoryGetCb_post(self, __, history, scroll_start_height): | |
1154 if len(history) == 0: | |
1155 # we don't unlock self._history_prepend_lock if there is no history, as there | |
1156 # is no sense to try to retrieve more in this case. | |
1157 log.debug(f"we've reached top of history for {self.target.bare} chat") | |
1158 else: | |
1159 # we have to schedule again for _history_scroll_adjust, else messages_widget | |
1160 # is not resized (self.messages_widget.height is not yet updated) | |
1161 # as a result, the scroll_to can't work correctly | |
1162 Clock.schedule_once(partial( | |
1163 self._history_scroll_adjust, | |
1164 scroll_start_height=scroll_start_height)) | |
1165 log.debug( | |
1166 f"{len(history)} messages prepended to history (last: {history[0][0]})") | |
1167 | |
1168 def _backHistoryGetCb(self, history): | |
1169 # TODO: factorise with QuickChat._historyGetCb | |
1170 scroll_start_height = self.messages_widget.height * self.history_scroll.scroll_y | |
1171 for data in reversed(history): | |
409
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
1172 uid, timestamp, from_jid, to_jid, message, subject, type_, extra_s = data |
326 | 1173 from_jid = jid.JID(from_jid) |
1174 to_jid = jid.JID(to_jid) | |
409
2caea63ae2ab
chat: show attachments as clickable icons
Goffi <goffi@goffi.org>
parents:
406
diff
changeset
|
1175 extra = data_format.deserialise(extra_s) |
326 | 1176 extra["history"] = True |
1177 self.messages[uid] = message = quick_chat.Message( | |
1178 self, | |
1179 uid, | |
1180 timestamp, | |
1181 from_jid, | |
1182 to_jid, | |
1183 message, | |
1184 subject, | |
1185 type_, | |
1186 extra, | |
1187 self.profile, | |
1188 ) | |
1189 self.messages.move_to_end(uid, last=False) | |
1190 self.prependMessage(message) | |
1191 Clock.schedule_once(partial( | |
1192 self._backHistoryGetCb_post, | |
1193 history=history, | |
1194 scroll_start_height=scroll_start_height)) | |
1195 | |
1196 def _backHistoryGetEb(self, failure_): | |
1197 G.host.addNote( | |
1198 _("Problem while getting back history"), | |
1199 _("Can't back history for {target}: {problem}").format( | |
1200 target=self.target, problem=failure_), | |
1201 C.XMLUI_DATA_LVL_ERROR) | |
1202 # we don't unlock self._history_prepend_lock on purpose, no need | |
1203 # to try to get more history if something is wrong | |
1204 | |
1205 def onScroll(self, scroll_view, scroll_y): | |
1206 if self._history_prepend_lock: | |
1207 return | |
1208 if (1-scroll_y) * self.messages_widget.height < INFINITE_SCROLL_LIMIT: | |
1209 self._history_prepend_lock = True | |
1210 log.debug(f"Retrieving back history for {self} [{self.history_count}]") | |
1211 self.history_count += 1 | |
1212 first_uid = next(iter(self.messages.keys())) | |
1213 filters = self.history_filters.copy() | |
1214 filters['before_uid'] = first_uid | |
1215 self.host.bridge.historyGet( | |
1216 str(self.host.profiles[self.profile].whoami.bare), | |
1217 str(self.target), | |
1218 30, | |
1219 True, | |
1220 {k: str(v) for k,v in filters.items()}, | |
1221 self.profile, | |
1222 callback=self._backHistoryGetCb, | |
1223 errback=self._backHistoryGetEb, | |
1224 ) | |
1225 | |
22 | 1226 |
395
c04c3b167cb0
chat: use header input to filter entities + open a new chat with unknown jid.
Goffi <goffi@goffi.org>
parents:
394
diff
changeset
|
1227 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
|
1228 jid_selector = properties.ObjectProperty() |
354 | 1229 profile = properties.StringProperty() |
1230 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
|
1231 use_header_input = True |
354 | 1232 |
1233 def on_select(self, contact_button): | |
1234 contact_jid = jid.JID(contact_button.jid) | |
1235 plugin_info = G.host.getPluginInfo(main=Chat) | |
1236 factory = plugin_info['factory'] | |
1237 self.screen_manager.transition.direction = 'up' | |
1238 carousel = self.whwrapper.carousel | |
1239 current_slides = {w.target: w for w in carousel.slides} | |
1240 if contact_jid in current_slides: | |
1241 slide = current_slides[contact_jid] | |
1242 idx = carousel.slides.index(slide) | |
1243 carousel.index = idx | |
1244 self.screen_manager.current = '' | |
1245 else: | |
1246 G.host.switchWidget( | |
1247 self, factory(plugin_info, contact_jid, profiles=[self.profile])) | |
1248 | |
1249 | |
395
c04c3b167cb0
chat: use header input to filter entities + open a new chat with unknown jid.
Goffi <goffi@goffi.org>
parents:
394
diff
changeset
|
1250 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
|
1251 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
|
1252 try: |
c04c3b167cb0
chat: use header input to filter entities + open a new chat with unknown jid.
Goffi <goffi@goffi.org>
parents:
394
diff
changeset
|
1253 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
|
1254 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
|
1255 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
|
1256 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
|
1257 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
|
1258 return |
c04c3b167cb0
chat: use header input to filter entities + open a new chat with unknown jid.
Goffi <goffi@goffi.org>
parents:
394
diff
changeset
|
1259 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
|
1260 |
c04c3b167cb0
chat: use header input to filter entities + open a new chat with unknown jid.
Goffi <goffi@goffi.org>
parents:
394
diff
changeset
|
1261 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
|
1262 """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
|
1263 for layout in self.jid_selector.items_layouts: |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
1264 self.do_filter( |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
1265 layout, |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
1266 text, |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
1267 # we append nick to jid to filter on both |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
1268 lambda c: c.jid + c.data.get('nick', ''), |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
1269 width_cb=lambda c: c.base_width, |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
1270 height_cb=lambda c: c.minimum_height, |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
396
diff
changeset
|
1271 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
|
1272 |
c04c3b167cb0
chat: use header input to filter entities + open a new chat with unknown jid.
Goffi <goffi@goffi.org>
parents:
394
diff
changeset
|
1273 |
22 | 1274 PLUGIN_INFO["factory"] = Chat.factory |
1275 quick_widgets.register(quick_chat.QuickChat, Chat) |