Compare commits

...

296 Commits

Author SHA1 Message Date
adbenitez f76b1cb3d3 change call icon to videocall 2025-10-23 14:15:42 +02:00
adbenitez 98551713ae Merge remote-tracking branch 'upstream/main' 2025-10-23 14:06:32 +02:00
Hocuri bc2e4002c3 refactor: Remove stock string that is rarely used these days (#3957) 2025-10-21 09:09:47 +00:00
adb 40b8f1297e Merge pull request #3955 from deltachat/prep-2.22.0
prepare 2.22.0
2025-10-20 16:24:09 +02:00
adbenitez 84f8a39355 prepare 2.22.0 2025-10-19 18:00:43 +02:00
Hocuri 6874191143 fix: Remove warning about unknown architecture in PR preview builds (#3951)
Co-authored-by: adb <adb@merlinux.eu>
2025-10-18 12:12:03 +02:00
adb aea7e912e0 Merge pull request #3953 from deltachat/update-core-and-stuff-17/10/25
Update core to 2.22
2025-10-17 14:56:17 +02:00
adbenitez 4f8068f144 update translations 2025-10-17 14:42:30 +02:00
adbenitez 4f4e42e20c update changelog 2025-10-17 14:39:11 +02:00
adbenitez 8ddb51382e update deltachat-core-rust to 'chore(release): prepare for 2.22.0' of 'v2.22.0' 2025-10-17 14:36:53 +02:00
adb 252263e6db Merge pull request #3949 from deltachat/adb/improve-readme
improve readme
2025-10-16 18:04:51 +02:00
adb 4efdc0b1c8 Update BUILDING.md
Co-authored-by: bjoern <r10s@b44t.com>
2025-10-16 16:03:34 +00:00
adb 30858c51d6 Update README.md
Co-authored-by: bjoern <r10s@b44t.com>
2025-10-16 16:02:49 +00:00
adb 42cd1c6ad1 Merge branch 'main' into adb/improve-readme 2025-10-16 17:12:34 +02:00
B. Petersen e6b40adf8a remove 1 year old mute-migration from global-setting to profile-setting; if ppl did not upgrade since then, they do not care much 2025-10-16 16:57:55 +02:00
B. Petersen 500e5a910d verified_one_on_one_chats option was removed in core 2.17 2025-10-16 16:57:55 +02:00
adbenitez fe3f34222d improve downloads hints 2025-10-16 16:54:01 +02:00
adbenitez 408c7ae727 update chatmail core link 2025-10-16 16:44:52 +02:00
adbenitez 5198191728 move building to its own file 2025-10-16 16:44:26 +02:00
adb 6f2cc60017 Merge pull request #3942 from deltachat/adb/remove-duplicate-classes
remove duplicated ListenableFuture and SettableFuture
2025-10-16 14:21:50 +02:00
adb 091cb931d7 Merge branch 'main' into adb/remove-duplicate-classes 2025-10-16 14:10:20 +02:00
adb 26ec26e75c Merge pull request #3946 from deltachat/prep-2.20.0
prepare 2.20.0
2025-10-16 14:08:54 +02:00
adbenitez 1b0b87f148 update build.gradle 2025-10-15 18:19:26 +02:00
adbenitez 9dbb918ed8 update changelog 2025-10-13 16:30:42 +02:00
adbenitez a955d6f2f7 Merge remote-tracking branch 'upstream/main' 2025-10-13 16:28:46 +02:00
adbenitez 42f8eb9153 update version number 2025-10-13 16:08:29 +02:00
adb 2143bc01d1 Merge pull request #3945 from deltachat/update-core-and-stuff-13/10/25
Update core to 2.20.0
2025-10-13 16:07:51 +02:00
adbenitez 5a3728428b update changelog 2025-10-13 15:47:38 +02:00
adbenitez f236085b92 update deltachat-core-rust to 'chore(release): prepare for 2.20.0' of 'v2.20.0' 2025-10-13 15:44:58 +02:00
adb ac6119792f Merge branch 'main' into adb/remove-duplicate-classes 2025-10-10 18:04:47 +02:00
adb b0cea8f099 Merge pull request #3943 from deltachat/update-core-and-stuff-10/10/25
Update core to 2.18.0
2025-10-10 18:04:23 +02:00
adbenitez 7590b21928 update version number and strings 2025-10-10 17:39:05 +02:00
adbenitez ea7fd0ec22 update deltachat-core-rust to 'chore(release): prepare for 2.18.0' of 'v2.18.0' 2025-10-10 15:57:51 +02:00
adbenitez cf4cb2f839 remove duplicated ListenableFuture and SettableFuture 2025-10-10 15:38:25 +02:00
adb 6a4e40d17b Merge pull request #3937 from deltachat/link2xt/recommend-lix-instead-of-determinate-nix-installer
Recommend Lix instead of Determinate Nix Installer
2025-10-10 15:28:02 +02:00
adb 5302e86011 Merge pull request #3938 from deltachat/adb/speedup-ci
speed up the PR's apk preview building
2025-10-10 13:30:18 +02:00
adb 5382e880a9 Merge branch 'main' into adb/speedup-ci 2025-10-10 12:29:24 +02:00
adb 2385b236c7 Merge pull request #3940 from deltachat/prep-2.17.0
update build.gradle
2025-10-10 12:28:30 +02:00
adbenitez 5224119f9e update build.gradle 2025-10-09 20:09:12 +02:00
adb dfef2b4120 Merge pull request #3939 from deltachat/update-translations-9/10/25
update translations
2025-10-09 20:05:55 +02:00
adbenitez 6d7f417233 update translations 2025-10-09 20:04:07 +02:00
adb 05ef95e757 Merge branch 'main' into adb/speedup-ci 2025-10-09 18:45:54 +02:00
adbenitez 8aa45b7bc9 speed up the PR's apk preview building 2025-10-09 16:49:29 +02:00
link2xt 7cea23caf5 Recommend Lix instead of Determinate Nix Installer
Determinate Systems server is installing its own fork of Nix
that is apparently not open source:
<https://lobste.rs/s/be78ef/dropping_upstream_nix_from_determinate#c_m3hq6r>
The company behind it also pushes the users to use FlakeHub
and has other problems.

[Lix] installer is a fork of The Determinate Nix Installer.
I uninstalled Nix preivously installed with The Determinate Nix Installer
and installed Lix, it works just the same for Android builds.

Upstream Nix would also be fine,
but it still has old installer that does not enable Flakes
and breaks on macOS on upgrades apparently,
so we cannot recommend it as the easiest way.

[Lix]: https://lix.systems/
2025-10-09 14:08:03 +00:00
adbenitez 4a2bed3e6c Merge remote-tracking branch 'upstream/main' 2025-10-09 15:39:22 +02:00
adbenitez 3aa2fbf67a Merge remote-tracking branch 'upstream/main' 2025-10-09 15:34:30 +02:00
adb c5d9471f2a Merge pull request #3936 from deltachat/adb/remove-awebp-dep
remove dependency for awebp, it is supported by Android
2025-10-09 15:01:38 +02:00
adb 5117b70c58 Merge pull request #3935 from deltachat/adb/deprecated-videochat-stock
don't set deprecated/unused stock strings
2025-10-09 14:27:54 +02:00
adbenitez da4d17aa14 remove dependency for awebp, it is supported by Android 2025-10-09 14:22:51 +02:00
adbenitez 6135813bff don't set deprecated/unused stock strings 2025-10-09 14:08:08 +02:00
adb 8547f7aab8 Merge pull request #3934 from deltachat/adb/update-calls-webapp-v0.10.0-beta
update calls webapp to v0.10.0-beta
2025-10-08 20:02:41 +02:00
adb 6dca20045c Merge branch 'main' into adb/update-calls-webapp-v0.10.0-beta 2025-10-08 19:17:17 +02:00
adbenitez 58ef777091 update calls webapp to v0.10.0-beta 2025-10-08 19:16:12 +02:00
B. Petersen 4a836b3d82 string 'Calls' not used at all 2025-10-08 19:11:09 +02:00
B. Petersen 363122fd15 clarify some strings 2025-10-08 19:11:09 +02:00
adb b751219c78 Merge pull request #3785 from deltachat/adb/integrated-videocalls
Android calls UI
2025-10-08 18:36:19 +02:00
adbenitez e586fafc54 tweak call footer's date format 2025-10-08 16:58:27 +02:00
adbenitez 2c04319c52 Merge branch 'adb/integrated-videocalls' of https://github.com/deltachat/deltachat-android into adb/integrated-videocalls 2025-10-08 16:45:55 +02:00
adbenitez f9607e4453 tweak call message-type colors 2025-10-08 16:45:17 +02:00
adb 6aec209ebc Update src/main/res/values/strings.xml
Co-authored-by: bjoern <r10s@b44t.com>
2025-10-08 14:31:33 +00:00
adbenitez 9adc9b34e5 fix string 2025-10-08 15:58:32 +02:00
adb 9267501bc1 Merge branch 'main' into adb/integrated-videocalls 2025-10-08 15:47:00 +02:00
adb 924c3f8920 Update src/main/java/org/thoughtcrime/securesms/preferences/AdvancedPreferenceFragment.java
Co-authored-by: bjoern <r10s@b44t.com>
2025-10-08 13:45:21 +00:00
adb 8f93dacbff Update src/main/res/xml/preferences_advanced.xml
Co-authored-by: bjoern <r10s@b44t.com>
2025-10-08 13:40:10 +00:00
adb a07e9312ea Merge pull request #3932 from deltachat/adb/issue-3930
process permissions result in GroupCreateActivity
2025-10-08 12:48:26 +02:00
adbenitez 79f6010d5f update changelog 2025-10-08 12:08:39 +02:00
adbenitez c5af1d4f2b process permissions result in GroupCreateActivity 2025-10-08 12:05:38 +02:00
adb 20a3820871 Merge pull request #3931 from deltachat/adb/media-preview-edge2edge
fix edge-to-edge in MediaPreviewActivity
2025-10-08 11:52:08 +02:00
adb cb0d1106b4 Merge branch 'main' into adb/media-preview-edge2edge 2025-10-08 11:19:52 +02:00
adb 291ef86a4f Merge branch 'main' into adb/integrated-videocalls 2025-10-08 11:17:40 +02:00
adb b0457bc036 Merge pull request #3925 from deltachat/adb/new-rpc-bindings
use auto-generated RPC bindings
2025-10-08 11:17:01 +02:00
adbenitez 4d7107314a fix edge-to-edge in MediaPreviewActivity 2025-10-07 19:15:07 +02:00
adbenitez 4185219088 update calls webapp to v0.9.0-beta 2025-10-07 14:32:18 +02:00
adb ef51492d0b Merge branch 'main' into adb/new-rpc-bindings 2025-10-06 18:20:00 +02:00
adbenitez 4dc10f977e update calls-webapp 0.8.0 2025-10-06 16:06:49 +02:00
adbenitez aaba52dba6 Merge branch 'adb/integrated-videocalls' of https://github.com/deltachat/deltachat-android into adb/integrated-videocalls 2025-10-06 15:51:22 +02:00
adbenitez ca4808aaca tweak strings 2025-10-06 15:51:10 +02:00
adb 66324fe914 Merge branch 'adb/new-rpc-bindings' into adb/integrated-videocalls 2025-10-06 15:49:19 +02:00
adbenitez a5f67e9d9f update core to 2.17.0 2025-10-06 15:48:22 +02:00
B. Petersen 8b5c887402 add 'Save Message' string
the string can be used for the action to put a message to 'Saved Messages'.

it will be useful esp. on desktop,
where plain 'Save' often has the mindset of 'Files',
esp. for older ppl :)
the added noun tries to break that.

additionally, desktop can resort menu items,
but that alone would not solve the issue.

there are also thoughs about renaming that alltogether,
eg. to bookmark, but that is a larger and more breaking change,
also the messages are not just 'bookmarked' on purpose,
to eg. survive auto deletion.
2025-10-03 14:33:20 +02:00
adbenitez 183cb03577 set new calls-related stock strings 2025-10-02 17:09:28 +02:00
adbenitez b1e6d59ba9 now it is CallState.Canceled not CallState.Cancelled 2025-10-02 17:05:43 +02:00
adb 33f38889c1 Merge branch 'adb/new-rpc-bindings' into adb/integrated-videocalls 2025-10-02 15:45:19 +02:00
adbenitez f97e800907 update core 2025-10-02 15:44:49 +02:00
adbenitez 21e597d09e add instructions on JSON-RPC binding generation 2025-10-02 15:28:21 +02:00
adbenitez 6b040b160d update changelog 2025-10-02 15:11:00 +02:00
adbenitez 57e5523bf3 update core to v2.16.0 2025-10-02 15:07:01 +02:00
adbenitez 874492c9ae update calls web-app 2025-10-01 16:16:52 +02:00
adbenitez 8ae6407461 add call duration to message bubble 2025-09-30 22:41:14 +02:00
adbenitez ae8ce94c00 add spaces around == 2025-09-30 22:39:37 +02:00
adbenitez 74208fff69 update CallInfo 2025-09-30 22:37:47 +02:00
adbenitez 7ace2b9baf add spaces arround == 2025-09-30 20:46:01 +02:00
adbenitez f28fffb9df update core 2025-09-30 20:07:47 +02:00
adbenitez 349e8d80c8 hide delivery status if not sending or error 2025-09-30 17:30:38 +02:00
adbenitez 4b9217e3e6 rename calls package 2025-09-30 16:29:47 +02:00
adbenitez 4e6e805ede remove unused old videochat invitation API 2025-09-30 15:59:58 +02:00
adbenitez 02a1c86f01 allow to pick call and call back by clicking call messages 2025-09-27 19:43:00 +02:00
adbenitez b28fb4ac9e update calls webapp 2025-09-27 19:36:35 +02:00
adbenitez fddc80e60b use new call_info RPC API 2025-09-27 01:09:50 +02:00
adb e5b1becf13 Merge branch 'adb/new-rpc-bindings' into adb/integrated-videocalls 2025-09-27 01:02:32 +02:00
adbenitez 01b78e37fd update src/main/java/chat/delta/rpc/types/CallState.java 2025-09-27 01:02:06 +02:00
adbenitez d0b1f36f60 fix imports, import from new Rpc package 2025-09-27 00:17:34 +02:00
adb e388464d28 Merge branch 'adb/new-rpc-bindings' into adb/integrated-videocalls 2025-09-27 00:14:07 +02:00
adbenitez afc7a04b63 revert changes in Rpc class 2025-09-27 00:13:13 +02:00
adbenitez b871e42b86 use auto-generated RPC bindings 2025-09-26 23:40:26 +02:00
adbenitez 3479233f82 offer incoming call when clicking on the notification 2025-09-26 18:00:06 +02:00
adbenitez 7e3e35a9a1 update calls-app to 0.6.0-beta 2025-09-26 17:47:35 +02:00
adbenitez 92711444e4 update calls-app to 0.6.0-beta 2025-09-26 17:25:47 +02:00
adb ec576d7159 Merge branch 'main' into adb/integrated-videocalls 2025-09-24 16:29:51 +02:00
adb 70a05221ab Merge pull request #3924 from deltachat/adb/update-workflows
update workflows and fix adding artifact link as comment to PRs
2025-09-24 16:29:27 +02:00
adbenitez 6335cfa178 update workflows and fix adding artifact link as comment to PRs 2025-09-24 15:35:55 +02:00
adbenitez ebda8c4577 hide calls button in "Saved Messages" and "Device Messages" 2025-09-24 14:23:52 +02:00
adbenitez de9a2df1b4 update DeclineCallReceiver.java 2025-09-22 18:43:20 +02:00
adbenitez a3c7e3db3d use RPC for call API 2025-09-22 18:33:59 +02:00
adbenitez 249fc829be fix constant numbering in ConversationAdapter.java 2025-09-22 17:44:27 +02:00
adb 5b62f7bf25 Merge pull request #3920 from deltachat/adb/issue-3916
improve displaying of call messages
2025-09-19 20:17:54 +02:00
adbenitez df6c858b92 improve displaying of calls messages 2025-09-19 18:44:06 +02:00
adbenitez c9816ae785 don't allow to edit call messages 2025-09-19 14:29:46 +02:00
adbenitez a24069ce3d ask for required permissions in incoming call 2025-09-17 19:27:45 +02:00
adbenitez f770f817d0 tweak preference name 2025-09-17 17:52:00 +02:00
adbenitez bee804e095 update to new calls-app's API 2025-09-12 18:59:34 +02:00
adbenitez 6b1c6b37ac add support for calls.getIceServers() and calls.getAvatar() 2025-09-12 15:59:00 +02:00
adbenitez 881e69c176 remove unused code 2025-09-11 21:58:54 +02:00
adbenitez ac6df2ff85 update changelog 2025-09-11 21:50:03 +02:00
adbenitez 7698ac5c06 some tweaks 2025-09-11 21:44:15 +02:00
adbenitez c2abe42b60 don't reject call on notification dismiss 2025-09-11 16:50:28 +02:00
adbenitez 3e95197d02 tweak calls channel 2025-09-11 16:33:15 +02:00
adbenitez 534a75feaa remove notification on accepted call 2025-09-11 13:22:21 +02:00
adbenitez 7a11234431 go back to chat after finishing call 2025-09-10 21:04:08 +02:00
adbenitez 0e91537a4d allow to decline calls and remove call notification 2025-09-10 20:47:25 +02:00
adbenitez b074bf1819 allow to answer from notification 2025-09-10 18:55:19 +02:00
adbenitez b8d2552aa8 remove unused imports 2025-09-10 16:04:55 +02:00
adbenitez 320c120a61 don't use calls integration API 2025-09-10 13:01:05 +02:00
adbenitez 6c1a3c850a tweak preview-apk workflow 2025-09-09 18:18:05 +02:00
adbenitez 7ec87f55b6 auto-accept calls for testing 2025-09-09 17:39:29 +02:00
adbenitez f6ce98f9a2 remove DC_MSG_VIDEOCHAT_INVITATION 2025-09-09 16:10:42 +02:00
adbenitez cb465ec85e remove outdated info message types 2025-09-09 15:16:56 +02:00
adbenitez 6f10a90c5f update calls webapp 0.4.0-beta 2025-09-09 14:58:05 +02:00
adb 9f439c852f Merge branch 'main' into adb/integrated-videocalls 2025-09-09 13:48:53 +02:00
adbenitez 2cc0451a8a update core 2025-09-09 13:48:40 +02:00
adb 02230d05a1 Merge pull request #3912 from deltachat/update-core-and-stuff-9/9/25
Update core to 2.13.0
2025-09-09 13:47:39 +02:00
adbenitez 9a6f6d7ea6 update strings 2025-09-09 13:45:24 +02:00
adbenitez f4cd299f70 update changelog 2025-09-09 13:35:49 +02:00
adbenitez d0358a4d0c update deltachat-core-rust to 'chore(release): prepare for 2.13.0' of 'v2.13.0' 2025-09-09 13:23:33 +02:00
adbenitez 4fc115b93d add basic notification 2025-09-09 13:22:20 +02:00
adbenitez 0157510c5d don't ask to start call 2025-09-06 21:39:06 +02:00
adbenitez 831ce19689 update core 2025-09-05 18:43:16 +02:00
adbenitez 9431e26696 end call on closing webview 2025-09-05 14:58:10 +02:00
adbenitez 9ef01dd352 add calls button 2025-09-03 16:07:19 +02:00
adbenitez 01c766db41 remove old videochat invitations 2025-09-03 16:02:09 +02:00
adb 364d15442a Merge branch 'main' into adb/integrated-videocalls 2025-09-03 14:21:53 +02:00
adb 32eefaab42 Merge pull request #3908 from deltachat/adb/issue-3893
show warning if background notifications will be unreliable
2025-09-02 18:12:46 +02:00
adb 4b8177f7f0 Merge branch 'main' into adb/issue-3893 2025-09-02 18:12:24 +02:00
B. Petersen 092a5caf8b deprecate another string 2025-09-02 18:11:39 +02:00
B. Petersen bfe4438773 deprecate some strings 2025-09-02 18:11:39 +02:00
adbenitez d251fffc07 update changelog 2025-09-02 17:37:22 +02:00
adb 180c2bc8de Merge branch 'main' into adb/issue-3893 2025-09-02 17:35:57 +02:00
adb 082815f676 Merge pull request #3910 from deltachat/adb/issue-3907
disable clone option for incoming channel
2025-09-02 17:02:07 +02:00
adbenitez 640688d774 update code to new calls app path 2025-09-02 14:59:06 +02:00
adbenitez 30868198a2 update calls webapp 2025-09-02 14:17:30 +02:00
adb 75673ef1ad Merge branch 'main' into adb/integrated-videocalls 2025-09-02 14:15:25 +02:00
adbenitez 478d937b3c tweak behavior 2025-09-02 00:01:36 +02:00
adb 7a5eb6bea6 Update src/main/res/values/strings.xml
Co-authored-by: bjoern <r10s@b44t.com>
2025-09-01 14:46:45 +00:00
adbenitez 0142d51835 update changelog 2025-09-01 16:45:51 +02:00
adbenitez 075bad3638 hide member list on incoming channels 2025-09-01 16:44:51 +02:00
adbenitez 1f173bae9b disable clone option for incoming channel 2025-09-01 16:33:52 +02:00
adbenitez 2deb61477f show warning if background notifications will be unreliable 2025-09-01 15:52:10 +02:00
adb fcc1ab1079 Merge pull request #3899 from deltachat/link2xt/nix-35
nix: update to Android platform 35
2025-08-27 17:14:25 +02:00
link2xt c72207da8a nix: update to Android platform 35 2025-08-27 00:32:50 +00:00
adb 82233d7862 Merge pull request #3898 from deltachat/adb/issue-3894
default to permanent notification if push is not possible
2025-08-26 16:26:28 +02:00
adbenitez 2547a0435c improve preference handling 2025-08-26 15:54:09 +02:00
adbenitez b6ce6d908f Merge branch 'adb/issue-3894' of https://github.com/deltachat/deltachat-android into adb/issue-3894 2025-08-26 13:24:04 +02:00
adbenitez c6bbb0a524 improve code 2025-08-26 13:23:54 +02:00
adb 826258a1be Merge branch 'main' into adb/issue-3894 2025-08-22 17:42:41 +02:00
B. Petersen 05dde13e68 update CHANGELOG 2025-08-22 17:35:32 +02:00
B. Petersen 06130c7cd8 fix initial selection 2025-08-22 17:35:32 +02:00
B. Petersen 5d7c701da8 drop disappearing messages options 1 and 30 minutes
- with the recent change to start the timer when the chat is opened,
  one minute is too easy too short to miss important information

- "30 minutes" does not really fit into the distribution;
  all other option have at least the factor 5 to the previous one,
  from "30 minutes" to "60 minutes", the time is doubled only.

removing the overall number of options and dropping the ones without larger usecases,
does not only simplifies UI;
having less tiny details also reduces noise in groups
where ppl people changing it very often for various weird reasons
(found the latter point somewhere in the Signal forum, btw)
2025-08-22 17:35:32 +02:00
adbenitez 91e898ee96 update changelog 2025-08-22 16:39:33 +02:00
adb 61e9466c59 Merge branch 'main' into adb/issue-3894 2025-08-22 16:38:37 +02:00
adbenitez 39c48d3dcd default to permanent notification if push is not possible 2025-08-22 16:36:00 +02:00
adbenitez 1c7c3f06e6 prototype with TelecomManager and ConnectionService APIs 2025-08-22 15:17:32 +02:00
B. Petersen d4ddb68137 remove deprecated strings 2025-08-20 17:47:07 +02:00
adbenitez c9ac421315 update call.html 2025-08-19 14:00:51 +02:00
adb e14bf24bb1 Merge branch 'main' into adb/integrated-videocalls 2025-08-18 15:22:52 +02:00
adb 700d11f600 Merge pull request #3889 from deltachat/adb/issue-3688
avoid superfluous error message when user cancel configuration
2025-08-18 15:12:16 +02:00
adbenitez fbb33c735c Merge branch 'adb/integrated-videocalls' of https://github.com/deltachat/deltachat-android into adb/integrated-videocalls 2025-08-18 14:58:46 +02:00
adbenitez 7cc9d7ea2f update core 2025-08-18 14:58:35 +02:00
adb ca27be240e Merge branch 'main' into adb/integrated-videocalls 2025-08-18 14:53:03 +02:00
adbenitez 8ab9b92517 update core 2025-08-18 14:47:57 +02:00
adbenitez f95b48ad6a Merge remote-tracking branch 'upstream/main' 2025-08-17 19:31:59 +02:00
adbenitez 8ebdc5414a update changelog 2025-08-17 18:33:03 +02:00
adbenitez a0e07cb2ea avoid superfluous error message when user cancel configuration 2025-08-17 18:30:22 +02:00
adb 152360d94a Merge pull request #3888 from deltachat/adb/issue-3853
fix direct share shortcuts
2025-08-16 21:31:26 +02:00
adbenitez 8513f7cd36 update changelog 2025-08-16 20:18:12 +02:00
adbenitez 17e3f3afdd fix direct share shortcuts 2025-08-16 20:10:53 +02:00
adb 7d7f62dae1 Merge pull request #3814 from deltachat/adb/issue-3795
target SDK 35 and implement edge-to-edge
2025-08-16 19:24:50 +02:00
adb 2bd0a0d935 Merge branch 'main' into adb/issue-3795 2025-08-16 17:08:37 +02:00
B. Petersen cf0414dd66 update CHANGELOG 2025-08-16 17:02:41 +02:00
B. Petersen 5fbd065882 improve info messages for dark theme
this improves readability of info messages
by setting the foreground to while.
`universal_overlay` was made for that;
it is in use like that on iOS/desktop since a long time.

moreover, other parts using the combination of
`conversation_item_update_bg_color`/`conversation_item_update_text_color`
are improved equally, eg. the day titles.
2025-08-16 17:02:41 +02:00
adb 5982a9dd8f Merge branch 'main' into adb/issue-3795 2025-08-16 16:15:59 +02:00
adbenitez 4b20e3f41f update changelog 2025-08-16 16:15:23 +02:00
adb ac8d8886cc Merge pull request #3885 from deltachat/link2xt/build-tools-35
Update Android SDK Build Tools to 35.0.0 in flake.nix
2025-08-16 16:13:58 +02:00
adbenitez a803d472bf don't use setStatusBarColor 2025-08-16 03:19:37 +02:00
adbenitez 396ed14067 adapt activities to edge-to-edge 2025-08-16 02:10:02 +02:00
adbenitez 5faea5e40a revert empty line 2025-08-15 23:24:19 +02:00
adbenitez 08bb248919 revert status bar color hack 2025-08-15 23:23:02 +02:00
link2xt 30dd7a9c33 Update Android SDK Build Tools to 35.0.0 in flake.nix
Since buildToolsVersion is not specified in `build.gradle`,
default version is set by Android Gradle Plugin.
Gradle plugin was updated in a77b1a5dd6,
so build tools version should be updated in flake.nix
to the corresponding version, otherwise building
fails while trying to install 35.0.0 into
read-only path managed by Nix.
2025-08-14 16:13:49 +00:00
adb 28f57a2ccb Merge branch 'main' into adb/issue-3795 2025-08-14 16:25:04 +02:00
adbenitez c0717237ad Merge remote-tracking branch 'upstream/main' 2025-08-13 16:28:56 +02:00
adb 5716372453 Merge pull request #3884 from deltachat/prep-2.11.0
prepare 2.11.0
2025-08-13 14:45:56 +02:00
adbenitez d362cf4467 bump version 2025-08-13 14:45:06 +02:00
adb 56118d3732 Merge pull request #3883 from deltachat/imgbot
[ImgBot] Optimize images
2025-08-13 14:00:48 +02:00
adb a03f51f7c5 Merge pull request #3875 from deltachat/adb/issue-3874
avoid NPE in DecryptableUri
2025-08-13 13:56:49 +02:00
ImgBotApp 6cf59133c2 [ImgBot] Optimize images
*Total -- 3,963.23kb -> 2,946.99kb (25.64%)

/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png -- 981.79kb -> 657.29kb (33.05%)
/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png -- 481.97kb -> 350.50kb (27.28%)
/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png -- 357.58kb -> 272.44kb (23.81%)
/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png -- 967.63kb -> 750.70kb (22.42%)
/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png -- 1,174.26kb -> 916.06kb (21.99%)

Signed-off-by: ImgBotApp <ImgBotHelp@gmail.com>
2025-08-13 11:56:18 +00:00
adb ef8d833f5e Merge branch 'main' into adb/issue-3874 2025-08-13 13:55:37 +02:00
adb b110c1f91e Merge pull request #3467 from deltachat/adb/issue-3437
add "After 1 year" option to disappearing messages
2025-08-13 13:55:04 +02:00
adbenitez e53a1f0b22 update changelog 2025-08-13 13:54:41 +02:00
adb 5a5cbfceb7 Merge branch 'main' into adb/issue-3437 2025-08-13 13:47:42 +02:00
adb 57a557a9b4 Merge pull request #3882 from deltachat/update-core-and-stuff-13/8/25
update core to 2.11.0
2025-08-13 13:45:20 +02:00
adbenitez 2328bf1e2a update translations 2025-08-13 13:44:34 +02:00
adbenitez ce4c9aaba0 update changelog 2025-08-13 13:18:54 +02:00
adbenitez 71a2cb7a5b update deltachat-core-rust to 'chore(release): prepare for 2.11.0' of 'v2.11.0' 2025-08-13 13:11:36 +02:00
adb 79462c0596 Merge branch 'main' into adb/issue-3795 2025-08-12 17:16:36 +02:00
adb 68f5d1ae27 Merge pull request #3881 from deltachat/adb/dont-use-android.R.id.content
don't use android.R.id.content
2025-08-12 16:34:31 +02:00
adbenitez 77caced5ed don't use android.R.id.content 2025-08-12 15:56:25 +02:00
adb 88a4f99cf8 Merge branch 'main' into adb/issue-3795 2025-08-12 15:19:37 +02:00
B. Petersen 42544fd447 update translations 2025-08-12 14:57:13 +02:00
adb 5ff869cd4a Merge pull request #3879 from deltachat/adb/issue-3878
call dcContext.deleteMsgs() in background thread
2025-08-09 16:35:00 +02:00
adbenitez 4af1666a31 call dcContext.deleteMsgs() in background thread 2025-08-09 16:01:46 +02:00
adbenitez 786fd3f47d avoid NPE in DecryptableUri 2025-08-09 15:24:02 +02:00
adb a0d9315ff4 Merge pull request #3873 from deltachat/adb/improve-screenshots
update screenshots
2025-08-09 00:51:07 +02:00
adbenitez 86954a3c42 update screenshots 2025-08-09 00:15:05 +02:00
adb f136b6d7d1 Merge branch 'main' into adb/issue-3795 2025-08-08 15:44:23 +02:00
adbenitez 9e4b744046 set ephemeral timer stock strings for 1 year 2025-08-08 15:36:24 +02:00
adb 8db4604224 Merge branch 'main' into adb/issue-3437 2025-08-08 15:12:01 +02:00
adb 43f9094c04 Merge pull request #3872 from deltachat/r10s/allow-cloning-email-chats
allow to clone email chats
2025-08-08 15:08:56 +02:00
adb 1217e65889 Merge branch 'main' into adb/issue-3437 2025-08-08 15:08:28 +02:00
adb d8eaf0ad4b Merge branch 'main' into adb/issue-3795 2025-08-08 15:04:52 +02:00
adb 4fbb8d2b78 Merge branch 'main' into r10s/allow-cloning-email-chats 2025-08-08 14:50:06 +02:00
adb 7cebd04086 Merge pull request #3867 from deltachat/adb/issue-3608
make apk builds more reproducible
2025-08-08 14:33:22 +02:00
adb b584fdfd89 Merge pull request #3870 from deltachat/adb/issue-3782
improve group image quality
2025-08-08 14:32:51 +02:00
B. Petersen db35fef6db update CHANGELOG 2025-08-08 13:39:15 +02:00
B. Petersen 068102a0d8 allow to clone email chats
this was disallowed at a time where we had no api
to create ad-hoc "new email" chats
2025-08-08 13:36:00 +02:00
adb 02ff8a2a6b Merge branch 'main' into adb/issue-3608 2025-08-08 13:03:28 +02:00
adbenitez 321b5a223b fix comment for 1 year value 2025-08-08 00:42:29 +02:00
adb ab7fd960ca Merge branch 'main' into adb/issue-3437 2025-08-08 00:38:46 +02:00
adbenitez dec685023e use same max. avatar size for groups and profiles, remove superflous class 2025-08-08 00:17:30 +02:00
adbenitez 168d2ae16c improve group image quality 2025-08-07 23:59:05 +02:00
adb e55249182a Merge pull request #3869 from deltachat/adb/update-deps-6/8/25
remove some dependecies and upgrade others
2025-08-07 23:50:43 +02:00
adbenitez 0966487978 pin firebase version 2025-08-07 23:14:06 +02:00
adbenitez fd057485db remove com.annimon:stream dependency 2025-08-07 17:45:01 +02:00
adbenitez a68f3a7024 remove dependecy on com.pnikosis:materialish-progress 2025-08-06 19:40:47 +02:00
adbenitez 1dad6ebf8a remove unused me.leolin:ShortcutBadger and com.jpardogo.materialtabstrip:library 2025-08-06 19:39:49 +02:00
adbenitez a77b1a5dd6 update gradle and some deps 2025-08-06 19:38:41 +02:00
adbenitez c0a65e2e9f properly set the pre-selected option 2025-08-06 15:48:27 +02:00
adbenitez 82ef0560a5 change to 1 year 2025-08-06 15:19:40 +02:00
adb 9166b2a42a Merge branch 'main' into adb/issue-3437 2025-08-06 15:01:14 +02:00
adb 2ef3811a56 Merge branch 'main' into adb/issue-3795 2025-08-06 14:47:41 +02:00
adb 1b91c1c482 Merge branch 'main' into adb/issue-3608 2025-08-06 14:47:13 +02:00
adbenitez 0d8962f76c make apk builds more reproducible 2025-08-06 14:45:25 +02:00
adb e98535418c Merge pull request #3865 from deltachat/adb/issue-3860
update screenshots
2025-08-06 14:06:45 +02:00
adbenitez 5eb9065d89 update screenshots 2025-08-05 18:35:08 +02:00
adb 9e70c43ab8 Merge pull request #3862 from deltachat/prep-2.10.0
Prepare 2.10.0
2025-08-05 12:37:28 +02:00
adbenitez fc8bfabeb2 update changelog 2025-08-05 11:56:40 +02:00
adbenitez 681c22293f update version number 2025-08-05 11:51:14 +02:00
adb bed8d511fe Merge pull request #3861 from deltachat/update-core-and-stuff-5/8/25
Update core to 2.10.0
2025-08-05 11:49:15 +02:00
adbenitez eeeb686868 update strings 2025-08-05 11:33:38 +02:00
adbenitez 76dda10a31 update changelog 2025-08-05 11:26:33 +02:00
adbenitez 6a7c4f24e9 update deltachat-core-rust to 'chore(release): prepare for 2.10.0' of 'v2.10.0' 2025-08-05 11:22:29 +02:00
adb 8cdfafd7c3 Merge pull request #3859 from deltachat/hoc/lookup-key-contacts-too
fix: Lookup key contacts by addr when clicking on a link
2025-08-05 11:20:46 +02:00
Hocuri 1c6faeac04 fix: Lookup key contacts by addr when clicking on a link
Companion PR to https://github.com/chatmail/core/pull/7073
2025-08-04 16:02:39 +02:00
adbenitez 7ecf0a7daa Merge remote-tracking branch 'upstream/main' 2025-08-03 00:25:01 +02:00
adb b2bf7e8ae7 Merge pull request #3858 from deltachat/adb/issue-3850
share address for email contacts
2025-08-02 22:24:15 +00:00
adbenitez 0a34456302 update changelog 2025-08-02 21:51:10 +02:00
adb 3ebcc1dd99 Merge branch 'main' into adb/issue-3850 2025-08-02 19:50:24 +00:00
adb ff7df0e1e6 Merge pull request #3856 from deltachat/adb/issue-3855
don't enlarge avatars for special chats
2025-08-02 19:49:42 +00:00
adbenitez 68cd070b98 share address for email contacts 2025-08-02 21:48:58 +02:00
adb 8ff8cffa15 Merge branch 'main' into adb/issue-3855 2025-08-02 19:31:59 +00:00
adb dc216feb30 Merge pull request #3857 from deltachat/adb/fix-changelog-typos-2/8/25
fix typos in changelog
2025-08-02 19:31:21 +00:00
adbenitez 84fc885617 fix typos in changelog 2025-08-02 21:30:31 +02:00
adbenitez 72bcbe80c0 update changelog 2025-08-02 21:27:49 +02:00
adbenitez b4ed26b842 don't enlarge avatars for special chats 2025-08-02 21:25:45 +02:00
adb 7be6b0a1ee Merge pull request #3854 from deltachat/adb/fix-archived-link-item
fix archived link item's layout
2025-08-01 18:17:43 +00:00
adbenitez 9a2fdcdcbd update changelogC 2025-08-01 19:42:48 +02:00
adbenitez e81960f98a fix "Archived" item's layout in chatlit 2025-08-01 19:41:49 +02:00
adbenitez a9541a936e implement edge-to-edge 2025-07-15 17:43:32 +02:00
adbenitez 571f49ab13 revert meeting change 2025-06-20 19:04:42 +02:00
adbenitez 365f1dbbe6 basic call 2025-06-20 18:56:45 +02:00
adbenitez 100bb06e20 Merge remote-tracking branch 'origin/r10s/call-api' into adb/integrated-videocalls 2025-06-20 18:54:58 +02:00
adbenitez 27f662707a fix VideochatUtil 2025-06-19 17:20:46 +02:00
adbenitez 3086c72304 undo temporary test 2025-06-19 17:17:53 +02:00
B. Petersen eee218a3b6 add call api 2025-06-19 00:48:59 +02:00
adbenitez fa868077b0 test integrated webxdc 2025-06-18 17:41:09 +02:00
adb e8776177ba Merge branch 'main' into adb/integrated-videocalls 2025-06-18 15:28:04 +00:00
adb 677c0592fc Merge branch 'main' into adb/integrated-videocalls 2025-06-12 12:57:07 +00:00
adbenitez 40a79fbad5 add "After 90 days" option to disappearing messages 2024-12-04 17:46:00 +01:00
221 changed files with 6519 additions and 4450 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ on:
jobs:
artifacts-url-comments:
name: add artifact links to pull request
runs-on: windows-2019
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- name: add artifact links to pull request
+10 -10
View File
@@ -2,16 +2,16 @@ name: Upload Preview APK
on: pull_request
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
build:
name: Upload Preview APK
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.9.1
with:
access_token: ${{ github.token }}
- uses: actions/checkout@v3
- uses: actions/checkout@v5
with:
submodules: recursive
- name: Validate Fastlane Metadata
@@ -19,12 +19,12 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
working-directory: jni/deltachat-core-rust
- uses: actions/setup-java@v3
- uses: actions/setup-java@v5
with:
java-version: 17
distribution: 'temurin'
- uses: android-actions/setup-android@v3
- uses: actions/cache@v3
- uses: actions/cache@v4
with:
path: |
~/.gradle/caches
@@ -37,6 +37,9 @@ jobs:
with:
ndk-version: r27
- name: Validate Gradle Wrapper
uses: gradle/actions/wrapper-validation@v4
- name: Compile core
env:
ANDROID_NDK_ROOT: ${{ steps.setup-ndk.outputs.ndk-path }}
@@ -44,9 +47,6 @@ jobs:
export PATH="${PATH}:${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64/bin/"
scripts/install-toolchains.sh && scripts/ndk-make.sh armeabi-v7a
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1
- name: Build APK
run: ./gradlew --no-daemon -PABI_FILTER=armeabi-v7a assembleFossDebug
+257
View File
@@ -0,0 +1,257 @@
# Building and Testing
This document describes how to set up the build environment,
build and test the app. Before diving into developing, please
first read [CONTRIBUTING.md](./CONTRIBUTING.md) for general
contribution hints and conventions.
Please follow all steps precisely.
If you run into troubles,
ask on one of the [communication channels](https://delta.chat/contribute) for help
## Check Out Repository
When checking out _deltachat-android_, make sure also to check out the
subproject _deltachat-core-rust_:
- When using Git, you can do this initially by
`$ git clone --recursive https://github.com/deltachat/deltachat-android`
or later by `git submodule update --init --recursive`. If you do this in your
home directory, this results in the folder `~/deltachat-android` which is just fine.
## Generate JSON-RPC bindings
To generate the JSON-RPC bindings (ex. `chat.delta.rpc.*` package)
install the [dcrpcgen tool](https://github.com/chatmail/dcrpcgen)
then generate the `schema.json` file:
```
# install deltachat-rpc-server program:
cargo install --path ./jni/deltachat-core-rust/deltachat-rpc-server
# check the version of core matches:
deltachat-rpc-server --version
# generate the schema:
deltachat-rpc-server --openrpc > schema.json
```
then pass the schema file to the `dcrpcgen` tool to generate the
code:
```
dcrpcgen java --schema schema.json -o ./src/main/java/
```
## Build Using Nix
The repository contains [Nix](https://nixos.org/) development environment
described in `flake.nix` file.
If you don't have Nix installed,
the easiest way is to follow the [Lix installation instructions](https://lix.systems/install/)
as this results in a setup with [Flakes](https://nixos.wiki/wiki/Flakes) feature enabled out of the box
and can be cleanly uninstalled with `/nix/nix-installer uninstall` once you don't need it anymore.
Once you have Nix with Flakes feature set up start the development environment shell:
```
nix develop
```
Nix development environment contains Rust with cross-compilation toolchains and Android SDK.
To [build an APK](https://developer.android.com/studio/build/building-cmdline) run the following 2 steps.
Note that the first step may take some time to build for all architectures. You can optionally read
[the first comment block in the `ndk-make.sh` script](https://github.com/deltachat/deltachat-android/blob/master/scripts/ndk-make.sh)
for pointers on how to build for a specific architecture.
```
$ scripts/ndk-make.sh
$ ./gradlew assembleDebug
```
Resulting APK files can be found in
`build/outputs/apk/gplay/debug/` and
`build/outputs/apk/fat/debug/`.
## Build Using Dockerfile
Another way to build APK is to use provided `Dockerfile`
with [Docker](https://www.docker.com/) or [Podman](https://podman.io/).
Podman is a drop-in replacement for Docker that does not require root privileges.
If you don't have Docker or Podman setup yet, read [how to setup Podman](#setup-podman)
below. If you don't want to use Docker or Podman, read [how to manually install the
build environment](#install-build-environment).
First, build the image `deltachat-android` by running
```
podman build --build-arg UID=$(id -u) --build-arg GID=$(id -g) . -t deltachat-android
```
or
```
docker build --build-arg UID=$(id -u) --build-arg GID=$(id -g) . -t deltachat-android
```
Then, run the image:
```
podman run --userns=keep-id -it --name deltachat -v $(pwd):/home/app:z -w /home/app localhost/deltachat-android
```
or
```
docker run -it --name deltachat -v $(pwd):/home/app:z -w /home/app localhost/deltachat-android
```
You can leave the container with Ctrl+D or by typing `exit` and re-enter it with
`docker start -ia deltachat` or `podman start -ia deltachat`.
Within the container, install toolchains and build the native library:
```
deltachat@6012dcb974fe:/home/app$ scripts/install-toolchains.sh
deltachat@6012dcb974fe:/home/app$ scripts/ndk-make.sh
```
Then, [build an APK](https://developer.android.com/studio/build/building-cmdline):
```
deltachat@6012dcb974fe:/home/app$ ./gradlew assembleDebug
```
### Troubleshooting
- Executing `./gradlew assembleDebug` inside the container fails with `The SDK directory '/home/user/Android/Sdk' does not exist.`:
The problem is that Android Studio (outside the container) automatically creates a file `local.properties` with a content like `sdk.dir=/home/username/Android/Sdk`,
so, Gradle-inside-the-container looks for the Sdk at `/home/username/Android/Sdk`, where it can't find it.
You could:
- either: remove the file or just the line starting with `sdk.dir`
- or: run `./gradlew assembleDebug` from outside the container (however, there may be incompatibility issues if different versions are installed inside and outside the container)
- Running the image fails with `ERRO[0000] The storage 'driver' option must be set in /etc/containers/storage.conf, guarantee proper operation.`:
In /etc/containers/storage.conf, replace the line: `driver = ""` with: `driver = "overlay"`.
You can also set the `driver` option to something else, you just need to set it to _something_.
[Read about possible options here](https://github.com/containers/storage/blob/master/docs/containers-storage.conf.5.md#storage-table).
## <a name="setup-podman"></a>Setup Podman
These instructions were only tested on a Manjaro machine so far. If anything doesn't work, please open an issue.
First, [Install Podman](https://podman.io/getting-started/installation).
Then, if you want to run Podman without root, run:
```
sudo touch /etc/subgid
sudo touch /etc/subuid
sudo usermod --add-subuids 165536-231072 --add-subgids 165536-231072 yourusername
```
(replace `yourusername` with your username).
See https://wiki.archlinux.org/index.php/Podman#Rootless_Podman for more information.
## <a name="install-build-environment"></a>Install Build Environment (without Docker or Podman)
To setup build environment manually:
- _Either_, in Android Studio, go to "Tools / SDK Manager / SDK Tools", enable "Show Package Details",
select "CMake" and the desired NDK (install the same NDK version as the [Dockerfile](https://github.com/deltachat/deltachat-android/blob/master/Dockerfile)), hit "Apply".
- _Or_ read [Dockerfile](https://github.com/deltachat/deltachat-android/blob/master/Dockerfile) and mimic what it does.
Then, in both cases, install Rust using [rustup](https://rustup.rs/)
and Rust toolchains for cross-compilation by executing `scripts/install-toolchains.sh`.
Then, configure `ANDROID_NDK_ROOT` environment variable to point to the Android NDK
installation directory e.g. by adding this to your `.bashrc`:
```bash
export ANDROID_NDK_ROOT=${HOME}/Android/Sdk/ndk/[version] # (or wherever your NDK is) Note that there is no `/` at the end!
export PATH=${PATH}:${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64/bin/:${ANDROID_NDK_ROOT}
```
After that, call `scripts/ndk-make.sh` in the root directory to build core-rust.
Afterwards run the project in Android Studio. The project requires API 25.
With chance, that's it :) - if not, read on how to set up a proper development
environment.
## Install Development Environment
1. Some libs required by Android Studio may be missing on 64 bit Linux machines
[Source](https://developer.android.com/studio/install.html)], so for Ubuntu execute
`$ sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386 lib32z1 libbz2-1.0:i386`
and for Fedora execute
`$ sudo yum install zlib.i686 ncurses-libs.i686 bzip2-libs.i686`.
2. Download Android Studio from <https://developer.android.com> (android-studio-ide-...-linux.zip)
and unpack the archive which contains a single folder called `android-studio`;
move this folder e.g. to `~/android-studio`.
3. To launch Android Studio for the first time, open a terminal, navigate to
`~/android-studio/bin`, execute `./studio.sh` and use all the standard values
from the wizard.
4. Android Studio now asks you if you want to open an existing project;
choose `~/deltachat-android` as created in the "Build" chapter (Android Studio starts to
build the project, however, there are some steps missing before this will
succeed).
5. If components are missing, click on the corresponding error
message and install eg. required SDKs and the "Build-Tools" (you should
also find the option at "Tools / Android / SDK Manager / SDK Platforms").
Now the build should succeed - but the app still misses the native part.
6. Download Android NDK from
[NDK Archives](https://developer.android.com/ndk/downloads)
and extract the archive containing a single folder
called something like `android-ndk-r23b-linux`; move this folder e.g. to `~/android-ndk`.
7. Export the folder path to your environment as `ANDROID_NDK_ROOT` and add it to `PATH`.
You can achieve this e.g. by adding this to your `.bashrc`
```bash
export ANDROID_NDK_ROOT=${HOME}/android-ndk
export PATH=${PATH}:${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64/bin/:${ANDROID_NDK_ROOT}
```
## Run UI Tests and Benchmarks
- You don't necessarily need a dedicated testing device.
Backup your current account first, maybe there are some bugs in switching accounts.
- You can run benchmarks on either an emulated device or a real device.
You need at least Android 9. For better benchmark results,
you should run the benchmark on a real device and make sure that the core is compiled in release mode.
- Disable animations on your device, otherwise the test may fail:
at "Developer options"
set all of "Window animation scale", "Transition animation scale" and "Animator duration scale" to 0x
- In Android Studio: "File" / "Sync project with gradle files"
- In Android Studio: "Run" / "Edit configurations" / "+" / "Android Instrumented test":
Either select a specific class or select "All in Module" / "OK" /
Select your configuration in the toolbar / Click on the green "run" button in the toolbar to run the tests
### Get the benchmark results
When the benchmark is done, you will get a result like
`MEASURED RESULTS (Benchmark) - Going thorough all 10 chats: 11635,11207,11363,11352,11279,11183,11137,11145,11032,11057`.
You can paste `11635,11207,11363,11352,11279,11183,11137,11145,11032,11057`
into a cell in a LibreOffice spreadsheet, do "Data" / "Text to columns",
choose `,` as a separator, hit "OK", and create a diagram.
### Run online tests
For some tests, you need to provide the credentials to an actual email account.
You have 2 ways to do this:
1. (Recommended): Put them into the file ~/.gradle/gradle.properties (create it if it doesn't exist):
```
TEST_ADDR=youraccount@yourdomain.org
TEST_MAIL_PW=youpassword
```
2. Or set them via environment variables.
## Decoding Symbols in Crash Reports
```
$ANDROID_NDK_ROOT/ndk-stack --sym obj/local/armeabi-v7a --dump crash.txt > decoded.txt
```
`obj/local/armeabi-v7a` is the extracted path from `deltachat-gplay-release-X.X.X.apk-symbols.zip` file from https://download.delta.chat/android/symbols/
Replace `armeabi-v7a` by the correct architecture the logs come from (can be guessed by trial and error)
+43 -3
View File
@@ -1,15 +1,55 @@
# Delta Chat Android Changelog
## v2.22.0
2025-10
* target Android 15
* improve readability of info messages in dark mode
* drop too short disappearing messages options
* fix Direct Share shortcuts
* fix: don't show error message when cancelling profile creation
* enable permanent notification by default if push notifications are not available
* hide "clone chat" and member list for incoming channels
* show warning if background notifications will be unreliable
* warn if the app has not been updated after 6 months instead of 1 year
* avoid "unknown sender for this chat" error
* properly display "Messages are end-to-end encrypted." in all encrypted groups
* show dialog if user has permanently denied camera permission and tries to take picture for group avatar
* several small fixes and improvements
* add experimental built-in calls
* update to core 2.22.0
## v2.11.0
2025-08
* add "After 1 year" option to disappearing messages
* improve image quality when setting group avatars
* add Estonian translation, update other translations
* allow to clone email chats
* fix some small bugs
* update to core 2.11.0
## v2.10.0
2025-08
* fix "Archived" item's layout in chat-list
* don't enlarge "Saved Messages" and "Devices Messages" avatars on click
* share email address for email contacts instead of vCard
* open existing encrypted chat when opening a mailto link or clicking an email address in a message bubble
* update to core 2.10.0
## v2.9.0
2025-07
* hide contact email addresses in search results
* disable non-functional message editing and ephemeral messages timer settings in classic email thread chat
* don't enlage email chats avatar placeholder
* don't enlarge email chats avatar placeholder
* improve message date/status footer layout, also in RTL languages
* display correct text when receiving a "Disapearing messages enabled" system message
* display correct text when receiving a "Disappearing messages enabled" system message
* Update to core 2.9.0
## v2.8.0
2025-07
* Profiles focus on recognizing contacts
* See the number of media directly in the profile, no need to tap around
@@ -21,7 +61,7 @@
* New icon for the QR icon
* Start rebuilding the experimental broadcast lists
into proper channels - note that this is work-in-progress
* Improved separation between unencryted chats/contacts and encrypted ones, avoiding mixing of encrypted and unencrypted messages in the same chat
* Improved separation between unencrypted chats/contacts and encrypted ones, avoiding mixing of encrypted and unencrypted messages in the same chat
* Removed padlocks, as encrypted is the default "normal" state. Instead, unencrypted email is marked with a small email / letter (✉️) icon
* Classic email chats/threads get a big email / letter icon making it easy to recognize
* After some time, add a device message asking to donate. Can't wait? Donate today at https://delta.chat/donate
+1 -1
View File
@@ -45,7 +45,7 @@ Some rough ideas, that may be helpful when thinking about how to enhance things:
## Contributing Code
The [README](./README.md) explains in detail how to set up the build environment.
The [BUILDING.md](./BUILDING.md) file explains in detail how to set up the build environment.
Please follow all steps precisely.
If you run into troubles,
ask on one of the [communication channels](https://delta.chat/contribute) for help.
+25 -31
View File
@@ -1,5 +1,5 @@
plugins {
id 'com.android.application' version '8.5.2'
id 'com.android.application' version '8.11.1'
id 'com.google.gms.google-services' version '4.4.1'
}
@@ -21,7 +21,7 @@ android {
}
namespace "org.thoughtcrime.securesms"
flavorDimensions "none"
compileSdk 34
compileSdk 35
// Set NDK version to strip native libraries.
// Even though we compile our libraries outside Gradle with `scripts/ndk-make.sh`,
@@ -33,14 +33,14 @@ android {
useLibrary 'org.apache.http.legacy'
defaultConfig {
versionCode 30000727
versionName "2.9.0"
versionCode 30000730
versionName "2.22.0"
applicationId "chat.delta.lite"
multiDexEnabled true
minSdkVersion 21
targetSdkVersion 34
targetSdkVersion 35
vectorDrawables.useSupportLibrary = true
@@ -209,9 +209,9 @@ dependencies {
implementation 'com.airbnb.android:lottie:4.2.2' // Lottie animations support.
implementation 'androidx.sharetarget:sharetarget:1.2.0'
implementation 'androidx.webkit:webkit:1.12.1'
implementation 'androidx.webkit:webkit:1.14.0'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.appcompat:appcompat:1.7.1'
implementation 'com.google.android.material:material:1.12.0'
implementation 'androidx.legacy:legacy-support-v13:1.0.0'
implementation ('androidx.preference:preference:1.2.1') {
@@ -219,7 +219,7 @@ dependencies {
exclude group: 'androidx.lifecycle', module:'lifecycle-viewmodel-ktx'
}
implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
implementation 'androidx.exifinterface:exifinterface:1.3.7'
implementation 'androidx.exifinterface:exifinterface:1.4.1'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.lifecycle:lifecycle-common-java8:2.6.2'
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.6.2'
@@ -233,52 +233,46 @@ dependencies {
implementation 'com.google.zxing:core:3.3.0' // fixed version to support SDK<24
implementation ('com.journeyapps:zxing-android-embedded:4.3.0') { transitive = false } // QR Code scanner
implementation 'com.fasterxml.jackson.core:jackson-databind:2.11.1' // used as JSON library
implementation 'com.google.code.gson:gson:2.12.1' // used as JSON library.
implementation "me.leolin:ShortcutBadger:1.1.16" // display messagecount on the home screen icon.
implementation 'com.jpardogo.materialtabstrip:library:1.0.9' // used in the emoji selector for the tab selection.
implementation 'com.github.Baseflow:PhotoView:2.3.0' // does the zooming on photos / media
implementation 'com.github.penfeizhou.android.animation:awebp:3.0.2' // animated webp support.
implementation 'com.caverock:androidsvg-aar:1.4' // SVG support.
implementation 'com.github.bumptech.glide:glide:4.12.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
implementation 'com.github.bumptech.glide:glide:4.16.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'
annotationProcessor 'androidx.annotation:annotation:1.9.1'
implementation 'com.makeramen:roundedimageview:2.1.0' // crops the avatars to circles
implementation 'com.pnikosis:materialish-progress:1.5' // used only in the "Progress Wheel" in Share Activity.
implementation 'com.makeramen:roundedimageview:2.3.0' // crops the avatars to circles
implementation 'com.github.amulyakhare:TextDrawable:558677ea31' // number of unread messages,
// the one-letter circle for the contacts (when there is not avatar) and a white background.
implementation 'com.googlecode.mp4parser:isoparser:1.0.6' // MP4 recoding; upgrading eg. to 1.1.22 breaks recoding, however, i have not investigated further, just reset to 1.0.6
implementation ('com.davemorrissey.labs:subsampling-scale-image-view:3.6.0') { // for the zooming on photos / media
implementation ('com.davemorrissey.labs:subsampling-scale-image-view:3.10.0') { // for the zooming on photos / media
exclude group: 'com.android.support', module: 'support-annotations'
}
implementation 'com.annimon:stream:1.1.8' // brings future java streams api to SDK Version < 24
// Replacement for ContentResolver
// that protects against the Surreptitious Sharing attack.
// <https://github.com/cketti/SafeContentResolver>
implementation 'de.cketti.safecontentresolver:safe-content-resolver-v21:1.0.0'
gplayImplementation('com.google.firebase:firebase-messaging:24.1.0') { // for PUSH notifications
gplayImplementation('com.google.firebase:firebase-messaging:24.1.2') { // for PUSH notifications, don't upgrade: v25.0.0 requires minSdk>=23
exclude group: 'com.google.firebase', module: 'firebase-core'
exclude group: 'com.google.firebase', module: 'firebase-analytics'
exclude group: 'com.google.firebase', module: 'firebase-measurement-connector'
}
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.assertj:assertj-core:1.7.1'
testImplementation 'org.mockito:mockito-core:1.9.5'
testImplementation 'org.powermock:powermock-api-mockito:1.6.1'
testImplementation 'org.powermock:powermock-module-junit4:1.6.1'
testImplementation 'org.powermock:powermock-module-junit4-rule:1.6.1'
testImplementation 'org.powermock:powermock-classloading-xstream:1.6.1'
testImplementation 'org.assertj:assertj-core:3.27.3'
testImplementation 'org.mockito:mockito-core:5.18.0'
testImplementation 'org.powermock:powermock-api-mockito:1.7.4'
testImplementation 'org.powermock:powermock-module-junit4:2.0.9'
testImplementation 'org.powermock:powermock-module-junit4-rule:2.0.9'
testImplementation 'org.powermock:powermock-classloading-xstream:2.0.9'
androidTestImplementation 'androidx.test:runner:1.6.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.6.1'
androidTestImplementation 'androidx.test:rules:1.6.1'
androidTestImplementation 'androidx.test.ext:junit:1.2.1'
androidTestImplementation 'androidx.test:runner:1.7.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.7.0'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.7.0'
androidTestImplementation 'androidx.test:rules:1.7.0'
androidTestImplementation 'androidx.test.ext:junit:1.3.0'
androidTestImplementation 'com.android.support:support-annotations:28.0.0'
androidTestImplementation ('org.assertj:assertj-core:1.7.1') {
androidTestImplementation ('org.assertj:assertj-core:3.27.3') {
exclude group: 'org.hamcrest', module: 'hamcrest-core'
}
}
Generated
+15 -15
View File
@@ -7,11 +7,11 @@
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1733948466,
"narHash": "sha256-o/uq/tU458Ykudi8Zk3sRga5iazkuSczt9wDOCUDOSU=",
"lastModified": 1756239746,
"narHash": "sha256-0ibN685tT+u/Nbmbrrq9G3mRUzct2Votyv/a7Wwv26s=",
"owner": "tadfisher",
"repo": "android-nixpkgs",
"rev": "0bf99ffaea6a7c0948ae10cf2e40c2905e4e4d6b",
"rev": "256631d162ec883b2341ee59621516e1f65f0f6b",
"type": "github"
},
"original": {
@@ -28,11 +28,11 @@
]
},
"locked": {
"lastModified": 1728330715,
"narHash": "sha256-xRJ2nPOXb//u1jaBnDP56M7v5ldavjbtR6lfGqSvcKg=",
"lastModified": 1741473158,
"narHash": "sha256-kWNaq6wQUbUMlPgw8Y+9/9wP0F8SHkjy24/mN3UAppg=",
"owner": "numtide",
"repo": "devshell",
"rev": "dd6b80932022cea34a019e2bb32f6fa9e494dfef",
"rev": "7c9e793ebe66bcba8292989a68c0419b737a22a0",
"type": "github"
},
"original": {
@@ -79,11 +79,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1733759999,
"narHash": "sha256-463SNPWmz46iLzJKRzO3Q2b0Aurff3U1n0nYItxq7jU=",
"lastModified": 1756125398,
"narHash": "sha256-XexyKZpf46cMiO5Vbj+dWSAXOnr285GHsMch8FBoHbc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "a73246e2eef4c6ed172979932bc80e1404ba2d56",
"rev": "3b9f00d7a7bf68acd4c4abb9d43695afb04e03a5",
"type": "github"
},
"original": {
@@ -95,11 +95,11 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1733749988,
"narHash": "sha256-+5qdtgXceqhK5ZR1YbP1fAUsweBIrhL38726oIEAtDs=",
"lastModified": 1756159630,
"narHash": "sha256-ohMvsjtSVdT/bruXf5ClBh8ZYXRmD4krmjKrXhEvwMg=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "bc27f0fde01ce4e1bfec1ab122d72b7380278e68",
"rev": "84c256e42600cb0fdf25763b48d28df2f25a0c8b",
"type": "github"
},
"original": {
@@ -138,11 +138,11 @@
"nixpkgs": "nixpkgs_3"
},
"locked": {
"lastModified": 1747017456,
"narHash": "sha256-C/U12fcO+HEF071b5mK65lt4XtAIZyJSSJAg9hdlvTk=",
"lastModified": 1756197489,
"narHash": "sha256-S16rPaBH1TnMbDyL5NlGSJcYd7wPlOEWTStdBDL7BHw=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "5b07506ae89b025b14de91f697eba23b48654c52",
"rev": "8ec04f46f1edeeed3f870da62191745b93975da7",
"type": "github"
},
"original": {
+2 -2
View File
@@ -15,10 +15,10 @@
pkgs = import nixpkgs { inherit system overlays; };
android-sdk = android.sdk.${system} (sdkPkgs:
with sdkPkgs; [
build-tools-34-0-0
build-tools-35-0-0
cmdline-tools-latest
platform-tools
platforms-android-34
platforms-android-35
ndk-27-2-12479018
]);
rust-version = pkgs.lib.removeSuffix "\n"
+2 -2
View File
@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
distributionSha256Sum=20f1b1176237254a6fc204d8434196fa11a4cfb387567519c61556e8710aed78
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-21
View File
@@ -735,12 +735,6 @@ JNIEXPORT jint Java_com_b44t_messenger_DcContext_sendTextMsg(JNIEnv *env, jobjec
}
JNIEXPORT jint Java_com_b44t_messenger_DcContext_sendVideochatInvitation(JNIEnv *env, jobject obj, jint chat_id)
{
return (jint)dc_send_videochat_invitation(get_dc_context(env, obj), chat_id);
}
JNIEXPORT jboolean Java_com_b44t_messenger_DcContext_sendWebxdcStatusUpdate(JNIEnv *env, jobject obj, jint msg_id, jstring payload)
{
CHAR_REF(payload);
@@ -1608,21 +1602,6 @@ JNIEXPORT jstring Java_com_b44t_messenger_DcMsg_getSetupCodeBegin(JNIEnv *env, j
}
JNIEXPORT jstring Java_com_b44t_messenger_DcMsg_getVideochatUrl(JNIEnv *env, jobject obj)
{
char* temp = dc_msg_get_videochat_url(get_dc_msg(env, obj));
jstring ret = JSTRING_NEW(temp);
dc_str_unref(temp);
return ret;
}
JNIEXPORT jint Java_com_b44t_messenger_DcMsg_getVideochatType(JNIEnv *env, jobject obj)
{
return (jint)dc_msg_get_videochat_type(get_dc_msg(env, obj));
}
JNIEXPORT void Java_com_b44t_messenger_DcMsg_setSubject(JNIEnv *env, jobject obj, jstring text)
{
CHAR_REF(text);
+5 -9
View File
@@ -1,15 +1,11 @@
# native methods
-keep class com.b44t.messenger.** { * ; }
# Gson uses generic type information stored in a class file when working with
# fields. Proguard removes such information by default, keep it.
-keepattributes Signature
# This is also needed for R8 in compat mode since multiple
# optimizations will remove the generic signature such as class
# merging and argument removal. See:
# https://r8.googlesource.com/r8/+/refs/heads/main/compatibility-faq.md#troubleshooting-gson-gson
-keep class com.google.gson.reflect.TypeToken { *; }
-keep class * extends com.google.gson.reflect.TypeToken
# Keep metadata needed by the JSON parser
-keep class chat.delta.rpc.** { * ; }
-keepattributes *Annotation*,EnclosingMethod,Signature
-keepnames class com.fasterxml.jackson.** { *; }
#-dontwarn com.fasterxml.jackson.databind.**
# bug with video recoder
-keep class com.coremedia.iso.** { *; }
+9 -1
View File
@@ -370,7 +370,7 @@
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize">
</activity>
<activity android:name=".videochat.VideochatActivity"
<activity android:name=".calls.CallActivity"
android:label=""
android:theme="@style/TextSecure.LightTheme"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize|uiMode"
@@ -436,6 +436,14 @@
</intent-filter>
</receiver>
<receiver android:name=".notifications.DeclineCallReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="org.thoughtcrime.securesms.notifications.DECLINE_CALL_NOTICED"/>
</intent-filter>
</receiver>
<receiver android:name=".notifications.RemoteReplyReceiver"
android:enabled="true"
android:exported="false">
File diff suppressed because one or more lines are too long
+27 -3
View File
@@ -87,6 +87,7 @@
<ul>
<li><a href="#jaká-oprávnění-delta-chat-potřebuje">Jaká oprávnění Delta Chat potřebuje?</a></li>
<li><a href="#pracuje-delta-chat-s-mým-poskytovatelem-e-mailu">Pracuje Delta Chat s <em>mým</em> poskytovatelem e-mailu?</a></li>
<li><a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">Can I use Delta Chat in parallel with other E-Mail apps?</a></li>
<li><a href="#i-want-to-manage-my-own-server-for-delta-chat-what-do-you-recommend">I want to manage my own server for Delta Chat. What do you recommend?</a></li>
<li><a href="#proč-musím-delta-chatu-zadat-mé-e-mailové-heslo-je-to-bezpečné">Proč musím Delta Chatu zadat mé e-mailové heslo? Je to bezpečné?</a></li>
<li><a href="#jaké-zprávy-delta-chat-zobrazuje">Jaké zprávy Delta Chat zobrazuje?</a></li>
@@ -407,7 +408,7 @@ who could have already replied, forwarded, saved, screenshotted or otherwise cop
in the settings of a chat,
at the top right of the chat window,
by selecting a time span
between 1 minute and 5 weeks.</p>
between 5 minutes and 1 year.</p>
<p>Until the setting is turned off again,
each chat members Delta Chat app takes care
@@ -780,8 +781,8 @@ there are no lock or similar markers on end-to-end encrypted messages, anymore.<
it is impossible to receive or send messages without end-to-end encryption.</p>
<p>If you instead create a profile using a classic e-mail server,
you can send and receive messages without end-to-end encryption.
Such messages lacking end-to-end encryption are marked with an e-mail icon
you can send and receive messages with or without end-to-end encryption.
Messages lacking end-to-end encryption are marked with an e-mail icon
<img style="vertical-align:middle; width:1.2em; margin:1px" src="../email-icon.png" alt="email" />.</p>
<h3 id="howtoe2ee">
@@ -1621,6 +1622,29 @@ Nicméně, někteří poskytovatelé vyžadují ke správnému chodu speciální
podrobnější popis je na <a href="https://providers.delta.chat">Provider Overview</a></li>
</ul>
<h3 id="can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">
Can I use Delta Chat in parallel with other E-Mail apps? <a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps" class="anchor"></a>
</h3>
<p>Yes, but it is not recommended.</p>
<p>Parallel usage with the same E-Mail address might lead to the following inconveniences:</p>
<ul>
<li>Next to your Delta Chat notifications,
you might also get notifications for (encrypted, so unreadable) chat mail messages
in your other email app</li>
<li>If Delta Chat is not running
or “Advanced &gt; Move automatically to the DeltaChat Folder” is disabled,
encrypted Delta Chat messages might clutter the Inbox in your other E-Mail apps.</li>
</ul>
<p><a href="https://support.delta.chat/t/sieve-rule-to-move-deltachat-mails-to-deltachat-folder/288/10">Sieve rules</a> can solve these problems.</p>
<h3 id="i-want-to-manage-my-own-server-for-delta-chat-what-do-you-recommend">
+87 -66
View File
@@ -87,6 +87,7 @@
<ul>
<li><a href="#welche-app-berechtigungen-benötigt-delta-chat">Welche App-Berechtigungen benötigt Delta Chat?</a></li>
<li><a href="#funktioniert-delta-chat-mit-meinem-e-mail-anbieter">Funktioniert Delta Chat mit <em>meinem</em> E-Mail-Anbieter?</a></li>
<li><a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">Can I use Delta Chat in parallel with other E-Mail apps?</a></li>
<li><a href="#ich-möchte-meinen-eigenen-server-für-delta-chat-verwalten-gibt-es-empfehlungen">Ich möchte meinen eigenen Server für Delta Chat verwalten. Gibt es Empfehlungen?</a></li>
<li><a href="#weshalb-muss-ich-mein-e-mail-kennwort-in-delta-chat-eingeben-ist-das-sicher">Weshalb muss ich mein E-Mail-Kennwort in Delta Chat eingeben? Ist das sicher?</a></li>
<li><a href="#welche-nachrichten-erscheinen-in-delta-chat">Welche Nachrichten erscheinen in Delta Chat?</a></li>
@@ -389,10 +390,11 @@ die die Nachricht bereits beantwortet, weitergeleitet, gespeichert, mit einem Sc
</h3>
<p>Sie schalten “Verschwindende Nachrichten
oben rechts im Chatfenster,
durch Auswahl einer Zeitspanne
zwischen 1 Minute und 5 Wochen ein.</p>
<p>You can turn on “disappearing messages
in the settings of a chat,
at the top right of the chat window,
by selecting a time span
between 5 minutes and 1 year.</p>
<p>Bis die Einstellung wieder ausgeschaltet wird,
kümmern sich die Delta-Chat-Apps der Chat-Teilnehmer
@@ -694,26 +696,23 @@ Willkommen bei der Macht des interoperablen und massiven Chatmail- und E-Mail-Sy
</h3>
<p>Delta Chat uses a <a href="#openpgp-secure">secure subset of the OpenPGP standard</a>
to provide automatic end-to-end encryption using these protocols:</p>
<p>Delta Chat verwendet eine <a href="#openpgp-secure">sichere Teilmenge des OpenPGP-Standards</a>, um eine automatische End-to-End-Verschlüsselung mit folgenden Protokollen bereitzustellen:</p>
<ul>
<li>
<p><a href="https://securejoin.delta.chat/en/latest/new.html">Secure-Join</a>
to exchange encryption setup information through QR-code scanning or “invite links.</p>
zum Austausch von Verschlüsselungsinformationen durch Scannen von QR-Codes oder „Einladungslinks.</p>
</li>
<li>
<p><a href="https://autocrypt.org">Autocrypt</a> is used for automatically
establishing end-to-end encryption between contacts and all members of a group chat.</p>
<p><a href="https://autocrypt.org">Autocrypt</a> wird verwendet, um automatisch eine Ende-zu-Ende-Verschlüsselung zwischen Kontakten und allen Mitgliedern einer Gruppe herzustellen.</p>
</li>
<li>
<p><a href="https://github.com/chatmail/core/blob/main/spec.md#attaching-a-contact-to-a-message">Sharing a contact to a
chat</a>
enables receivers to use end-to-end encryption with the contact.</p>
<p><a href="https://github.com/chatmail/core/blob/main/spec.md#attaching-a-contact-to-a-message">Teilen eines Kontakts im Chat</a>
ermöglicht es den Empfängern, eine Ende-zu-Ende-Verschlüsselung mit dem Kontakt zu verwenden.</p>
</li>
</ul>
<p>Delta Chat does not query, publish or interact with any OpenPGP key servers.</p>
<p>Delta Chat fragt keine OpenPGP-Keyserver ab, veröffentlicht dort keine Daten und interagiert auch sonst nicht mit diesen.</p>
<h3 id="whene2e">
@@ -723,9 +722,8 @@ enables receivers to use end-to-end encryption with the contact.</p>
</h3>
<p>All messages in Delta Chat are <strong>end-to-end encrypted by default</strong>.
Since the Delta Chat Version 2 release series (July 2025)
there are no lock or similar markers on end-to-end encrypted messages, anymore.</p>
<p>Alle Nachrichten in Delta Chat sind <strong>standardmäßig Ende-zu-Ende-verschlüsselt</strong>.
Seit der Veröffentlichung von Delta Chat Version 2 (Juli 2025) gibt es keine Schlösser oder ähnliche Markierungen mehr an EndezuEnde-verschlüsselten Nachrichten.</p>
<h3 id="kann-ich-e-mails-ohne-ende-zu-ende-verschlüsselung-empfangen-oder-senden">
@@ -737,9 +735,9 @@ there are no lock or similar markers on end-to-end encrypted messages, anymore.<
<p>Wenn Sie die Standard-<a href="https://chatmail.at/relays">Chatmail-Relays</a> verwenden, ist es unmöglich, Nachrichten ohne End-to-End-Verschlüsselung zu empfangen oder zu senden.</p>
<p>Wenn Sie stattdessen ein Profil mit einem klassischen E-Mail-Server erstellen,
können Sie Nachrichten ohne End-to-End-Verschlüsselung senden und empfangen.
Solche Nachrichten werden mit einem E-Mail-Symbol gekennzeichnet
<p>If you instead create a profile using a classic e-mail server,
you can send and receive messages with or without end-to-end encryption.
Messages lacking end-to-end encryption are marked with an e-mail icon
<img style="vertical-align:middle; width:1.2em; margin:1px" src="../email-icon.png" alt="email" />.</p>
<h3 id="howtoe2ee">
@@ -750,9 +748,9 @@ Solche Nachrichten werden mit einem E-Mail-Symbol gekennzeichnet
</h3>
<p>You can send an invite link through another private chat,
show an invitation QR code when next to each other or in a video call,
or click on acontact” that was shared in a chat.</p>
<p>Man kann einen Einladungslink über einen anderen privaten Chat senden,
einen Einladungs-QR-Code zeigen, wenn man nebeneinander steht oder einen Videoanruf tätigen,
oder auf einenKontakt” klicken der per Chat geteilt wurde.</p>
<ul>
<li>
@@ -761,35 +759,35 @@ tippen Sie auf den Titel der Gruppe, um die Mitgliederliste anzuzeigen,
und wählen Sie „QR-Einladungscode“.</p>
</li>
<li>
<p>For <strong>direct 1:1 chat invitations</strong>,
tap the QR Code icon <img style="vertical-align:middle; width:1.8em; margin:1px" src="../qr-icon.png" />
on the Delta Chat app main screen.</p>
<p>Für <strong>direkte 1:1-Chat-Einladungen</strong>,
tippt man auf das QR-Code-Symbol <img style="vertical-align:middle; width:1.8em; margin:1px" src="../qr-icon.png" />
auf dem Hauptbildschirm der Delta-Chat-App.</p>
</li>
</ul>
<p>Ask your chat partner to scan the QR image
with their Delta Chat app,
or clickCopy” or “Share” to create an invite link
and share it with your chat partner.</p>
<p>Man kann seinen Chat-Partner bitten, denn QR-Code
mit seiner Delta Chat-App zu scannen,
oder aufKopieren” oder “Teilen” drücken, um einen Einladungslink zu erstellen
und diesen mit seinem Chat-Partner zu teilen.</p>
<p>Now wait while <a href="https://securejoin.delta.chat/en/latest/new.html#setup-contact-protocol">end-to-end encryption is getting established</a>.</p>
<p>Nun wartet man, während die <a href="https://securejoin.delta.chat/en/latest/new.html#setup-contact-protocol">Ende-zu-Ende-Verschlüsselung eingerichtet wird</a>.</p>
<ul>
<li>
<p>If both sides are online, they will soon see a (group or direct) chat
and can start messaging securely.</p>
<p>Wenn beide Seiten online sind, sehen sie bald einen (Gruppen- oder direkten) Chat
und können mit der sicheren Nachrichtenübermittlung beginnen.</p>
</li>
<li>
<p>If one side is offline or in bad network,
the ability to chat is delayed until connectivity is restored.</p>
<p>Wenn eine Seite offline ist oder eine schlechte Verbindung hat,
wird die Möglichkeit zu chatten verzögert, bis die Verbindung wiederhergestellt ist.</p>
</li>
</ul>
<p>Congratulations!
You now will automatically use end-to-end encryption
with this contact.
If you add each other to chat groups,
end-to-end encryption will be established among all members.</p>
<p>Glückwunsch!
Du verwenden jetzt automatisch eine Ende-zu-Ende-Verschlüsselung
mit diesem Kontakt.
Wenn man sich gegenseitig zu Chatgruppen hinzufügt,
wird eine Ende-zu-Ende-Verschlüsselung zwischen allen Mitgliedern eingerichtet.</p>
<h3 id="e2eeguarantee">
@@ -838,9 +836,9 @@ und Anhang-Metadaten wie Dateinamen.</p>
</h3>
<p>Yes, Delta Chat uses a secure subset of OpenPGP
requiring the whole message to be properly encrypted and signed.
For example, “Detached signaturesare not treated as secure.</p>
<p>Ja, Delta Chat verwendet ein sicheres subset von OpenPGP
das verlangt, dass die gesamte Nachricht ordnungsgemäß verschlüsselt und signiert wurde.
Als Beispiel, werden “angehängte Signaturennicht als sicher behandelt.</p>
<p>Die meisten öffentlich diskutierten OpenPGP-Probleme
resultieren in Wirklichkeit aus schlechter Usability oder schlechter Implementierung von Tools oder Anwendungen - oder beidem.
@@ -906,10 +904,11 @@ so wie in der Autocrypt-Level-1-Spezifikation definiert.</p>
</h3>
<p>If you are sending or receiving e-mail messages without end-to-end encryption (using a classic e-mail server),
they are still protected from cell or cable companies who can not read or modify your e-mail messages.
But both your and your recipients e-mail providers
may read, analyze or modify your messages, including any attachments.</p>
<p>Wenn Sie E-Mail-Nachrichten ohne Ende-zu-Ende-Verschlüsselung senden oder empfangen (mit einem klassischen E-Mail-Server),
sind sie immer noch vor Mobilfunkanbietern oder Kabelnetzbetreibern geschützt, die Ihre E-Mail-Nachrichten nicht lesen oder verändern können.</p>
<p>Aber sowohl Ihr E-Mail-Anbieter als auch der E-Mail-Anbieter des Empfängers
können Ihre Nachrichten, einschließlich aller Anhänge, lesen, analysieren oder verändern.</p>
<p>Delta Chat verwendet standardmäßig strikte
<a href="https://en.wikipedia.org/wiki/Transport_Layer_Security">TLS-Verschlüsselung</a>,
@@ -948,7 +947,7 @@ Stattdessen werden alle Gruppen-Metadaten durchgängig verschlüsselt und aussch
</li>
</ul>
<p>All other message, contact and group metadata resides in the end-to-end encrypted part of messages.</p>
<p>Alle anderen Metadaten zu Nachrichten, Kontakten und Gruppen befinden sich im Ende-zu-Ende-verschlüsselten Teil der Nachrichten.</p>
<h3 id="device-seizure">
@@ -976,12 +975,12 @@ can not be identified easily.</p>
</h3>
<p>No, not yet.</p>
<p>Nein, noch nichts.</p>
<p>The Signal messenger introduced <a href="https://signal.org/blog/sealed-sender/">“Sealed Sender” in 2018</a>
to keep their server infrastructure ignorant of who is sending a message to a set of recipients.
It is particularly important because the Signal server knows the mobile number of each account,
which is usually associated with a passport identity.</p>
<p>Der Signal-Messenger führte 2018 <a href="https://signal.org/blog/sealed-sender/">“Sealed Sender”</a> ein
um seine Serverinfrastruktur darüber im Unklaren zu lassen, wer eine Nachricht an eine Gruppe von Empfängern sendet.
Dies ist besonders wichtig, weil der Signal-Server die Handynummer jedes Kontos kennt,
die in der Regel mit einer Passidentität verbunden ist.</p>
<p>Even if <a href="https://chatmail.at/relays">chatmail relays</a>
do not ask for any private data (including no phone numbers),
@@ -997,7 +996,7 @@ but an implementation has not been agreed as a priority yet.</p>
</h3>
<p>No, not yet.</p>
<p>Nein, noch nichts.</p>
<p>Delta Chat today doesnt support Perfect Forward Secrecy (PFS).
This means that if your private decryption key is leaked,
@@ -1023,12 +1022,11 @@ which would make it available in all <a href="https://chatmail.at/clients">chatm
</h3>
<p>No, not yet.</p>
<p>Nein, noch nichts.</p>
<p>Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
We aim to add PQC support in <a href="https://github.com/chatmail/core">chatmail core</a> after the draft is finalized at the IETF
in collaboration with other OpenPGP implementers.</p>
<p>Delta Chat verwendet die Rust OpenPGP-Bibliothek <a href="https://github.com/rpgp/rpgp">rPGP</a>
die den neuesten <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP Entwurf</a> unterstützt.
Wir beabsichtigen, PQC-Unterstützung zum <a href="https://github.com/chatmail/core">chatmail core</a> hinzuzufügen, sobald der Entwurf bei der IETF in Zusammenarbeit mit anderen OpenPGP-Implementierern fertiggestellt ist.</p>
<h3 id="wie-kann-ich-die-verschlüsselung-manuell-überprüfen">
@@ -1379,10 +1377,10 @@ forum</a> veröffentlicht und diskutiert.</li>
</h3>
<p>Note:
Changing email addresses is temporarily disabled
because of ongoing changes to the DeltaChat core.
It should be available again in a few months.</p>
<p>Anmerkung:
Das Ändern von E-Mail-Adressen ist vorübergehend deaktiviert
wegen laufender Änderungen am DeltaChat-Core.
Es sollte in ein paar Monaten wieder verfügbar sein.</p>
<ol>
<li>
@@ -1482,6 +1480,29 @@ gesendet haben, Nachrichten an Ihre neue Adresse senden.</p>
Allerdings benötigen einige Anbieter besondere Einstellungen, um ordnungsgemäß zu funktionieren; eine von NutzerInnen erstellte Sammlung zu einigen Optionen findet sich unter <a href="https://providers.delta.chat">Provider Overview</a>.</li>
</ul>
<h3 id="can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">
Can I use Delta Chat in parallel with other E-Mail apps? <a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps" class="anchor"></a>
</h3>
<p>Yes, but it is not recommended.</p>
<p>Parallel usage with the same E-Mail address might lead to the following inconveniences:</p>
<ul>
<li>Next to your Delta Chat notifications,
you might also get notifications for (encrypted, so unreadable) chat mail messages
in your other email app</li>
<li>If Delta Chat is not running
or “Advanced &gt; Move automatically to the DeltaChat Folder” is disabled,
encrypted Delta Chat messages might clutter the Inbox in your other E-Mail apps.</li>
</ul>
<p><a href="https://support.delta.chat/t/sieve-rule-to-move-deltachat-mails-to-deltachat-folder/288/10">Sieve rules</a> can solve these problems.</p>
<h3 id="ich-möchte-meinen-eigenen-server-für-delta-chat-verwalten-gibt-es-empfehlungen">
@@ -1491,10 +1512,10 @@ Allerdings benötigen einige Anbieter besondere Einstellungen, um ordnungsgemä
</h3>
<ul>
<li>Most mail servers will work well. But what we personally recommend is a
chatmail relay server, as described <a href="https://delta.chat/en/2023-12-13-chatmail">in this
blogpost</a>.</li>
<li>You can find an <a href="https://github.com/chatmail/relay">installation guide on GitHub</a>.</li>
<li>Die meisten Mailserver werden gut funktionieren. Aber wir persönlich empfehlen ein
Chatmail-Relay-Server, wie er <a href="https://delta.chat/en/2023-12-13-chatmail">in diesem
Blogpost</a> beschrieben wird.</li>
<li>Man kann eine <a href="https://github.com/chatmail/relay">Installationsanleitung auf GitHub</a> finden.</li>
</ul>
<h3 id="weshalb-muss-ich-mein-e-mail-kennwort-in-delta-chat-eingeben-ist-das-sicher">
+27 -3
View File
@@ -87,6 +87,7 @@
<ul>
<li><a href="#which-permissions-does-delta-chat-need">Which permissions does Delta Chat need?</a></li>
<li><a href="#does-delta-chat-work-with-my-e-mail-provider">Does Delta Chat work with <em>my</em> e-mail-provider?</a></li>
<li><a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">Can I use Delta Chat in parallel with other E-Mail apps?</a></li>
<li><a href="#i-want-to-manage-my-own-server-for-delta-chat-what-do-you-recommend">I want to manage my own server for Delta Chat. What do you recommend?</a></li>
<li><a href="#why-do-i-have-to-enter-my-e-mail-password-into-delta-chat-is-this-secure">Why do I have to enter my E-Mail password into Delta Chat? Is this secure?</a></li>
<li><a href="#which-messages-do-appear-in-delta-chat">Which messages do appear in Delta Chat?</a></li>
@@ -411,7 +412,7 @@ who could have already replied, forwarded, saved, screenshotted or otherwise cop
in the settings of a chat,
at the top right of the chat window,
by selecting a time span
between 1 minute and 5 weeks.</p>
between 5 minutes and 1 year.</p>
<p>Until the setting is turned off again,
each chat members Delta Chat app takes care
@@ -784,8 +785,8 @@ there are no lock or similar markers on end-to-end encrypted messages, anymore.<
it is impossible to receive or send messages without end-to-end encryption.</p>
<p>If you instead create a profile using a classic e-mail server,
you can send and receive messages without end-to-end encryption.
Such messages lacking end-to-end encryption are marked with an e-mail icon
you can send and receive messages with or without end-to-end encryption.
Messages lacking end-to-end encryption are marked with an e-mail icon
<img style="vertical-align:middle; width:1.2em; margin:1px" src="../email-icon.png" alt="email" />.</p>
<h3 id="howtoe2ee">
@@ -1626,6 +1627,29 @@ However, some providers need special options to work properly,
see <a href="https://providers.delta.chat">Provider Overview</a></li>
</ul>
<h3 id="can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">
Can I use Delta Chat in parallel with other E-Mail apps? <a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps" class="anchor"></a>
</h3>
<p>Yes, but it is not recommended.</p>
<p>Parallel usage with the same E-Mail address might lead to the following inconveniences:</p>
<ul>
<li>Next to your Delta Chat notifications,
you might also get notifications for (encrypted, so unreadable) chat mail messages
in your other email app</li>
<li>If Delta Chat is not running
or “Advanced &gt; Move automatically to the DeltaChat Folder” is disabled,
encrypted Delta Chat messages might clutter the Inbox in your other E-Mail apps.</li>
</ul>
<p><a href="https://support.delta.chat/t/sieve-rule-to-move-deltachat-mails-to-deltachat-folder/288/10">Sieve rules</a> can solve these problems.</p>
<h3 id="i-want-to-manage-my-own-server-for-delta-chat-what-do-you-recommend">
+76 -54
View File
@@ -12,7 +12,7 @@
<li><a href="#qué-significa-fijar-mutear-archivar">¿Qué significa fijar, mutear, archivar?</a></li>
<li><a href="#save">¿Cómo funcionan los “Mensajes guardados”?</a></li>
<li><a href="#qué-significa-el-punto-verde">¿Qué significa el punto verde?</a></li>
<li><a href="#edit">Correct typos and delete messages after sending</a></li>
<li><a href="#edit">Corregir errores y borrar mensajes después de enviar</a></li>
<li><a href="#ephemeralmsgs">¿Cómo funciona la desaparición de mensajes?</a></li>
</ul>
</li>
@@ -27,12 +27,12 @@
<li><a href="#delold">¿Qué pasa si activo “Borrar mensajes del dispositivo”?</a></li>
</ul>
</li>
<li><a href="#instant-delivery">Instant message delivery and Push Notifications</a>
<li><a href="#instant-delivery">Entrega de mensajes instantáneos y notificaciones Push</a>
<ul>
<li><a href="#what-are-push-notifications-how-can-i-get-instant-message-delivery">What are Push Notifications? How can I get instant message delivery?</a></li>
<li><a href="#are-push-notifications-enabled-on-ios-devices-is-there-an-alternative">Are Push Notifications enabled on iOS devices? Is there an alternative?</a></li>
<li><a href="#android-push">Are Push notifications enabled / needed on Android devices?</a></li>
<li><a href="#privacy-notifications">How private are Delta Chat Push Notifications?</a></li>
<li><a href="#qué-son-las-notificaciones-push-cómo-puedo-recibir-mensajes-instantáneos">¿Qué son las Notificaciones Push? ¿Cómo puedo recibir mensajes instantáneos?</a></li>
<li><a href="#están-activadas-las-notificaciones-push-en-los-dispositivos-ios-existe-alguna-alternativa">¿Están activadas las notificaciones Push en los dispositivos iOS? ¿Existe alguna alternativa?</a></li>
<li><a href="#android-push">¿Están habilitadas / son necesarias las notificaciones Push en los dispositivos Android?</a></li>
<li><a href="#privacy-notifications">¿Qué privadas son las notificaciones push de Delta Chat?</a></li>
<li><a href="#why-does-delta-chat-integrate-with-centralized-proprietary-applegoogle-push-services">Why does Delta Chat integrate with centralized proprietary Apple/Google push services?</a></li>
</ul>
</li>
@@ -41,7 +41,7 @@
<li><a href="#qué-estándares-se-utilizan-para-el-cifrado-de-extremo-a-extremo">¿Qué estándares se utilizan para el cifrado de extremo a extremo?</a></li>
<li><a href="#whene2e">¿Cómo puedo saber si los mensajes están cifrados de extremo a extremo?</a></li>
<li><a href="#can-i-still-receive-or-send-mails-without-end-to-end-encryption">Can i still receive or send mails without end-to-end encryption?</a></li>
<li><a href="#howtoe2ee">How can I establish a chat with a new contact?</a></li>
<li><a href="#howtoe2ee">¿Cómo puedo establecer un chat con un nuevo contacto?</a></li>
<li><a href="#e2eeguarantee">What does the green checkmark in a contact profile mean?</a></li>
<li><a href="#los-adjuntos-imágenes-archivos-audio-etc-están-cifrados-de-extremo-a-extremo">¿Los adjuntos (imágenes, archivos, audio, etc.) están cifrados de extremo a extremo?</a></li>
<li><a href="#openpgp-secure">¿Es OpenPGP seguro?</a></li>
@@ -87,6 +87,7 @@
<ul>
<li><a href="#qué-permisos-necesita-delta-chat">¿Qué permisos necesita Delta Chat?</a></li>
<li><a href="#delta-chat-funciona-con-mi-proveedor-de-correo-electrónico">¿Delta Chat funciona con <em>mi</em> proveedor de correo electrónico?</a></li>
<li><a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">Can I use Delta Chat in parallel with other E-Mail apps?</a></li>
<li><a href="#i-want-to-manage-my-own-server-for-delta-chat-what-do-you-recommend">I want to manage my own server for Delta Chat. What do you recommend?</a></li>
<li><a href="#por-qué-debo-ingresar-mi-contraseña-de-correo-electrónico-en-delta-chat-es-esto-seguro">¿Por qué debo ingresar mi contraseña de correo electrónico en Delta Chat? ¿Es esto seguro?</a></li>
<li><a href="#qué-mensajes-se-muestran-en-delta-chat">¿Qué mensajes se muestran en Delta Chat?</a></li>
@@ -215,18 +216,16 @@ Basado en <a href="https://github.com/chatmail/core/blob/main/standards.md#stand
</h3>
<p>A profile is <strong>a name, a picture</strong> and some additional information for encrypting messages.
A profile lives on your device(s) only
and uses a chatmail or a classic e-mail server to transport messages.</p>
<p>Un perfil es <strong>un nombre, una foto</strong> y algunas informaciones adicionales para encriptar los mensajes.
Un perfil solo existe dentro de tu dispositivo(s)
y utilice un servidor de chatmail o correo electrónico clásico para el transporte de los mensajes.</p>
<p>En la primera instalación de Delta Chat se crea un primer perfil.</p>
<p>Después, puedes tocar la imagen de tu perfil en la esquina superior izquierda para <strong>Añadir perfiles</strong>
o para <strong>Cambiar perfiles</strong>.</p>
<p>You may want to use separate profiles for political, family or work related activities,
or e. g. for a dedicated “spam-profile” with which you register at websites and platforms
that tend to cause unsolicited messages (“spam”) sooner or later.</p>
<p>Se podría considerar la utilización de perfiles diferenciados para actividades vinculadas con políticas, familia o trabajo, o para un perfil dedicado a “spam”, que podría ser utilizado para páginas web y plataformas que tendrán la capacidad de generar mensajes no solicitados.</p>
<p>Quizás quieres aprender <a href="#multiclient">cómo se usa el mismo perfil en múltiples dispositivos</a>.</p>
@@ -265,11 +264,11 @@ dispositivo.</p>
</h3>
<p>Yes,
you can do so under <strong>Settings → Profile → Bio</strong>.
Your contacts who use Delta Chat will see it
when they view your contact details.
Moreover, it will appear as a classic e-mail signature.</p>
<p>,
es posible hacerlo en “Ajustes → Perfil → Texto de firma”.
Los contactos que usan Delta Chat podrán ver
si revisan los detalles de tu perfil.<br />
Además, se encontrará en la firma de correos electrónicos clásicos.</p>
<h3 id="qué-significa-fijar-mutear-archivar">
@@ -326,15 +325,15 @@ Con pulsar a <img style="vertical-align:middle; width:1.2em; margin:1px" src="..
puedes volver al mensaje original en el chat original</p>
</li>
<li>
<p>Finally, you can also use “Save Messages” to take <strong>personal notes</strong> - open the chat, type something, add a photo or a voice message etc.</p>
<p>Finalmente, también se puede utilizar “Mensajes guardados” para tomar <strong>notas personales</strong> - abre el chat, escribe algo, añade una foto o un mensaje de voz, etc.</p>
</li>
<li>
<p>As “Saved Message” are synced, they can become very handy for transferring data between devices</p>
<p>Como los “mensajes guardados” se sincronizan, pueden ser muy útiles para transferir datos entre dispositivos.</p>
</li>
</ul>
<p>Messages stay saved even if they are edited or deleted -
may it be by <a href="#edit">sender</a>, by <a href="#delold">device cleanup</a> or by <a href="#ephemeralmsgs">disappearing messages of other chats</a>.</p>
<p>Los mensajes se quedan guardados, también si se han cambiado o están borrados -
Sea por el <a href="#edit">remitente</a>, por la <a href="#delold">limpieza del dispositivo</a> o por la <a href="#ephemeralmsgs">desaparición de mensajes de otros chats</a>.</p>
<h3 id="qué-significa-el-punto-verde">
@@ -349,16 +348,16 @@ junto al avatar de un contacto.
Significa que ha sido <strong>visto recientemente</strong> en los últimos 10 minutos:</p>
<ul>
<li>either because they messaged you directly,</li>
<li>because they wrote something to a group you are both a member of,</li>
<li>because they sent you a read receipt for a message you wrote,</li>
<li>because they edit or delete a message in a chat shared with you,</li>
<li>or because they use an <a href="#webxdc">app</a> in a chat shared with you.</li>
<li>sea porque te enviaron un mensaje directamente,</li>
<li>porque escribieron algo en un grupo en que ambos son miembros,</li>
<li>porque te enviaron un acuse de recibo de un mensaje que escribiste,</li>
<li>porque editaron o borraron un mensaje en un chat compartido contigo,</li>
<li>o porque utilizan una <a href="#webxdc">app</a> en un chat compartido contigo.</li>
</ul>
<p>So this is not a real time online status -
and if someone doesnt answer right away even though they seem to be online,
dont worry and give them some space :)</p>
<p>Así que esto no es un estado de en línea en tiempo real -
y si alguien no responde de inmediato, aunque parece que estar en línea,
no te preocupes y dale un poco de espacio :)</p>
<p>On the other hand, others will not always “see that you are online”.
If you have turned off read receipts,
@@ -368,16 +367,16 @@ until one of the above conditions are met.</p>
<h3 id="edit">
Correct typos and delete messages after sending <a href="#edit" class="anchor"></a>
Corregir errores y borrar mensajes después de enviar <a href="#edit" class="anchor"></a>
</h3>
<ul>
<li>
<p>You can edit the text of your messages after sending.
For that, long tap or right click the message and select <strong>Edit</strong>
or <img style="vertical-align:middle; width:1.2em; margin:1px" src="../edit-icon.png" alt="Edit icon" />.</p>
<p>Se puede editar el texto de los mensajes después de enviarlos.
Para ello, mantenga pulsado o haz clic con el botón derecho en el mensaje y seleccione <strong>Editar</strong>
o <img style="vertical-align:middle; width:1.2em; margin:1px" src="../edit-icon.png" alt="Edit icon" />.</p>
</li>
<li>
<p>Si has enviado un mensaje accidentalmente
@@ -400,11 +399,11 @@ who could have already replied, forwarded, saved, screenshotted or otherwise cop
</h3>
<p>Puedes activar “desaparición de mensajes”
en la configuración de un chat,
en la parte superior derecha de la ventana de chat,
seleccionando un lapso de tiempo
entre 1 minuto y 5 semanas.</p>
<p>You can turn on “disappearing messages”
in the settings of a chat,
at the top right of the chat window,
by selecting a time span
between 5 minutes and 1 year.</p>
<p>Hasta que la configuración se desactive nuevamente,
La aplicación Delta Chat de cada miembro del chat se encarga
@@ -560,15 +559,15 @@ older than that.</li>
<h2 id="instant-delivery">
Instant message delivery and Push Notifications <a href="#instant-delivery" class="anchor"></a>
Entrega de mensajes instantáneos y notificaciones Push <a href="#instant-delivery" class="anchor"></a>
</h2>
<h3 id="what-are-push-notifications-how-can-i-get-instant-message-delivery">
<h3 id="qué-son-las-notificaciones-push-cómo-puedo-recibir-mensajes-instantáneos">
What are Push Notifications? How can I get instant message delivery? <a href="#what-are-push-notifications-how-can-i-get-instant-message-delivery" class="anchor"></a>
¿Qué son las Notificaciones Push? ¿Cómo puedo recibir mensajes instantáneos? <a href="#qué-son-las-notificaciones-push-cómo-puedo-recibir-mensajes-instantáneos" class="anchor"></a>
</h3>
@@ -577,11 +576,11 @@ older than that.</li>
so that an inactive Delta Chat app can fetch messages in the background
and show notifications on a users phone if needed.</p>
<p>Push Notifications work with all <a href="https://delta.chat/chatmail">chatmail</a> servers on</p>
<p>Las notificaciones push funcionan con todos los servidores de <a href="https://delta.chat/chatmail">chatmail</a> en</p>
<ul>
<li>
<p>iOS devices, by integrating with Apple Push services.</p>
<p>dispositivos iOS, por la integración de los servicios Push de Apple.</p>
</li>
<li>
<p>Android devices, by integrating with the Google FCM Push service,
@@ -590,13 +589,13 @@ instead of proprietary Google code on the phone.</p>
</li>
</ul>
<p>As of May 2024, classic e-mail servers do not support Push Notifications
for Delta Chat users.</p>
<p>A partir de mayo de 2024, los servidores de correo electrónico clásicos no admiten notificaciones push
para los usuarios de Delta Chat.</p>
<h3 id="are-push-notifications-enabled-on-ios-devices-is-there-an-alternative">
<h3 id="están-activadas-las-notificaciones-push-en-los-dispositivos-ios-existe-alguna-alternativa">
Are Push Notifications enabled on iOS devices? Is there an alternative? <a href="#are-push-notifications-enabled-on-ios-devices-is-there-an-alternative" class="anchor"></a>
¿Están activadas las notificaciones Push en los dispositivos iOS? ¿Existe alguna alternativa? <a href="#están-activadas-las-notificaciones-push-en-los-dispositivos-ios-existe-alguna-alternativa" class="anchor"></a>
</h3>
@@ -611,7 +610,7 @@ does not expose data to Apple that it doesnt already have.</p>
<h3 id="android-push">
Are Push notifications enabled / needed on Android devices? <a href="#android-push" class="anchor"></a>
¿Están habilitadas / son necesarias las notificaciones Push en los dispositivos Android? <a href="#android-push" class="anchor"></a>
</h3>
@@ -649,7 +648,7 @@ safe to try if you experience messages arrive only with long delays.</p>
<h3 id="privacy-notifications">
How private are Delta Chat Push Notifications? <a href="#privacy-notifications" class="anchor"></a>
¿Qué privadas son las notificaciones push de Delta Chat? <a href="#privacy-notifications" class="anchor"></a>
</h3>
@@ -658,7 +657,7 @@ safe to try if you experience messages arrive only with long delays.</p>
It does not leak e-mail, IP address or message content (not even encrypted)
to any system involved in the delivery of Push Notifications.</p>
<p>Here is how Delta Chat apps perform Push Notification delivery:</p>
<p>Así es como las aplicaciones Delta Chat realizan la entrega de Notificaciones Push:</p>
<ul>
<li>
@@ -776,14 +775,14 @@ there are no lock or similar markers on end-to-end encrypted messages, anymore.<
it is impossible to receive or send messages without end-to-end encryption.</p>
<p>If you instead create a profile using a classic e-mail server,
you can send and receive messages without end-to-end encryption.
Such messages lacking end-to-end encryption are marked with an e-mail icon
you can send and receive messages with or without end-to-end encryption.
Messages lacking end-to-end encryption are marked with an e-mail icon
<img style="vertical-align:middle; width:1.2em; margin:1px" src="../email-icon.png" alt="email" />.</p>
<h3 id="howtoe2ee">
How can I establish a chat with a new contact? <a href="#howtoe2ee" class="anchor"></a>
¿Cómo puedo establecer un chat con un nuevo contacto? <a href="#howtoe2ee" class="anchor"></a>
</h3>
@@ -1604,6 +1603,29 @@ Esto es lo que hace Delta Chat con esos permisos:</p>
Sin embargo, algunos proveedores necesitan opciones especiales para funcionar correctamente, ver <a href="https://providers.delta.chat">Descripción de proveedores</a></li>
</ul>
<h3 id="can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">
Can I use Delta Chat in parallel with other E-Mail apps? <a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps" class="anchor"></a>
</h3>
<p>Yes, but it is not recommended.</p>
<p>Parallel usage with the same E-Mail address might lead to the following inconveniences:</p>
<ul>
<li>Next to your Delta Chat notifications,
you might also get notifications for (encrypted, so unreadable) chat mail messages
in your other email app</li>
<li>If Delta Chat is not running
or “Advanced &gt; Move automatically to the DeltaChat Folder” is disabled,
encrypted Delta Chat messages might clutter the Inbox in your other E-Mail apps.</li>
</ul>
<p><a href="https://support.delta.chat/t/sieve-rule-to-move-deltachat-mails-to-deltachat-folder/288/10">Sieve rules</a> can solve these problems.</p>
<h3 id="i-want-to-manage-my-own-server-for-delta-chat-what-do-you-recommend">
+27 -3
View File
@@ -87,6 +87,7 @@
<ul>
<li><a href="#de-quelles-autorisations-delta-chat-a-t-il-besoin">De quelles autorisations Delta Chat a-t-il besoin?</a></li>
<li><a href="#est-ce-que-delta-chat-fonctionne-avec-mon-fournisseur-de-courriel-">Est-ce que Delta Chat fonctionne avec <em>mon</em> fournisseur de courriel ?</a></li>
<li><a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">Can I use Delta Chat in parallel with other E-Mail apps?</a></li>
<li><a href="#i-want-to-manage-my-own-server-for-delta-chat-what-do-you-recommend">I want to manage my own server for Delta Chat. What do you recommend?</a></li>
<li><a href="#pourquoi-dois-je-entrer-le-mot-de-passe-de-mon-compte-de-courriel-dans-delta-chat--est-ce-sécurisé-">Pourquoi dois-je entrer le mot de passe de mon compte de courriel dans Delta Chat ? Est-ce sécurisé ?</a></li>
<li><a href="#quels-sont-les-messages-qui-apparaissent-dans-delta-chat-">Quels sont les messages qui apparaissent dans Delta Chat ?</a></li>
@@ -397,7 +398,7 @@ who could have already replied, forwarded, saved, screenshotted or otherwise cop
in the settings of a chat,
at the top right of the chat window,
by selecting a time span
between 1 minute and 5 weeks.</p>
between 5 minutes and 1 year.</p>
<p>Until the setting is turned off again,
each chat members Delta Chat app takes care
@@ -758,8 +759,8 @@ there are no lock or similar markers on end-to-end encrypted messages, anymore.<
it is impossible to receive or send messages without end-to-end encryption.</p>
<p>If you instead create a profile using a classic e-mail server,
you can send and receive messages without end-to-end encryption.
Such messages lacking end-to-end encryption are marked with an e-mail icon
you can send and receive messages with or without end-to-end encryption.
Messages lacking end-to-end encryption are marked with an e-mail icon
<img style="vertical-align:middle; width:1.2em; margin:1px" src="../email-icon.png" alt="email" />.</p>
<h3 id="howtoe2ee">
@@ -1566,6 +1567,29 @@ Voici ce que fait Delta Chat avec ces autorisations:</p>
Cependant, il faut activer des options spéciales pour que cela fonctionne correctement avec certains fournisseurs… Voir <a href="https://providers.delta.chat">la liste des fournisseurs</a>.</li>
</ul>
<h3 id="can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">
Can I use Delta Chat in parallel with other E-Mail apps? <a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps" class="anchor"></a>
</h3>
<p>Yes, but it is not recommended.</p>
<p>Parallel usage with the same E-Mail address might lead to the following inconveniences:</p>
<ul>
<li>Next to your Delta Chat notifications,
you might also get notifications for (encrypted, so unreadable) chat mail messages
in your other email app</li>
<li>If Delta Chat is not running
or “Advanced &gt; Move automatically to the DeltaChat Folder” is disabled,
encrypted Delta Chat messages might clutter the Inbox in your other E-Mail apps.</li>
</ul>
<p><a href="https://support.delta.chat/t/sieve-rule-to-move-deltachat-mails-to-deltachat-folder/288/10">Sieve rules</a> can solve these problems.</p>
<h3 id="i-want-to-manage-my-own-server-for-delta-chat-what-do-you-recommend">
+27 -3
View File
@@ -87,6 +87,7 @@
<ul>
<li><a href="#izin-apa-yang-dibutuhkan-delta-chat">Izin apa yang dibutuhkan Delta Chat?</a></li>
<li><a href="#does-delta-chat-work-with-my-e-mail-provider">Does Delta Chat work with <em>my</em> e-mail-provider?</a></li>
<li><a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">Can I use Delta Chat in parallel with other E-Mail apps?</a></li>
<li><a href="#i-want-to-manage-my-own-server-for-delta-chat-what-do-you-recommend">I want to manage my own server for Delta Chat. What do you recommend?</a></li>
<li><a href="#mengapa-saya-harus-memasukkan-kata-sandi-e-mail-saya-ke-delta-chat-apakah-ini-aman">Mengapa saya harus memasukkan kata sandi E-Mail saya ke Delta Chat? Apakah ini aman?</a></li>
<li><a href="#pesan-mana-yang-muncul-di-delta-chat">Pesan mana yang muncul di Delta Chat?</a></li>
@@ -411,7 +412,7 @@ who could have already replied, forwarded, saved, screenshotted or otherwise cop
in the settings of a chat,
at the top right of the chat window,
by selecting a time span
between 1 minute and 5 weeks.</p>
between 5 minutes and 1 year.</p>
<p>Until the setting is turned off again,
each chat members Delta Chat app takes care
@@ -784,8 +785,8 @@ there are no lock or similar markers on end-to-end encrypted messages, anymore.<
it is impossible to receive or send messages without end-to-end encryption.</p>
<p>If you instead create a profile using a classic e-mail server,
you can send and receive messages without end-to-end encryption.
Such messages lacking end-to-end encryption are marked with an e-mail icon
you can send and receive messages with or without end-to-end encryption.
Messages lacking end-to-end encryption are marked with an e-mail icon
<img style="vertical-align:middle; width:1.2em; margin:1px" src="../email-icon.png" alt="email" />.</p>
<h3 id="howtoe2ee">
@@ -1626,6 +1627,29 @@ However, some providers need special options to work properly,
see <a href="https://providers.delta.chat">Provider Overview</a></li>
</ul>
<h3 id="can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">
Can I use Delta Chat in parallel with other E-Mail apps? <a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps" class="anchor"></a>
</h3>
<p>Yes, but it is not recommended.</p>
<p>Parallel usage with the same E-Mail address might lead to the following inconveniences:</p>
<ul>
<li>Next to your Delta Chat notifications,
you might also get notifications for (encrypted, so unreadable) chat mail messages
in your other email app</li>
<li>If Delta Chat is not running
or “Advanced &gt; Move automatically to the DeltaChat Folder” is disabled,
encrypted Delta Chat messages might clutter the Inbox in your other E-Mail apps.</li>
</ul>
<p><a href="https://support.delta.chat/t/sieve-rule-to-move-deltachat-mails-to-deltachat-folder/288/10">Sieve rules</a> can solve these problems.</p>
<h3 id="i-want-to-manage-my-own-server-for-delta-chat-what-do-you-recommend">
+94 -70
View File
@@ -50,10 +50,10 @@
<li><a href="#tls">I messaggi contrassegnati dallicona della posta sono esposti su Internet?</a></li>
<li><a href="#message-metadata">In che modo Delta Chat protegge i metadati nei messaggi?</a></li>
<li><a href="#device-seizure">Come proteggere i metadati e contatti quando un dispositivo viene sequestrato?</a></li>
<li><a href="#sealedsender">Does Delta Chat support “Sealed Sender”?</a></li>
<li><a href="#sealedsender">Delta Chat supportaMittente Sigillato”?</a></li>
<li><a href="#pfs">Delta Chat supporta Perfect Forward Secrecy?</a></li>
<li><a href="#pqc">Does Delta Chat support Post-Quantum-Cryptography?</a></li>
<li><a href="#how-can-i-manually-check-encryption-information">How can I manually check encryption information?</a></li>
<li><a href="#pqc">Delta Chat supporta la Crittografia Post-Quantistica?</a></li>
<li><a href="#come-posso-controllare-manualmente-le-informazioni-di-crittografia">Come posso controllare manualmente le informazioni di crittografia?</a></li>
<li><a href="#importkey">Posso riutilizzare la mia chiave privata esistente?</a></li>
<li><a href="#security-audits">Delta Chat è stata verificata in modo indipendente per le vulnerabilità di sicurezza?</a></li>
</ul>
@@ -87,6 +87,7 @@
<ul>
<li><a href="#di-quali-autorizzazioni-ha-bisogno-delta-chat">Di quali autorizzazioni ha bisogno Delta Chat?</a></li>
<li><a href="#delta-chat-funziona-con-il-mio-fornitore-e-mail">Delta Chat funziona con il <em>mio</em> fornitore e-mail?</a></li>
<li><a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">Can I use Delta Chat in parallel with other E-Mail apps?</a></li>
<li><a href="#vorrei-gestire-il-mio-server-per-delta-chat-cosa-mi-consigliate">Vorrei gestire il mio server per Delta Chat. Cosa mi consigliate?</a></li>
<li><a href="#perché-devo-inserire-la-mia-password-e-mail-in-delta-chat-è-sicuro">Perché devo inserire la mia password E-Mail in Delta Chat? È sicuro?</a></li>
<li><a href="#quali-messaggi-vengono-mostrati-in-delta-chat">Quali messaggi vengono mostrati in Delta Chat?</a></li>
@@ -405,11 +406,11 @@ che avrebbero già potuto rispondere, inoltrare, salvare, scattare una schermata
</h3>
<p>Puoi attivare i “messaggi che scompaiono
nelle impostazioni di una chat,
in alto a destra nella finestra della chat,
selezionando un intervallo di tempo
tra 1 minuto e 5 settimane.</p>
<p>You can turn on “disappearing messages
in the settings of a chat,
at the top right of the chat window,
by selecting a time span
between 5 minutes and 1 year.</p>
<p>Fino a quando limpostazione non viene nuovamente disattivata,
lapp Delta Chat di ogni membro della chat si prende cura
@@ -776,9 +777,9 @@ non ci sono più lucchetti o marcatori simili, sui messaggi crittografati end-to
<p>Se si utilizzano i <a href="https://chatmail.at/relays">relays di chatmail</a>,
è impossibile ricevere o inviare messaggi senza la crittografia end-to-end.</p>
<p>Se invece si crea un profilo utilizzando un server di posta elettronica classico,
è possibile inviare e ricevere messaggi senza crittografia end-to-end.
I messaggi privi di crittografia end-to-end sono contrassegnati da unicona e-mail<br />
<p>If you instead create a profile using a classic e-mail server,
you can send and receive messages with or without end-to-end encryption.
Messages lacking end-to-end encryption are marked with an e-mail icon
<img style="vertical-align:middle; width:1.2em; margin:1px" src="../email-icon.png" alt="email" />.</p>
<h3 id="howtoe2ee">
@@ -838,16 +839,16 @@ la crittografia end-to-end sarà stabilita tra tutti i membri.</p>
</h3>
<p>A contact profile might show a green checkmark
<p>Il profilo di un contatto potrebbe mostrare una spunta verde
<img style="vertical-align:middle; width:1.5em; margin:1px" src="../green-checkmark.png" alt="green checkmark" />
and an “Introduced by” line.
Every green-checkmarked contact either did a direct <a href="#howtoe2ee">QR-scan</a> with you
or was introduced by a another green-checkmarked contact.
Introductions happen automatically when adding members to groups.
Whoever adds a green-checkmarked contact to a group with only green-checkmarked members
becomes an introducer.
In a contact profile you can tap on the “Introduced by …” text repeatedly
until you get to the one with whom you directly did a <a href="#howtoe2ee">QR-scan</a>.</p>
e una linea “Verificato da”.
Ogni contatto con la spunta verde ha fatto un <a href="#howtoe2ee">QR-scan</a> con te
o è stato verificato da un altro contatto con la spunta verde.
La verifica si ha automaticamente allaggiunta dei membri nei gruppi.
Chiunque aggiunga un contatto con spunta verde a un gruppo con solo membri con la spunta verde
diventa colui che lha verificato.
Nel profilo di un contatto puoi premere sul campo “Verificato da …” ripetutamente
fino a che vedi con chi hai avuto un <a href="#howtoe2ee">QR-scan</a>.</p>
<p>Per una discussione più approfondita sulla “crittografia end-to-end garantita”
consultare <a href="https://securejoin.delta.chat/en/latest/new.html">Protocolli Secure-Join</a>
@@ -969,25 +970,25 @@ anche se il messaggio non sarà crittografato end-to-end.</p>
</h3>
<p>Unlike most other messengers,
Delta Chat apps do not store any metadata about contacts or groups on servers, also not in encrypted form.
Instead, all group metadata is end-to-end encrypted and stored on end-user devices, only.</p>
<p>A differenza della maggior parte degli altri servizi di messaggistica,
le apps Delta Chat non memorizzano alcun metadato sui contatti o sui gruppi sui server, né in forma crittografata.
Tutti i metadati dei gruppi sono invece crittografati end-to-end e memorizzati esclusivamente sui dispositivi degli utenti finali.</p>
<p>E-mail Servers can therefore only see</p>
<p>I Server E-mail possono quindi vedere solo</p>
<ul>
<li>
<p>the message date,</p>
<p>la data del messaggio,</p>
</li>
<li>
<p>sender and receiver addresses</p>
<p>indirizzi del mittente e del destinatario</p>
</li>
<li>
<p>and message size.</p>
<p>e dimensione del messaggio.</p>
</li>
</ul>
<p>All other message, contact and group metadata resides in the end-to-end encrypted part of messages.</p>
<p>Tutti gli altri metadati dei messaggi, dei contatti e dei gruppi risiedono nella parte crittografata end-to-end dei messaggi.</p>
<h3 id="device-seizure">
@@ -997,36 +998,36 @@ Instead, all group metadata is end-to-end encrypted and stored on end-user devic
</h3>
<p>Both for protecting against metadata-collecting e-mail servers
as well as against the threat of device seizure
we recommend to use a <a href="https://chatmail.at/relays">chatmail relay</a>
to create chat profiles using random e-mail addresses for transport.
Note that Delta Chat apps on all platforms support multiple profiles
so you can easily use situation-specific profiles next to your “main” profile
with the knowledge that all their data, along with all metadata, will be deleted.
Moreover, if a device is seized then chat contacts using short-lived profiles
can not be identified easily.</p>
<p>Sia per proteggersi dai server e-mail che raccolgono metadati
sia per proteggersi dal rischio di sequestro del dispositivo,
consigliamo di utilizzare un <a href="https://chatmail.at/relays">chatmail relay</a>
per creare profili di chat utilizzando indirizzi e-mail casuali per il trasporto.
Si noti che le apps Delta Chat su tutte le piattaforme supportano più profili,
quindi è possibile utilizzare facilmente profili specifici per ogni situazione accanto al profilo “principale”,
con la consapevolezza che tutti i loro dati, insieme a tutti i metadati, verranno eliminati.
Inoltre, se un dispositivo viene sequestrato, i contatti di chat che utilizzano profili di breve durata
non possono essere identificati facilmente.</p>
<h3 id="sealedsender">
Does Delta Chat support “Sealed Sender”? <a href="#sealedsender" class="anchor"></a>
Delta Chat supportaMittente Sigillato”? <a href="#sealedsender" class="anchor"></a>
</h3>
<p>No, non ancora.</p>
<p>The Signal messenger introduced <a href="https://signal.org/blog/sealed-sender/">Sealed Sender” in 2018</a>
to keep their server infrastructure ignorant of who is sending a message to a set of recipients.
It is particularly important because the Signal server knows the mobile number of each account,
which is usually associated with a passport identity.</p>
<p>Il messenger Signal ha introdotto <a href="https://signal.org/blog/sealed-sender/">Mittente Sigillato” nel 2018</a>
per impedire che la propria infrastruttura server venga a conoscenza di chi sta inviando un messaggio a un insieme di destinatari.
È particolarmente importante perché il server Signal conosce il numero di cellulare di ciascun profilo,
che di solito è associato a unidentità tramite passaporto.</p>
<p>Even if <a href="https://chatmail.at/relays">chatmail relays</a>
do not ask for any private data (including no phone numbers),
it might still be worthwhile to protect relational metadata between addresses.
We dont foresee bigger problems in using random throw-away e-mail addresses for sealed sending
but an implementation has not been agreed as a priority yet.</p>
<p>Anche se i <a href="https://chatmail.at/relays">relays di chat</a>
non richiedono dati privati (inclusi numeri di telefono),
potrebbe comunque valere la pena proteggere i metadati relazionali tra gli indirizzi.
Non prevediamo problemi maggiori nellutilizzo di indirizzi e-mail casuali usa e getta per linvio sigillato,
ma unimplementazione non è stata ancora concordata come priorità.</p>
<h3 id="pfs">
@@ -1038,41 +1039,41 @@ but an implementation has not been agreed as a priority yet.</p>
<p>No, non ancora.</p>
<p>Delta Chat today doesnt support Perfect Forward Secrecy (PFS).
This means that if your private decryption key is leaked,
and someone has collected your prior in-transit messages,
they will be able to decrypt and read them using the leaked decryption key.
Note that Forward Secrecy only increases security if you delete messages.
Otherwise, someone obtaining your decryption keys
is typically also able to get all your non-deleted messages
and doesnt even need to decrypt any previously collected messages.</p>
<p>Delta Chat al momento non supporta la tecnologia Perfect Forward Secrecy (PFS).
Ciò significa che se la tua chiave di decrittazione privata viene divulgata
e qualcuno ha raccolto i tuoi messaggi in transito precedenti,
sarà in grado di decifrarli e leggerli utilizzando la chiave di decrittazione divulgata.
Tieni presente che la tecnologia Forward Secrecy aumenta la sicurezza solo se elimini i messaggi.
In caso contrario, chi ottiene le tue chiavi di decrittazione
in genere è in grado di ottenere anche tutti i tuoi messaggi non eliminati
e non ha nemmeno bisogno di decifrare i messaggi raccolti in precedenza.</p>
<p>We designed a Forward Secrecy approach that withstood
initial examination from some cryptographers and implementation experts
but is pending a more formal write up
to ascertain it reliably works in federated messaging and with multi-device usage,
before it could be implemented in <a href="https://github.com/chatmail/core">chatmail core</a>,
which would make it available in all <a href="https://chatmail.at/clients">chatmail clients</a>.</p>
<p>Abbiamo progettato un approccio Forward Secrecy che ha superato
lesame iniziale di alcuni crittografi ed esperti di implementazione
ma è in attesa di una stesura più formale
per accertarne laffidabilità nella messaggistica federata e nellutilizzo su più dispositivi,
prima di poter essere implementato in <a href="https://github.com/chatmail/core">chatmail core</a>,
che lo renderebbe disponibile in tutti i <a href="https://chatmail.at/clients">clients di chatmail</a>.</p>
<h3 id="pqc">
Does Delta Chat support Post-Quantum-Cryptography? <a href="#pqc" class="anchor"></a>
Delta Chat supporta la Crittografia Post-Quantistica? <a href="#pqc" class="anchor"></a>
</h3>
<p>No, non ancora.</p>
<p>Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
We aim to add PQC support in <a href="https://github.com/chatmail/core">chatmail core</a> after the draft is finalized at the IETF
in collaboration with other OpenPGP implementers.</p>
<p>Delta Chat utilizza la libreria Rust OpenPGP <a href="https://github.com/rpgp/rpgp">rPGP</a>
che supporta lultima <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">bozza IETF Post-Quantum-Cryptography OpenPGP</a>.
Il nostro obiettivo è aggiungere il supporto PQC nel <a href="https://github.com/chatmail/core">core di chatmail</a> dopo che la bozza sarà stata finalizzata dallIETF
in collaborazione con altri implementatori di OpenPGP.</p>
<h3 id="how-can-i-manually-check-encryption-information">
<h3 id="come-posso-controllare-manualmente-le-informazioni-di-crittografia">
How can I manually check encryption information? <a href="#how-can-i-manually-check-encryption-information" class="anchor"></a>
Come posso controllare manualmente le informazioni di crittografia? <a href="#come-posso-controllare-manualmente-le-informazioni-di-crittografia" class="anchor"></a>
</h3>
@@ -1096,8 +1097,8 @@ la connessione è sicura.</p>
<p>Delta Chat genera chiavi OpenPGP sicure in conformità alle specifiche di Autocrypt 1.1.
Puoi esportare le tue chiavi private ma non puoi importare chiavi private aggiuntive.</p>
<p>In generale, non raccomandiamo on proponiamo agli utenti di gestire manualmente le chiavi.
Noi vogliamo assicurare che gli audit di sicurezza si possano focalizzare su pochi algoritmi crittografici comprovati
<p>In generale, non raccomandiamo o proponiamo agli utenti di gestire manualmente le chiavi.
Noi vogliamo assicurare che gli audits di sicurezza si possano focalizzare su pochi algoritmi crittografici comprovati
invece che sullintera estensione dei possibili algoritmi consentiti con OpenPGP.</p>
<h3 id="security-audits">
@@ -1596,6 +1597,29 @@ Tuttavia, alcuni provider necessitano di opzioni speciali per funzionare corrett
vedi <a href="https://providers.delta.chat">Panoramica fornitore</a></li>
</ul>
<h3 id="can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">
Can I use Delta Chat in parallel with other E-Mail apps? <a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps" class="anchor"></a>
</h3>
<p>Yes, but it is not recommended.</p>
<p>Parallel usage with the same E-Mail address might lead to the following inconveniences:</p>
<ul>
<li>Next to your Delta Chat notifications,
you might also get notifications for (encrypted, so unreadable) chat mail messages
in your other email app</li>
<li>If Delta Chat is not running
or “Advanced &gt; Move automatically to the DeltaChat Folder” is disabled,
encrypted Delta Chat messages might clutter the Inbox in your other E-Mail apps.</li>
</ul>
<p><a href="https://support.delta.chat/t/sieve-rule-to-move-deltachat-mails-to-deltachat-folder/288/10">Sieve rules</a> can solve these problems.</p>
<h3 id="vorrei-gestire-il-mio-server-per-delta-chat-cosa-mi-consigliate">
+27 -3
View File
@@ -87,6 +87,7 @@
<ul>
<li><a href="#welke-android-rechten-heeft-delta-chat-nodig">Welke Android-rechten heeft Delta Chat nodig?</a></li>
<li><a href="#wordt-mijn-e-mailprovider-ondersteund-door-delta-chat">Wordt <em>mijn</em> e-mailprovider ondersteund door Delta Chat?</a></li>
<li><a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">Can I use Delta Chat in parallel with other E-Mail apps?</a></li>
<li><a href="#i-want-to-manage-my-own-server-for-delta-chat-what-do-you-recommend">I want to manage my own server for Delta Chat. What do you recommend?</a></li>
<li><a href="#waarom-moet-ik-mijn-e-mailwachtwoord-invoeren-in-delta-chat-is-dat-wel-veilig">Waarom moet ik mijn e-mailwachtwoord invoeren in Delta Chat? Is dat wel veilig?</a></li>
<li><a href="#welke-berichten-vind-ik-terug-in-delta-chat">Welke berichten vind ik terug in Delta Chat?</a></li>
@@ -407,7 +408,7 @@ who could have already replied, forwarded, saved, screenshotted or otherwise cop
in the settings of a chat,
at the top right of the chat window,
by selecting a time span
between 1 minute and 5 weeks.</p>
between 5 minutes and 1 year.</p>
<p>Until the setting is turned off again,
each chat members Delta Chat app takes care
@@ -777,8 +778,8 @@ there are no lock or similar markers on end-to-end encrypted messages, anymore.<
it is impossible to receive or send messages without end-to-end encryption.</p>
<p>If you instead create a profile using a classic e-mail server,
you can send and receive messages without end-to-end encryption.
Such messages lacking end-to-end encryption are marked with an e-mail icon
you can send and receive messages with or without end-to-end encryption.
Messages lacking end-to-end encryption are marked with an e-mail icon
<img style="vertical-align:middle; width:1.2em; margin:1px" src="../email-icon.png" alt="email" />.</p>
<h3 id="howtoe2ee">
@@ -1617,6 +1618,29 @@ Delta Chat doet het volgende met deze rechten:</p>
Sommige providers verwachten echter bepaalde opties. Bekijk hiervoor het <a href="https://providers.delta.chat">provideroverzicht</a></li>
</ul>
<h3 id="can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">
Can I use Delta Chat in parallel with other E-Mail apps? <a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps" class="anchor"></a>
</h3>
<p>Yes, but it is not recommended.</p>
<p>Parallel usage with the same E-Mail address might lead to the following inconveniences:</p>
<ul>
<li>Next to your Delta Chat notifications,
you might also get notifications for (encrypted, so unreadable) chat mail messages
in your other email app</li>
<li>If Delta Chat is not running
or “Advanced &gt; Move automatically to the DeltaChat Folder” is disabled,
encrypted Delta Chat messages might clutter the Inbox in your other E-Mail apps.</li>
</ul>
<p><a href="https://support.delta.chat/t/sieve-rule-to-move-deltachat-mails-to-deltachat-folder/288/10">Sieve rules</a> can solve these problems.</p>
<h3 id="i-want-to-manage-my-own-server-for-delta-chat-what-do-you-recommend">
+52 -52
View File
@@ -50,10 +50,10 @@
<li><a href="#tls">Czy wiadomości oznaczone ikoną poczty są widoczne w internecie?</a></li>
<li><a href="#message-metadata">W jaki sposób Delta Chat chroni metadane w wiadomościach?</a></li>
<li><a href="#device-seizure">Jak chronić metadane i kontakty w przypadku przejęcia urządzenia?</a></li>
<li><a href="#sealedsender">Does Delta Chat support “Sealed Sender”?</a></li>
<li><a href="#sealedsender">Czy Delta Chat obsługuje funkcję „Sealed Sender”?</a></li>
<li><a href="#pfs">Czy Delta Chat obsługuje funkcję Perfect Forward Secrecy?</a></li>
<li><a href="#pqc">Does Delta Chat support Post-Quantum-Cryptography?</a></li>
<li><a href="#how-can-i-manually-check-encryption-information">How can I manually check encryption information?</a></li>
<li><a href="#pqc">Czy Delta Chat obsługuje kryptografię postkwantową?</a></li>
<li><a href="#jak-mogę-ręcznie-sprawdzić-informacje-o-szyfrowaniu">Jak mogę ręcznie sprawdzić informacje o szyfrowaniu?</a></li>
<li><a href="#importkey">Czy mogę ponownie wykorzystać mój istniejący klucz prywatny?</a></li>
<li><a href="#security-audits">Czy Delta Chat był niezależnie kontrolowany pod kątem luk w zabezpieczeniach?</a></li>
</ul>
@@ -87,6 +87,7 @@
<ul>
<li><a href="#jakich-uprawnień-potrzebuje-delta-chat">Jakich uprawnień potrzebuje Delta Chat?</a></li>
<li><a href="#czy-delta-chat-działa-z-moim-dostawcą-poczty-e-mail">Czy Delta Chat działa z <em>moim</em> dostawcą poczty e-mail?</a></li>
<li><a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">Can I use Delta Chat in parallel with other E-Mail apps?</a></li>
<li><a href="#chcę-zarządzać-własnym-serwerem-dla-delta-chat-co-polecacie">Chcę zarządzać własnym serwerem dla Delta Chat. Co polecacie?</a></li>
<li><a href="#dlaczego-muszę-wpisać-moje-hasło-e-mail-do-delta-chat-czy-to-jest-bezpieczne">Dlaczego muszę wpisać moje hasło e-mail do Delta Chat? Czy to jest bezpieczne?</a></li>
<li><a href="#jakie-wiadomości-pojawiają-się-w-delta-chat">Jakie wiadomości pojawiają się w Delta Chat?</a></li>
@@ -356,7 +357,11 @@
</h3>
<p>Możesz włączyć „znikające wiadomości” w ustawieniach czatu, w prawym górnym rogu okna czatu, wybierając przedział czasu od 1 minuty do 5 tygodni.</p>
<p>You can turn on “disappearing messages”
in the settings of a chat,
at the top right of the chat window,
by selecting a time span
between 5 minutes and 1 year.</p>
<p>Dopóki ustawienie nie zostanie ponownie wyłączone, aplikacja Delta Chat u każdego członka czatu zajmie się usuwaniem wiadomości po wybranym okresie. Przedział czasu rozpoczyna się w momencie, gdy odbiorca po raz pierwszy zobaczy wiadomość w Delta Chat. Wiadomości są usuwane zarówno na każdym koncie e-mail na serwerze, jak i w samej aplikacji.</p>
@@ -638,7 +643,10 @@ nadal będziesz mógł pisać, ale nie będziesz już powiadamiany o żadnych no
<p>Jeśli korzystasz z domyślnych <a href="https://chatmail.at/relays">przekaźników chatmail</a>, odbieranie ani wysyłanie wiadomości bez szyfrowania end-to-end jest niemożliwe.</p>
<p>Jeśli zamiast tego utworzysz profil przy użyciu klasycznego serwera poczty e-mail, możesz wysyłać i odbierać wiadomości bez szyfrowania end-to-end. Takie wiadomości bez szyfrowania end-to-end są oznaczone ikoną e-mail <img style="vertical-align:middle; width:1.2em; margin:1px" src="../email-icon.png" alt="email" />.</p>
<p>If you instead create a profile using a classic e-mail server,
you can send and receive messages with or without end-to-end encryption.
Messages lacking end-to-end encryption are marked with an e-mail icon
<img style="vertical-align:middle; width:1.2em; margin:1px" src="../email-icon.png" alt="email" />.</p>
<h3 id="howtoe2ee">
@@ -782,36 +790,21 @@ nadal będziesz mógł pisać, ale nie będziesz już powiadamiany o żadnych no
</h3>
<p>Both for protecting against metadata-collecting e-mail servers
as well as against the threat of device seizure
we recommend to use a <a href="https://chatmail.at/relays">chatmail relay</a>
to create chat profiles using random e-mail addresses for transport.
Note that Delta Chat apps on all platforms support multiple profiles
so you can easily use situation-specific profiles next to your “main” profile
with the knowledge that all their data, along with all metadata, will be deleted.
Moreover, if a device is seized then chat contacts using short-lived profiles
can not be identified easily.</p>
<p>Zarówno w celu ochrony przed serwerami poczty e-mail gromadzącymi metadane, jak i przed zagrożeniem przejęcia urządzenia, zalecamy użycie <a href="https://chatmail.at/relays">przełącznika chatmail</a> do tworzenia profili czatu z losowymi adresami e-mail do przesyłania. Pamiętaj, że aplikacje Delta Chat na wszystkich platformach obsługują wiele kont, dzięki czemu możesz z łatwością korzystać z kont „1-tygodniowych” lub „1-miesięcznych” związanych z konkretnymi działaniami obok konta „głównego”, wiedząc, że wszystkie tymczasowe dane konta wraz ze wszystkimi metadanymi zostaną usunięte. Co więcej, jeśli urządzenie zostanie przejęte, kontakty czatu korzystające z profili krótkotrwałych nie będą mogły zostać łatwo zidentyfikowane.</p>
<h3 id="sealedsender">
Does Delta Chat support “Sealed Sender”? <a href="#sealedsender" class="anchor"></a>
Czy Delta Chat obsługuje funkcję „Sealed Sender”? <a href="#sealedsender" class="anchor"></a>
</h3>
<p>No, not yet.</p>
<p>Nie, jeszcze nie.</p>
<p>The Signal messenger introduced <a href="https://signal.org/blog/sealed-sender/">Sealed Sender” in 2018</a>
to keep their server infrastructure ignorant of who is sending a message to a set of recipients.
It is particularly important because the Signal server knows the mobile number of each account,
which is usually associated with a passport identity.</p>
<p>Komunikator Signal wprowadził funkcję <a href="https://signal.org/blog/sealed-sender/">Sealed Sender”</a> w 2018 roku, aby infrastruktura serwerowa nie wiedziała, kto wysyła wiadomość do grupy odbiorców. Jest to szczególnie ważne, ponieważ serwer Signal zna numer telefonu komórkowego każdego konta, który zazwyczaj jest powiązany z identyfikatorem paszportu.</p>
<p>Even if <a href="https://chatmail.at/relays">chatmail relays</a>
do not ask for any private data (including no phone numbers),
it might still be worthwhile to protect relational metadata between addresses.
We dont foresee bigger problems in using random throw-away e-mail addresses for sealed sending
but an implementation has not been agreed as a priority yet.</p>
<p>Nawet jeśli <a href="https://chatmail.at/relays">przekaźniki chatmail</a> nie proszą o żadne prywatne dane (w tym numery telefonów), warto chronić metadane relacji między adresami. Nie przewidujemy poważniejszych problemów w korzystaniu z losowych, jednorazowych adresów e-mail do wysyłania wiadomości w tajemnicy, ale wdrożenie tej funkcji nie zostało jeszcze uznane za priorytetowe.</p>
<h3 id="pfs">
@@ -821,43 +814,28 @@ but an implementation has not been agreed as a priority yet.</p>
</h3>
<p>No, not yet.</p>
<p>Nie, jeszcze nie.</p>
<p>Delta Chat today doesnt support Perfect Forward Secrecy (PFS).
This means that if your private decryption key is leaked,
and someone has collected your prior in-transit messages,
they will be able to decrypt and read them using the leaked decryption key.
Note that Forward Secrecy only increases security if you delete messages.
Otherwise, someone obtaining your decryption keys
is typically also able to get all your non-deleted messages
and doesnt even need to decrypt any previously collected messages.</p>
<p>Delta Chat obecnie nie obsługuje mechanizmu Perfect Forward Secrecy (PFS). Oznacza to, że jeśli twój prywatny klucz deszyfrujący zostanie ujawniony, a ktoś zdobędzie twoje wcześniejsze wiadomości w trakcie transmisji, będzie mógł je odszyfrować i odczytać za pomocą ujawnionego klucza deszyfrującego. Należy pamiętać, że mechanizm Forward Secrecy zwiększa bezpieczeństwo tylko w przypadku usuwania wiadomości. W przeciwnym razie osoba, która uzyska twoje klucze deszyfrujące, zazwyczaj będzie mogła uzyskać dostęp do wszystkich nieusuniętych wiadomości i nie będzie musiała odszyfrowywać żadnych wcześniej zebranych wiadomości.</p>
<p>We designed a Forward Secrecy approach that withstood
initial examination from some cryptographers and implementation experts
but is pending a more formal write up
to ascertain it reliably works in federated messaging and with multi-device usage,
before it could be implemented in <a href="https://github.com/chatmail/core">chatmail core</a>,
which would make it available in all <a href="https://chatmail.at/clients">chatmail clients</a>.</p>
<p>Opracowaliśmy metodę Forward Secrecy, która przeszła wstępną analizę niektórych kryptografów i ekspertów ds. wdrożeń, ale oczekuje na bardziej formalne opracowanie, które potwierdzi jej niezawodne działanie w federacyjnym przesyłaniu wiadomości i w przypadku korzystania z wielu urządzeń, zanim zostanie zaimplementowana w <a href="https://github.com/chatmail/core">rdzeniu chatmail</a>, co uczyniłoby ją dostępną we wszystkich <a href="https://chatmail.at/clients">klientach chatmail</a>.</p>
<h3 id="pqc">
Does Delta Chat support Post-Quantum-Cryptography? <a href="#pqc" class="anchor"></a>
Czy Delta Chat obsługuje kryptografię postkwantową? <a href="#pqc" class="anchor"></a>
</h3>
<p>No, not yet.</p>
<p>Nie, jeszcze nie.</p>
<p>Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
We aim to add PQC support in <a href="https://github.com/chatmail/core">chatmail core</a> after the draft is finalized at the IETF
in collaboration with other OpenPGP implementers.</p>
<p>Delta Chat korzysta z biblioteki Rust OpenPGP <a href="https://github.com/rpgp/rpgp">rPGP</a>, która obsługuje najnowszy <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">projekt OpenPGP IETF Post-Quantum-Cryptography</a>. Planujemy dodać obsługę PQC do <a href="https://github.com/chatmail/core">rdzenia chatmail</a> po sfinalizowaniu projektu w IETF we współpracy z innymi implementatorami OpenPGP.</p>
<h3 id="how-can-i-manually-check-encryption-information">
<h3 id="jak-mogę-ręcznie-sprawdzić-informacje-o-szyfrowaniu">
How can I manually check encryption information? <a href="#how-can-i-manually-check-encryption-information" class="anchor"></a>
Jak mogę ręcznie sprawdzić informacje o szyfrowaniu? <a href="#jak-mogę-ręcznie-sprawdzić-informacje-o-szyfrowaniu" class="anchor"></a>
</h3>
@@ -1184,10 +1162,9 @@ Listy rozgłoszeniowe są nadal wysoce eksperymentalne i bardzo prawdopodobne,
</h3>
<p>Note:
Changing email addresses is temporarily disabled
because of ongoing changes to the DeltaChat core.
It should be available again in a few months.</p>
<p>Uwaga: Zmiana adresów e-mail jest tymczasowo wyłączona
z powodu trwających zmian w rdzeniu DeltaChat.
Powinna być ponownie dostępna za kilka miesięcy.</p>
<ol>
<li>
@@ -1262,6 +1239,29 @@ Oto, co robi Delta Chat z tymi uprawnieniami:</p>
Jednak niektórzy dostawcy potrzebują specjalnych opcji, aby działać poprawnie, zobacz <a href="https://providers.delta.chat">Przegląd dostawców</a></li>
</ul>
<h3 id="can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">
Can I use Delta Chat in parallel with other E-Mail apps? <a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps" class="anchor"></a>
</h3>
<p>Yes, but it is not recommended.</p>
<p>Parallel usage with the same E-Mail address might lead to the following inconveniences:</p>
<ul>
<li>Next to your Delta Chat notifications,
you might also get notifications for (encrypted, so unreadable) chat mail messages
in your other email app</li>
<li>If Delta Chat is not running
or “Advanced &gt; Move automatically to the DeltaChat Folder” is disabled,
encrypted Delta Chat messages might clutter the Inbox in your other E-Mail apps.</li>
</ul>
<p><a href="https://support.delta.chat/t/sieve-rule-to-move-deltachat-mails-to-deltachat-folder/288/10">Sieve rules</a> can solve these problems.</p>
<h3 id="chcę-zarządzać-własnym-serwerem-dla-delta-chat-co-polecacie">
+27 -3
View File
@@ -87,6 +87,7 @@
<ul>
<li><a href="#quais-permissões-o-delta-chat-precisa">Quais permissões o Delta Chat precisa?</a></li>
<li><a href="#o-delta-chat-funciona-com-meu-provedor-de-e-mail">O Delta Chat funciona com <em>meu</em> provedor de e-mail?</a></li>
<li><a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">Can I use Delta Chat in parallel with other E-Mail apps?</a></li>
<li><a href="#i-want-to-manage-my-own-server-for-delta-chat-what-do-you-recommend">I want to manage my own server for Delta Chat. What do you recommend?</a></li>
<li><a href="#por-que-preciso-entrar-com-a-senha-do-meu-email-no-delta-chat-isso-é-seguro">Por que preciso entrar com a senha do meu email no Delta Chat? Isso é seguro?</a></li>
<li><a href="#quais-mensagens-aparecem-no-delta-chat">Quais mensagens aparecem no Delta Chat?</a></li>
@@ -407,7 +408,7 @@ who could have already replied, forwarded, saved, screenshotted or otherwise cop
in the settings of a chat,
at the top right of the chat window,
by selecting a time span
between 1 minute and 5 weeks.</p>
between 5 minutes and 1 year.</p>
<p>Until the setting is turned off again,
each chat members Delta Chat app takes care
@@ -778,8 +779,8 @@ there are no lock or similar markers on end-to-end encrypted messages, anymore.<
it is impossible to receive or send messages without end-to-end encryption.</p>
<p>If you instead create a profile using a classic e-mail server,
you can send and receive messages without end-to-end encryption.
Such messages lacking end-to-end encryption are marked with an e-mail icon
you can send and receive messages with or without end-to-end encryption.
Messages lacking end-to-end encryption are marked with an e-mail icon
<img style="vertical-align:middle; width:1.2em; margin:1px" src="../email-icon.png" alt="email" />.</p>
<h3 id="howtoe2ee">
@@ -1618,6 +1619,29 @@ No entanto, alguns provedores precisam de opções especiais para funcionar corr
ver <a href="https://providers.delta.chat">Visão Geral dos Provedores</a></li>
</ul>
<h3 id="can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">
Can I use Delta Chat in parallel with other E-Mail apps? <a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps" class="anchor"></a>
</h3>
<p>Yes, but it is not recommended.</p>
<p>Parallel usage with the same E-Mail address might lead to the following inconveniences:</p>
<ul>
<li>Next to your Delta Chat notifications,
you might also get notifications for (encrypted, so unreadable) chat mail messages
in your other email app</li>
<li>If Delta Chat is not running
or “Advanced &gt; Move automatically to the DeltaChat Folder” is disabled,
encrypted Delta Chat messages might clutter the Inbox in your other E-Mail apps.</li>
</ul>
<p><a href="https://support.delta.chat/t/sieve-rule-to-move-deltachat-mails-to-deltachat-folder/288/10">Sieve rules</a> can solve these problems.</p>
<h3 id="i-want-to-manage-my-own-server-for-delta-chat-what-do-you-recommend">
+139 -116
View File
@@ -45,15 +45,15 @@
<li><a href="#e2eeguarantee">Что означает зеленая галочка в профиле контакта?</a></li>
<li><a href="#зашифрованы-ли-вложения-изображения-файлы-аудио-и-т-д-сквозным-шифрованием">Зашифрованы ли вложения (изображения, файлы, аудио и т. д.) сквозным шифрованием?</a></li>
<li><a href="#openpgp-secure">OpenPGP безопасен?</a></li>
<li><a href="#openpgp-alternatives">Did you consider using alternatives to OpenPGP for end-to-end-encryption?</a></li>
<li><a href="#openpgp-alternatives">Рассматривали ли вы альтернативы OpenPGP для сквозного шифрования?</a></li>
<li><a href="#подвержен-ли-delta-chat-уязвимости-efail">Подвержен ли Delta Chat уязвимости EFAIL?</a></li>
<li><a href="#tls">Видны ли в Интернете сообщения, отмеченные значком почты?</a></li>
<li><a href="#message-metadata">Как Delta Chat защищает метаданные в сообщениях?</a></li>
<li><a href="#device-seizure">Как защитить метаданные и контакты при изъятии устройства?</a></li>
<li><a href="#sealedsender">Does Delta Chat support “Sealed Sender”?</a></li>
<li><a href="#pfs">Поддерживает ли Delta Chat совершенную прямую секретность (Perfect forward secrecy, PFS)?</a></li>
<li><a href="#pqc">Does Delta Chat support Post-Quantum-Cryptography?</a></li>
<li><a href="#how-can-i-manually-check-encryption-information">How can I manually check encryption information?</a></li>
<li><a href="#sealedsender">Поддерживает ли Delta Chat функцию “Sealed Sender” (Засекреченный отправитель)?</a></li>
<li><a href="#pfs">Поддерживает ли Delta Chat свойство Perfect forward secrecy, PFS (Совершенную прямую секретность)?</a></li>
<li><a href="#pqc">Поддерживает ли Delta Chat Post-Quantum-Cryptography (Постквантовую криптографию)?</a></li>
<li><a href="#как-можно-вручную-проверить-информацию-о-шифровании">Как можно вручную проверить информацию о шифровании?</a></li>
<li><a href="#importkey">Можно ли повторно использовать существующий секретный ключ?</a></li>
<li><a href="#security-audits">Проходил ли Delta Chat независимую проверку на наличие уязвимостей безопасности?</a></li>
</ul>
@@ -87,6 +87,7 @@
<ul>
<li><a href="#какие-разрешения-нужны-delta-chat">Какие разрешения нужны Delta Chat?</a></li>
<li><a href="#работает-ли-delta-chat-с-моим-провайдером-электронной-почты">Работает ли Delta Chat с <em>моим</em> провайдером электронной почты?</a></li>
<li><a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">Can I use Delta Chat in parallel with other E-Mail apps?</a></li>
<li><a href="#я-хочу-управлять-своим-собственным-сервером-для-delta-chat-что-вы-посоветуете">Я хочу управлять своим собственным сервером для Delta Chat. Что вы посоветуете?</a></li>
<li><a href="#почему-я-должен-вводить-свой-пароль-от-электронной-почты-в-delta-chat-это-безопасно">Почему я должен вводить свой пароль от электронной почты в Delta Chat? Это безопасно?</a></li>
<li><a href="#какие-сообщения-отображаются-в-delta-chat">Какие сообщения отображаются в Delta Chat?</a></li>
@@ -403,11 +404,11 @@
</h3>
<p>Вы можете включить “исчезающие сообщения
в настройках чата,
в правом верхнем углу окна чата,
выбрав временной интервал
от 1 минуты до 5 недель.</p>
<p>You can turn on “disappearing messages
in the settings of a chat,
at the top right of the chat window,
by selecting a time span
between 5 minutes and 1 year.</p>
<p>Пока настройка не будет снова отключена,
приложение Delta Chat каждого участника чата позаботится
@@ -732,22 +733,22 @@ Push-уведомления недоступны.</p>
</h3>
<p>Delta Chat uses a <a href="#openpgp-secure">secure subset of the OpenPGP standard</a>
to provide automatic end-to-end encryption using these protocols:</p>
<p>Delta Chat использует <a href="#openpgp-secure">безопасное подмножество стандарта OpenPGP</a>
для реализации автоматического сквозного шифрования c помощью следующих протоколов:</p>
<ul>
<li>
<p><a href="https://securejoin.delta.chat/en/latest/new.html">Secure-Join</a>
to exchange encryption setup information through QR-code scanning or “invite links”.</p>
для обмена информацией о настройке шифрования через сканирование QR-кода или “ссылок-приглашений”.</p>
</li>
<li>
<p><a href="https://autocrypt.org">Autocrypt</a> is used for automatically
establishing end-to-end encryption between contacts and all members of a group chat.</p>
<p><a href="https://autocrypt.org">Autocrypt</a> используется для автоматической
настройки сквозного шифрования между контактами и всеми членами группового чата.</p>
</li>
<li>
<p><a href="https://github.com/chatmail/core/blob/main/spec.md#attaching-a-contact-to-a-message">Sharing a contact to a
chat</a>
enables receivers to use end-to-end encryption with the contact.</p>
<p><a href="https://github.com/chatmail/core/blob/main/spec.md#attaching-a-contact-to-a-message">Обмен контактом в
чате</a>
позволяет получателям настроить сквозное шифрование с этим контактом.</p>
</li>
</ul>
@@ -761,9 +762,9 @@ enables receivers to use end-to-end encryption with the contact.</p>
</h3>
<p>All messages in Delta Chat are <strong>end-to-end encrypted by default</strong>.
Since the Delta Chat Version 2 release series (July 2025)
there are no lock or similar markers on end-to-end encrypted messages, anymore.</p>
<p>Все сообщения в Delta Chat <strong>по умолчанию шифруются сквозным шифрованием</strong>.
С момента выхода серии релизов Delta Chat версии 2 (июль 2025 года)
на сообщениях со сквозным шифрованием больше не отображаются замки или другие подобные индикаторы.</p>
<h3 id="могу-ли-я-получать-или-отправлять-письма-без-сквозного-шифрования">
@@ -773,12 +774,12 @@ there are no lock or similar markers on end-to-end encrypted messages, anymore.<
</h3>
<p>If you use default <a href="https://chatmail.at/relays">chatmail relays</a>,
it is impossible to receive or send messages without end-to-end encryption.</p>
<p>Если вы используете стандартные <a href="https://chatmail.at/relays">ретрансляторы chatmail</a>,
невозможно получать или отправлять сообщения без сквозного шифрования.</p>
<p>If you instead create a profile using a classic e-mail server,
you can send and receive messages without end-to-end encryption.
Such messages lacking end-to-end encryption are marked with an e-mail icon
you can send and receive messages with or without end-to-end encryption.
Messages lacking end-to-end encryption are marked with an e-mail icon
<img style="vertical-align:middle; width:1.2em; margin:1px" src="../email-icon.png" alt="email" />.</p>
<h3 id="howtoe2ee">
@@ -789,9 +790,9 @@ Such messages lacking end-to-end encryption are marked with an e-mail icon
</h3>
<p>You can send an invite link through another private chat,
show an invitation QR code when next to each other or in a video call,
or click on a “contact” that was shared in a chat.</p>
<p>Вы можете отправить ссылку-приглашение через другой личный чат,
показать QR-код приглашения, когда вы рядом или во время видеозвонка,
или нажать на “контакт”, которым поделились в чате.</p>
<ul>
<li>
@@ -800,35 +801,34 @@ or click on a “contact” that was shared in a chat.</p>
и выберите “QR-код приглашения”.</p>
</li>
<li>
<p>For <strong>direct 1:1 chat invitations</strong>,
tap the QR Code icon <img style="vertical-align:middle; width:1.8em; margin:1px" src="../qr-icon.png" />
on the Delta Chat app main screen.</p>
<p>Для <strong>приглашений в прямой чат 1:1</strong>,
коснитесь значка QR-кода <img style="vertical-align:middle; width:1.8em; margin:1px" src="../qr-icon.png" />
на главном экране приложения Delta Chat.</p>
</li>
</ul>
<p>Ask your chat partner to scan the QR image
with their Delta Chat app,
or click “Copy” or “Share” to create an invite link
and share it with your chat partner.</p>
<p>Попросите вашего собеседника отсканировать QR-код
с помощью приложения Delta Chat,
или нажмите “Копировать” или “Поделиться”, чтобы создать ссылку-приглашение
и отправьте её вашему собеседнику.</p>
<p>Now wait while <a href="https://securejoin.delta.chat/en/latest/new.html#setup-contact-protocol">end-to-end encryption is getting established</a>.</p>
<p>Теперь дождитесь, <a href="https://securejoin.delta.chat/en/latest/new.html#setup-contact-protocol">пока устанавливается сквозное шифрование</a>.</p>
<ul>
<li>
<p>If both sides are online, they will soon see a (group or direct) chat
and can start messaging securely.</p>
<p>Если оба участника онлайн, они вскоре увидят (групповой или прямой) чат
и смогут начать защищённую переписку.</p>
</li>
<li>
<p>If one side is offline or in bad network,
the ability to chat is delayed until connectivity is restored.</p>
<p>Если одна из сторон не в сети или имеет плохое соединение,
возможность переписки будет отложена до восстановления связи.</p>
</li>
</ul>
<p>Congratulations!
You now will automatically use end-to-end encryption
with this contact.
If you add each other to chat groups,
end-to-end encryption will be established among all members.</p>
<p>Поздравляем!
Теперь вы автоматически будете использовать сквозное шифрование с данным контактом.
Если вы добавите друг друга в групповые чаты,
сквозное шифрование будет настроено для всех участников.</p>
<h3 id="e2eeguarantee">
@@ -838,16 +838,16 @@ end-to-end encryption will be established among all members.</p>
</h3>
<p>A contact profile might show a green checkmark
<img style="vertical-align:middle; width:1.5em; margin:1px" src="../green-checkmark.png" alt="green checkmark" />
and an “Introduced by” line.
Every green-checkmarked contact either did a direct <a href="#howtoe2ee">QR-scan</a> with you
or was introduced by a another green-checkmarked contact.
Introductions happen automatically when adding members to groups.
Whoever adds a green-checkmarked contact to a group with only green-checkmarked members
becomes an introducer.
In a contact profile you can tap on the “Introduced by …” text repeatedly
until you get to the one with whom you directly did a <a href="#howtoe2ee">QR-scan</a>.</p>
<p>В профиле контакта может отображаться зелёная галочка
<img style="vertical-align:middle; width:1.5em; margin:1px" src="../green-checkmark.png" alt="зелёная галочка" />
и строка “Подтверждён пользователем”.
Каждый контакт с зелёной галочкой либо выполнил непосредственное сканирование <a href="#howtoe2ee">QR-кода</a> с вами,
либо был подтверждён другим контактом с зелёной галочкой.
Подтверждения происходят автоматически при добавлении участников в группы.
Тот, кто добавляет контакт с зелёной галочкой в группу, где только участники с зелёными галочками,
становится подтверждающим.
В профиле контакта вы можете последовательно нажимать на текст “Подтверждён …” до тех пор,
пока не дойдёте до того, с кем вы напрямую выполнили сканирование <a href="#howtoe2ee">QR-кода</a>.</p>
<p>Для более подробного обсуждения “гарантированного сквозного шифрования”
пожалуйста, обратитесь к <a href="https://securejoin.delta.chat/en/latest/new.html">протоколам Secure-Join</a>
@@ -877,9 +877,9 @@ until you get to the one with whom you directly did a <a href="#howtoe2ee">QR-sc
</h3>
<p>Yes, Delta Chat uses a secure subset of OpenPGP
requiring the whole message to be properly encrypted and signed.
For example, “Detached signatures” are not treated as secure.</p>
<p>Да, Delta Chat использует безопасное подмножество OpenPGP
требующее, чтобы всё сообщение было правильно зашифровано и подписано.
Например, “Отделённые подписи” не считаются безопасными.</p>
<p>OpenPGP сам по себе не является небезопасным.
Большинство обсуждаемых в публичной сфере проблем безопасности OpenPGP
@@ -899,7 +899,7 @@ Delta Chat вместо этого использует реализацию Ope
<h3 id="openpgp-alternatives">
Did you consider using alternatives to OpenPGP for end-to-end-encryption? <a href="#openpgp-alternatives" class="anchor"></a>
Рассматривали ли вы альтернативы OpenPGP для сквозного шифрования? <a href="#openpgp-alternatives" class="anchor"></a>
</h3>
@@ -947,10 +947,10 @@ Delta Chat вместо этого использует реализацию Ope
</h3>
<p>If you are sending or receiving e-mail messages without end-to-end encryption (using a classic e-mail server),
they are still protected from cell or cable companies who can not read or modify your e-mail messages.
But both your and your recipients e-mail providers
may read, analyze or modify your messages, including any attachments.</p>
<p>Если вы отправляете или получаете электронные сообщения без сквозного шифрования (используя классический почтовый сервер),
они всё равно защищены от операторов сотовой связи или интернет-провайдеров, которые не могут прочитать или изменить ваши электронные сообщения.
Однако и ваш почтовый провайдер, и почтовый провайдер вашего получателя
могут читать, анализировать или изменять ваши сообщения, включая любые вложения.</p>
<p>Delta Chat по умолчанию использует строгое
<a href="https://en.wikipedia.org/wiki/Transport_Layer_Security">TLS-шифрование</a>,
@@ -971,25 +971,25 @@ may read, analyze or modify your messages, including any attachments.</p>
</h3>
<p>Unlike most other messengers,
Delta Chat apps do not store any metadata about contacts or groups on servers, also not in encrypted form.
Instead, all group metadata is end-to-end encrypted and stored on end-user devices, only.</p>
<p>В отличие от большинства других мессенджеров,
приложения Delta Chat не сохраняют никакие метаданные о контактах или группах на серверах, даже в зашифрованной форме.
Вместо этого все групповые метаданные шифруются сквозным шифрованием и хранятся исключительно на устройствах конечных пользователей.</p>
<p>E-mail Servers can therefore only see</p>
<p>Поэтому, почтовые серверы имеют доступ только к</p>
<ul>
<li>
<p>the message date,</p>
<p>дате сообщения,</p>
</li>
<li>
<p>sender and receiver addresses</p>
<p>адресам отправителя и получателя</p>
</li>
<li>
<p>and message size.</p>
<p>и размеру сообщения.</p>
</li>
</ul>
<p>All other message, contact and group metadata resides in the end-to-end encrypted part of messages.</p>
<p>Все прочие метаданные сообщений, контактов и групп содержатся в части сообщений, защищённой сквозным шифрованием.</p>
<h3 id="device-seizure">
@@ -999,82 +999,82 @@ Instead, all group metadata is end-to-end encrypted and stored on end-user devic
</h3>
<p>Both for protecting against metadata-collecting e-mail servers
as well as against the threat of device seizure
we recommend to use a <a href="https://chatmail.at/relays">chatmail relay</a>
to create chat profiles using random e-mail addresses for transport.
Note that Delta Chat apps on all platforms support multiple profiles
so you can easily use situation-specific profiles next to your “main” profile
with the knowledge that all their data, along with all metadata, will be deleted.
Moreover, if a device is seized then chat contacts using short-lived profiles
can not be identified easily.</p>
<p>Для защиты от серверов электронной почты, собирающих метаданные,
а также от угрозы конфискации устройства,
мы рекомендуем использовать <a href="https://chatmail.at/relays">релей chatmail</a>
для создания чат-профилей с использованием случайных электронных адресов для передачи сообщений.
Обратите внимание, что приложения Delta Chat на всех платформах поддерживают несколько профилей,
так что вы можете легко использовать отдельные профили, для конкретной ситуации, помимо вашего “основного” профиля,
зная, что все их данные, вместе с метаданными, будут удалены.
Кроме того, если устройство изъято, контакты, использующие временные профили,
не могут быть легко идентифицированы.</p>
<h3 id="sealedsender">
Does Delta Chat support “Sealed Sender”? <a href="#sealedsender" class="anchor"></a>
Поддерживает ли Delta Chat функцию “Sealed Sender” (Засекреченный отправитель)? <a href="#sealedsender" class="anchor"></a>
</h3>
<p>Нет, пока нет.</p>
<p>The Signal messenger introduced <a href="https://signal.org/blog/sealed-sender/">“Sealed Sender” in 2018</a>
to keep their server infrastructure ignorant of who is sending a message to a set of recipients.
It is particularly important because the Signal server knows the mobile number of each account,
which is usually associated with a passport identity.</p>
<p>Мессенджер Signal внедрил функцию <a href="https://signal.org/blog/sealed-sender/">“Sealed Sender” (Засекреченный отправитель) в 2018 году</a>,
чтобы их серверная инфраструктура не имела информации о том, кто отправляет сообщение группе получателей.
Это особенно важно, поскольку сервер Signal знает мобильный номер каждого аккаунта,
который обычно привязан к паспортным данным.</p>
<p>Even if <a href="https://chatmail.at/relays">chatmail relays</a>
do not ask for any private data (including no phone numbers),
it might still be worthwhile to protect relational metadata between addresses.
We dont foresee bigger problems in using random throw-away e-mail addresses for sealed sending
but an implementation has not been agreed as a priority yet.</p>
<p>Даже если <a href="https://chatmail.at/relays">релеи chatmail</a>
не запрашивают никаких личных данных (включая телефонные номера),
всё равно может быть полезно защитить реляционные метаданные между адресами
Мы не видим серьёзных проблем в использовании случайных одноразовых электронных адресов для функции sealed sender,
но реализация пока не определена как приоритетная задача.</p>
<h3 id="pfs">
Поддерживает ли Delta Chat совершенную прямую секретность (Perfect forward secrecy, PFS)? <a href="#pfs" class="anchor"></a>
Поддерживает ли Delta Chat свойство Perfect forward secrecy, PFS (Совершенную прямую секретность)? <a href="#pfs" class="anchor"></a>
</h3>
<p>Нет, пока нет.</p>
<p>Delta Chat today doesnt support Perfect Forward Secrecy (PFS).
This means that if your private decryption key is leaked,
and someone has collected your prior in-transit messages,
they will be able to decrypt and read them using the leaked decryption key.
Note that Forward Secrecy only increases security if you delete messages.
Otherwise, someone obtaining your decryption keys
is typically also able to get all your non-deleted messages
and doesnt even need to decrypt any previously collected messages.</p>
<p>На данный момент, Delta Chat не поддерживает Perfect Forward Secrecy (PFS) (Совершенную прямую секретность).
Это означает, что если ваш приватный ключ дешифрования будет скомпрометирован,
и кто-то собрал ваши предыдущие сообщения во время передачи,
они смогут расшифровать и прочитать их, используя скомпрометированный ключ дешифрования.
Обратите внимание, что Forward Secrecy (Прямая секретность) повышает безопасность только если вы удаляете сообщения.
В противном случае, тот, кто получает ваши ключи дешифрования
также может получить все ваши не удалённые сообщения
и ему даже не нужно расшифровывать какие-либо ранее собранные сообщения.</p>
<p>We designed a Forward Secrecy approach that withstood
initial examination from some cryptographers and implementation experts
but is pending a more formal write up
to ascertain it reliably works in federated messaging and with multi-device usage,
before it could be implemented in <a href="https://github.com/chatmail/core">chatmail core</a>,
which would make it available in all <a href="https://chatmail.at/clients">chatmail clients</a>.</p>
<p>Мы разработали подход к Forward Secrecy (Прямой секретности), который прошёл
первичную проверку некоторыми криптографами и экспертами по реализации
но требует более формального описания
чтобы убедиться, что он надёжно работает в федеративном обмене сообщениями и при использовании нескольких устройств,
прежде чем он может быть внедрён в <a href="https://github.com/chatmail/core">ядро chatmail</a>,
что сделает его доступным во всех <a href="https://chatmail.at/clients">клиентах clients</a>.</p>
<h3 id="pqc">
Does Delta Chat support Post-Quantum-Cryptography? <a href="#pqc" class="anchor"></a>
Поддерживает ли Delta Chat Post-Quantum-Cryptography (Постквантовую криптографию)? <a href="#pqc" class="anchor"></a>
</h3>
<p>Нет, пока нет.</p>
<p>Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
We aim to add PQC support in <a href="https://github.com/chatmail/core">chatmail core</a> after the draft is finalized at the IETF
in collaboration with other OpenPGP implementers.</p>
<p>Delta Chat использует библиотеку OpenPGP на Rust <a href="https://github.com/rpgp/rpgp">rPGP</a>,
которая поддерживает последний <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">черновик IETF Post-Quantum-Cryptography OpenPGP</a>.
Мы планируем добавить поддержку PQC в <a href="https://github.com/chatmail/core">ядро chatmail</a> после того, как черновик будет окончательно утвержден в IETF
в сотрудничестве с другими разработчиками OpenPGP.</p>
<h3 id="how-can-i-manually-check-encryption-information">
<h3 id="как-можно-вручную-проверить-информацию-о-шифровании">
How can I manually check encryption information? <a href="#how-can-i-manually-check-encryption-information" class="anchor"></a>
Как можно вручную проверить информацию о шифровании? <a href="#как-можно-вручную-проверить-информацию-о-шифровании" class="anchor"></a>
</h3>
@@ -1511,10 +1511,10 @@ Delta Chat</a>.</li>
</h3>
<p>Note:
Changing email addresses is temporarily disabled
because of ongoing changes to the DeltaChat core.
It should be available again in a few months.</p>
<p>Примечание:
Смена электронных адресов временно отключена
из-за продолжающихся изменений в ядре DeltaChat.
Функция должна снова заработать через несколько месяцев.</p>
<ol>
<li>
@@ -1617,6 +1617,29 @@ It should be available again in a few months.</p>
см. <a href="https://providers.delta.chat">Обзор провайдеров</a></li>
</ul>
<h3 id="can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">
Can I use Delta Chat in parallel with other E-Mail apps? <a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps" class="anchor"></a>
</h3>
<p>Yes, but it is not recommended.</p>
<p>Parallel usage with the same E-Mail address might lead to the following inconveniences:</p>
<ul>
<li>Next to your Delta Chat notifications,
you might also get notifications for (encrypted, so unreadable) chat mail messages
in your other email app</li>
<li>If Delta Chat is not running
or “Advanced &gt; Move automatically to the DeltaChat Folder” is disabled,
encrypted Delta Chat messages might clutter the Inbox in your other E-Mail apps.</li>
</ul>
<p><a href="https://support.delta.chat/t/sieve-rule-to-move-deltachat-mails-to-deltachat-folder/288/10">Sieve rules</a> can solve these problems.</p>
<h3 id="я-хочу-управлять-своим-собственным-сервером-для-delta-chat-что-вы-посоветуете">
+27 -3
View File
@@ -87,6 +87,7 @@
<ul>
<li><a href="#aké-povolenia-potrebuje-delta-chat">Aké povolenia potrebuje Delta Chat?</a></li>
<li><a href="#funguje-delta-chat-s-mojím-poskytovateľom-e-mailov">Funguje Delta Chat s mojím poskytovateľom e-mailov?</a></li>
<li><a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">Can I use Delta Chat in parallel with other E-Mail apps?</a></li>
<li><a href="#i-want-to-manage-my-own-server-for-delta-chat-what-do-you-recommend">I want to manage my own server for Delta Chat. What do you recommend?</a></li>
<li><a href="#prečo-musím-zadávať-svoje-e-mailové-heslo-do-delta-chat-je-to-bezpečné">Prečo musím zadávať svoje e-mailové heslo do Delta Chat? Je to bezpečné?</a></li>
<li><a href="#ktoré-správy-sa-zobrazujú-v-delta-chate">Ktoré správy sa zobrazujú v Delta Chate?</a></li>
@@ -408,7 +409,7 @@ who could have already replied, forwarded, saved, screenshotted or otherwise cop
in the settings of a chat,
at the top right of the chat window,
by selecting a time span
between 1 minute and 5 weeks.</p>
between 5 minutes and 1 year.</p>
<p>Until the setting is turned off again,
each chat members Delta Chat app takes care
@@ -781,8 +782,8 @@ there are no lock or similar markers on end-to-end encrypted messages, anymore.<
it is impossible to receive or send messages without end-to-end encryption.</p>
<p>If you instead create a profile using a classic e-mail server,
you can send and receive messages without end-to-end encryption.
Such messages lacking end-to-end encryption are marked with an e-mail icon
you can send and receive messages with or without end-to-end encryption.
Messages lacking end-to-end encryption are marked with an e-mail icon
<img style="vertical-align:middle; width:1.2em; margin:1px" src="../email-icon.png" alt="email" />.</p>
<h3 id="howtoe2ee">
@@ -1623,6 +1624,29 @@ Niektorí poskytovatelia však potrebujú na správne fungovanie špeciálne mo
pozrite si <a href="https://providers.delta.chat">Prehľad poskytovateľa</a></li>
</ul>
<h3 id="can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">
Can I use Delta Chat in parallel with other E-Mail apps? <a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps" class="anchor"></a>
</h3>
<p>Yes, but it is not recommended.</p>
<p>Parallel usage with the same E-Mail address might lead to the following inconveniences:</p>
<ul>
<li>Next to your Delta Chat notifications,
you might also get notifications for (encrypted, so unreadable) chat mail messages
in your other email app</li>
<li>If Delta Chat is not running
or “Advanced &gt; Move automatically to the DeltaChat Folder” is disabled,
encrypted Delta Chat messages might clutter the Inbox in your other E-Mail apps.</li>
</ul>
<p><a href="https://support.delta.chat/t/sieve-rule-to-move-deltachat-mails-to-deltachat-folder/288/10">Sieve rules</a> can solve these problems.</p>
<h3 id="i-want-to-manage-my-own-server-for-delta-chat-what-do-you-recommend">
+27 -3
View File
@@ -87,6 +87,7 @@
<ul>
<li><a href="#çleje-lyp-delta-chat-i">Ç’leje lyp Delta Chat-i?</a></li>
<li><a href="#a-funksionon-delta-chat-me-shërbimin-tim-email">A funksionon Delta Chat me shërbimin <em>tim</em> email?</a></li>
<li><a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">Can I use Delta Chat in parallel with other E-Mail apps?</a></li>
<li><a href="#i-want-to-manage-my-own-server-for-delta-chat-what-do-you-recommend">I want to manage my own server for Delta Chat. What do you recommend?</a></li>
<li><a href="#pse-më-duhet-të-jap-fjalëkalimin-e-email-it-tim-në-delta-chat-a-është-e-sigurt-kjo">Pse më duhet të jap fjalëkalimin e email-it tim në Delta Chat? A është e sigurt kjo?</a></li>
<li><a href="#cilat-mesazhe-shfaqen-në-delta-chat">Cilat mesazhe shfaqen në Delta Chat?</a></li>
@@ -408,7 +409,7 @@ who could have already replied, forwarded, saved, screenshotted or otherwise cop
in the settings of a chat,
at the top right of the chat window,
by selecting a time span
between 1 minute and 5 weeks.</p>
between 5 minutes and 1 year.</p>
<p>Until the setting is turned off again,
each chat members Delta Chat app takes care
@@ -782,8 +783,8 @@ there are no lock or similar markers on end-to-end encrypted messages, anymore.<
it is impossible to receive or send messages without end-to-end encryption.</p>
<p>If you instead create a profile using a classic e-mail server,
you can send and receive messages without end-to-end encryption.
Such messages lacking end-to-end encryption are marked with an e-mail icon
you can send and receive messages with or without end-to-end encryption.
Messages lacking end-to-end encryption are marked with an e-mail icon
<img style="vertical-align:middle; width:1.2em; margin:1px" src="../email-icon.png" alt="email" />.</p>
<h3 id="howtoe2ee">
@@ -1623,6 +1624,29 @@ Sidoqoftë, disa furnizues shërbimesh kanë nevojë për mundësi speciale, që
të funksionojnë si duhet, shihni <a href="https://providers.delta.chat">Provider Overview</a></li>
</ul>
<h3 id="can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">
Can I use Delta Chat in parallel with other E-Mail apps? <a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps" class="anchor"></a>
</h3>
<p>Yes, but it is not recommended.</p>
<p>Parallel usage with the same E-Mail address might lead to the following inconveniences:</p>
<ul>
<li>Next to your Delta Chat notifications,
you might also get notifications for (encrypted, so unreadable) chat mail messages
in your other email app</li>
<li>If Delta Chat is not running
or “Advanced &gt; Move automatically to the DeltaChat Folder” is disabled,
encrypted Delta Chat messages might clutter the Inbox in your other E-Mail apps.</li>
</ul>
<p><a href="https://support.delta.chat/t/sieve-rule-to-move-deltachat-mails-to-deltachat-folder/288/10">Sieve rules</a> can solve these problems.</p>
<h3 id="i-want-to-manage-my-own-server-for-delta-chat-what-do-you-recommend">
+102 -146
View File
@@ -40,20 +40,20 @@
<ul>
<li><a href="#які-стандарти-використовуються-для-наскрізного-шифрування">Які стандарти використовуються для наскрізного шифрування?</a></li>
<li><a href="#whene2e">Як дізнатися, чи повідомлення зашифровано наскрізним шифруванням?</a></li>
<li><a href="#can-i-still-receive-or-send-mails-without-end-to-end-encryption">Can i still receive or send mails without end-to-end encryption?</a></li>
<li><a href="#howtoe2ee">How can I establish a chat with a new contact?</a></li>
<li><a href="#e2eeguarantee">What does the green checkmark in a contact profile mean?</a></li>
<li><a href="#чи-можу-я-отримувати-та-надсилати-пошту-без-наскрізного-шифрування">Чи можу я отримувати та надсилати пошту без наскрізного шифрування?</a></li>
<li><a href="#howtoe2ee">Як створити чат з новим контактом?</a></li>
<li><a href="#e2eeguarantee">Що означає зелена галочка в профілі контакту?</a></li>
<li><a href="#чи-зашифровані-наскрізно-вкладення-зображення-файли-аудіо-тощо">Чи зашифровані наскрізно вкладення (зображення, файли, аудіо тощо)?</a></li>
<li><a href="#openpgp-secure">Чи безпечний OpenPGP?</a></li>
<li><a href="#openpgp-alternatives">Did you consider using alternatives to OpenPGP for end-to-end-encryption?</a></li>
<li><a href="#openpgp-alternatives">Чи розглядали ви можливість використання альтернатив OpenPGP для наскрізного шифрування?</a></li>
<li><a href="#чи-вразливий-delta-chat-до-efail">Чи вразливий Delta Chat до EFAIL?</a></li>
<li><a href="#tls">Are messages marked with the mail icon exposed on the Internet?</a></li>
<li><a href="#чи-повідомлення-позначені-значком-пошти-доступні-в-інтернетіtls">Чи повідомлення, позначені значком пошти, доступні в Інтернеті?{#tls}</a></li>
<li><a href="#message-metadata">Як Delta Chat захищає метадані у повідомленнях?</a></li>
<li><a href="#device-seizure">Як захистити метадані та контакти якщо пристрій вилучено?</a></li>
<li><a href="#sealedsender">Does Delta Chat support “Sealed Sender”?</a></li>
<li><a href="#sealedsender">Чи підтримує Delta Chat функцію “Запечатаний відправник”?</a></li>
<li><a href="#pfs">Чи підтримує Delta Chat цілковиту пряму секретність (Perfect Forward Secrecy)?</a></li>
<li><a href="#pqc">Does Delta Chat support Post-Quantum-Cryptography?</a></li>
<li><a href="#how-can-i-manually-check-encryption-information">How can I manually check encryption information?</a></li>
<li><a href="#pqc">Чи підтримує Delta Chat пост-квантову криптографію?</a></li>
<li><a href="#як-я-можу-вручну-перевірити-інформацію-про-шифрування">Як я можу вручну перевірити інформацію про шифрування?</a></li>
<li><a href="#importkey">Чи можна повторно використовувати існуючий закритий ключ?</a></li>
<li><a href="#security-audits">Чи проходив Delta Chat незалежний аудит на наявність вразливостей у безпеці?</a></li>
</ul>
@@ -87,7 +87,8 @@
<ul>
<li><a href="#яких-дозволів-потребує-delta-chat">Яких дозволів потребує Delta Chat?</a></li>
<li><a href="#чи-підтримує-delta-chat-роботу-з-моїм-провайдером-електронної-пошти">Чи підтримує Delta Chat роботу з <em>моїм</em> провайдером електронної пошти?</a></li>
<li><a href="#i-want-to-manage-my-own-server-for-delta-chat-what-do-you-recommend">I want to manage my own server for Delta Chat. What do you recommend?</a></li>
<li><a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">Can I use Delta Chat in parallel with other E-Mail apps?</a></li>
<li><a href="#я-хочу-керувати-власним-сервером-для-delta-chat-що-ви-порекомендуєте">Я хочу керувати власним сервером для Delta Chat. Що ви порекомендуєте?</a></li>
<li><a href="#чому-я-маю-вводити-пароль-до-моєї-електронної-пошти-у-delta-chat-чи-це-безпечно">Чому я маю вводити пароль до моєї електронної пошти у Delta Chat? Чи це безпечно?</a></li>
<li><a href="#які-повідомлення-відображаються-у-delta-chat">Які повідомлення відображаються у Delta Chat?</a></li>
<li><a href="#чи-підтримує-delta-chat-html-листи">Чи підтримує Delta Chat HTML-листи?</a></li>
@@ -358,7 +359,11 @@
</h3>
<p>Увімкнути “повідомлення, що зникають” можна в налаштуваннях чату, у верхньому правому куті вікна чату, вибравши проміжок часу від 1 хвилини до 5 тижнів.</p>
<p>You can turn on “disappearing messages”
in the settings of a chat,
at the top right of the chat window,
by selecting a time span
between 5 minutes and 1 year.</p>
<p>Доки налаштування не буде знову вимкнено, додаток Delta Chat кожного учасника чату піклується про видалення повідомлень через вибраний проміжок часу. Проміжок часу починається коли одержувач вперше побачив повідомлення в Delta Chat. Повідомлення видаляються як з кожної поштової скриньки на сервері, так і в самому додатку.</p>
@@ -606,26 +611,21 @@ Push-сповіщення автоматично активуються для
</h3>
<p>Delta Chat uses a <a href="#openpgp-secure">secure subset of the OpenPGP standard</a>
to provide automatic end-to-end encryption using these protocols:</p>
<p>Delta Chat використовує <a href="#openpgp-secure">безпечну підмножину стандарту OpenPGP</a> для забезпечення автоматичного наскрізного шифрування за допомогою цих протоколів:</p>
<ul>
<li>
<p><a href="https://securejoin.delta.chat/en/latest/new.html">Secure-Join</a>
to exchange encryption setup information through QR-code scanning or “invite links”.</p>
<p>Використовуйте <a href="https://securejoin.delta.chat/en/latest/new.html">Secure-Join</a> щоб обмінюватися інформацією про налаштування шифрування, через сканування QR-коду або “посилання-запрошення”.</p>
</li>
<li>
<p><a href="https://autocrypt.org">Autocrypt</a> is used for automatically
establishing end-to-end encryption between contacts and all members of a group chat.</p>
<p><a href="https://autocrypt.org">Autocrypt</a> використовується для автоматичного встановлення наскрізного шифрування між контактами і всіма учасниками групового чату.</p>
</li>
<li>
<p><a href="https://github.com/chatmail/core/blob/main/spec.md#attaching-a-contact-to-a-message">Sharing a contact to a
chat</a>
enables receivers to use end-to-end encryption with the contact.</p>
<p><a href="https://github.com/chatmail/core/blob/main/spec.md#attaching-a-contact-to-a-message">Поширення контакту в чаті</a> дозволяє отримувачам використовувати наскрізне шифрування з контактом.</p>
</li>
</ul>
<p>Delta Chat does not query, publish or interact with any OpenPGP key servers.</p>
<p>Delta Chat не запитує, не публікує і не взаємодіє з будь-якими серверами ключів OpenPGP.</p>
<h3 id="whene2e">
@@ -635,91 +635,67 @@ enables receivers to use end-to-end encryption with the contact.</p>
</h3>
<p>All messages in Delta Chat are <strong>end-to-end encrypted by default</strong>.
Since the Delta Chat Version 2 release series (July 2025)
there are no lock or similar markers on end-to-end encrypted messages, anymore.</p>
<p>Всі повідомлення в Delta Chat за замовчуванням <strong>наскрізно зашифровані</strong>. Починаючи з версії 2 Delta Chat (липень 2025 року) на наскрізних зашифрованих повідомленнях більше немає замків або інших подібних маркерів.</p>
<h3 id="can-i-still-receive-or-send-mails-without-end-to-end-encryption">
<h3 id="чи-можу-я-отримувати-та-надсилати-пошту-без-наскрізного-шифрування">
Can i still receive or send mails without end-to-end encryption? <a href="#can-i-still-receive-or-send-mails-without-end-to-end-encryption" class="anchor"></a>
Чи можу я отримувати та надсилати пошту без наскрізного шифрування? <a href="#чи-можу-я-отримувати-та-надсилати-пошту-без-наскрізного-шифрування" class="anchor"></a>
</h3>
<p>If you use default <a href="https://chatmail.at/relays">chatmail relays</a>,
it is impossible to receive or send messages without end-to-end encryption.</p>
<p>Якщо ви використовуєте стандартні <a href="https://chatmail.at/relays">ретранслятори чату</a>, неможливо отримувати або надсилати повідомлення без наскрізного шифрування.</p>
<p>If you instead create a profile using a classic e-mail server,
you can send and receive messages without end-to-end encryption.
Such messages lacking end-to-end encryption are marked with an e-mail icon
you can send and receive messages with or without end-to-end encryption.
Messages lacking end-to-end encryption are marked with an e-mail icon
<img style="vertical-align:middle; width:1.2em; margin:1px" src="../email-icon.png" alt="email" />.</p>
<h3 id="howtoe2ee">
How can I establish a chat with a new contact? <a href="#howtoe2ee" class="anchor"></a>
Як створити чат з новим контактом? <a href="#howtoe2ee" class="anchor"></a>
</h3>
<p>You can send an invite link through another private chat,
show an invitation QR code when next to each other or in a video call,
or click on a “contact” that was shared in a chat.</p>
<p>Ви можете надіслати посилання-запрошення через інший приватний чат, показати QR-код запрошення, коли ви знаходитесь поруч один з одним або під час відеодзвінка, або натиснути на “контакт”, яким ви поділилися в чаті.</p>
<ul>
<li>
<p>Для <strong>Запрошення до групи</strong>, торкніться назви групи чату, щоб побачити список її учасників, і виберіть “QR-код запрошення”.</p>
</li>
<li>
<p>For <strong>direct 1:1 chat invitations</strong>,
tap the QR Code icon <img style="vertical-align:middle; width:1.8em; margin:1px" src="../qr-icon.png" />
on the Delta Chat app main screen.</p>
<p>Для <strong>прямих запрошень у чат один-на-один</strong>, торкніться іконки QR-коду <img style="vertical-align:middle; width:1.8em; margin:1px" src="../qr-icon.png" /> на головному екрані програми Delta Chat.</p>
</li>
</ul>
<p>Ask your chat partner to scan the QR image
with their Delta Chat app,
or click “Copy” or “Share” to create an invite link
and share it with your chat partner.</p>
<p>Попросіть вашого партнера по чату відсканувати QR-зображення у своєму додатку Delta Chat, або натисніть “Копіювати” чи “Поділитися”, щоб створити посилання-запрошення і поділитися ним з вашим партнером по чату.</p>
<p>Now wait while <a href="https://securejoin.delta.chat/en/latest/new.html#setup-contact-protocol">end-to-end encryption is getting established</a>.</p>
<p>Тепер зачекайте, поки встановиться <a href="https://securejoin.delta.chat/en/latest/new.html#setup-contact-protocol">наскрізне шифрування</a>.</p>
<ul>
<li>
<p>If both sides are online, they will soon see a (group or direct) chat
and can start messaging securely.</p>
<p>Якщо обидві сторони онлайн, вони незабаром побачать (груповий або прямий) чат і можуть почати безпечно обмінюватися повідомленнями.</p>
</li>
<li>
<p>If one side is offline or in bad network,
the ability to chat is delayed until connectivity is restored.</p>
<p>Якщо одна зі сторін перебуває в офлайні або в поганій мережі, можливість спілкуватися в чаті затримується до відновлення з’єднання.</p>
</li>
</ul>
<p>Congratulations!
You now will automatically use end-to-end encryption
with this contact.
If you add each other to chat groups,
end-to-end encryption will be established among all members.</p>
<p>Вітаємо!
Тепер ви автоматично використовуватимете наскрізне шифрування з цим контактом. Якщо ви додасте один одного в групи чату, наскрізне шифрування буде встановлено між усіма учасниками.</p>
<h3 id="e2eeguarantee">
What does the green checkmark in a contact profile mean? <a href="#e2eeguarantee" class="anchor"></a>
Що означає зелена галочка в профілі контакту? <a href="#e2eeguarantee" class="anchor"></a>
</h3>
<p>A contact profile might show a green checkmark
<img style="vertical-align:middle; width:1.5em; margin:1px" src="../green-checkmark.png" alt="green checkmark" />
and an “Introduced by” line.
Every green-checkmarked contact either did a direct <a href="#howtoe2ee">QR-scan</a> with you
or was introduced by a another green-checkmarked contact.
Introductions happen automatically when adding members to groups.
Whoever adds a green-checkmarked contact to a group with only green-checkmarked members
becomes an introducer.
In a contact profile you can tap on the “Introduced by …” text repeatedly
until you get to the one with whom you directly did a <a href="#howtoe2ee">QR-scan</a>.</p>
<p>У профілі контакту може відображатися зелена галочка <img style="vertical-align:middle; width:1.5em; margin:1px" src="../green-checkmark.png" alt="green checkmark" /> і рядок “Представлений”. Кожен контакт із зеленою галочкою або зробив пряме <a href="#howtoe2ee">QR-сканування</a> з вами або був представлений іншим контактом, позначеним зеленою галочкою. Знайомство відбувається автоматично під час додавання учасників до груп. Той, хто додає контакт із зеленою галочкою до групи, в якій є лише учасники із зеленою галочкою стає представником. У профілі контакту ви можете кілька разів натиснути на текст “Представлений …” поки не потрапите до того, з ким ви безпосередньо зробили <a href="#howtoe2ee">QR-сканування</a>.</p>
<p>Для більш детального обговорення “гарантованого наскрізного шифрування” будь ласка, перегляньте <a href="https://securejoin.delta.chat/en/latest/new.html">Протоколи безпечного приєднання</a> і, зокрема, прочитайте про “Перевірені групи”, технічний термін того, що тут називається чатами з “зеленою галочкою” або “гарантованим наскрізним шифруванням”.</p>
@@ -743,9 +719,7 @@ until you get to the one with whom you directly did a <a href="#howtoe2ee">QR-sc
</h3>
<p>Yes, Delta Chat uses a secure subset of OpenPGP
requiring the whole message to be properly encrypted and signed.
For example, “Detached signatures” are not treated as secure.</p>
<p>Так, Delta Chat використовує безпечну підмножину OpenPGP яка вимагає, щоб все повідомлення було належним чином зашифровано і підписано. Наприклад, “відокремлені підписи” не вважаються безпечними.</p>
<p>OpenPGP сам по собі не є небезпечним. Більшість публічно обговорюваних проблем безпеки OpenPGP насправді виникають через недостатню зручність використання або погану реалізацію інструментів чи програм (або обох).
Особливо важливо розрізняти OpenPGP, стандарт шифрування IETF, і GnuPG (GPG), інструмент командного рядка, що реалізує OpenPGP.
@@ -757,7 +731,7 @@ Delta Chat скоріше використовує реалізацію OpenPGP
<h3 id="openpgp-alternatives">
Did you consider using alternatives to OpenPGP for end-to-end-encryption? <a href="#openpgp-alternatives" class="anchor"></a>
Чи розглядали ви можливість використання альтернатив OpenPGP для наскрізного шифрування? <a href="#openpgp-alternatives" class="anchor"></a>
</h3>
@@ -778,18 +752,15 @@ Delta Chat скоріше використовує реалізацію OpenPGP
<p>Delta Chat також ніколи не був вразливим до EFAIL-атаки “Пряма ексфільтрація” тому що він розшифровує лише “багатокомпонентні/зашифровані” повідомлення, які містять рівно одну зашифровану і підписану частину, як визначено специфікацією Autocrypt Level 1.</p>
<h3 id="tls">
<h3 id="чи-повідомлення-позначені-значком-пошти-доступні-в-інтернетіtls">
Are messages marked with the mail icon exposed on the Internet? <a href="#tls" class="anchor"></a>
Чи повідомлення, позначені значком пошти, доступні в Інтернеті?{#tls} <a href="#чи-повідомлення-позначені-значком-пошти-доступні-в-інтернетіtls" class="anchor"></a>
</h3>
<p>If you are sending or receiving e-mail messages without end-to-end encryption (using a classic e-mail server),
they are still protected from cell or cable companies who can not read or modify your e-mail messages.
But both your and your recipients e-mail providers
may read, analyze or modify your messages, including any attachments.</p>
<p>Якщо ви надсилаєте або отримуєте електронні листи без наскрізного шифрування (використовуючи класичний сервер електронної пошти), вони все одно захищені від мобільних або кабельних компаній, які не можуть читати чи змінювати ваші повідомлення. Однак як ваш, так і поштовий провайдер одержувача можуть читати, аналізувати або змінювати ваші листи, включаючи будь-які вкладення.</p>
<p>За замовчуванням Delta Chat використовує суворе <a href="https://en.wikipedia.org/wiki/Transport_Layer_Security">TLS-шифрування</a> яке захищає з’єднання між вашим пристроєм і провайдером електронної пошти. Вся робота з TLS-шифруванням Delta Chat пройшла незалежний <a href="#security-audits">аудит безпеки</a>. Крім того, з’єднання між вашим провайдером та провайдером електронної пошти одержувача зазвичай також шифрується при передачі даних. Якщо задіяні поштові сервери підтримують <a href="https://datatracker.ietf.org/doc/html/rfc8461">MTA-STS</a> то між провайдерами електронної пошти буде застосовуватися транспортне шифрування в цьому випадку повідомлення Delta Chat ніколи не будуть доступні в Інтернеті у вигляді відкритого тексту навіть якщо повідомлення не було наскрізь зашифровано.</p>
@@ -801,25 +772,23 @@ may read, analyze or modify your messages, including any attachments.</p>
</h3>
<p>Unlike most other messengers,
Delta Chat apps do not store any metadata about contacts or groups on servers, also not in encrypted form.
Instead, all group metadata is end-to-end encrypted and stored on end-user devices, only.</p>
<p>На відміну від більшості інших месенджерів, додатки Delta Chat не зберігають жодних метаданих про контакти чи групи на серверах, навіть у зашифрованому вигляді. Натомість усі метадані груп наскрізно зашифровані та зберігаються виключно на пристроях користувачів.</p>
<p>E-mail Servers can therefore only see</p>
<p>Тому поштові сервери можуть бачити лише</p>
<ul>
<li>
<p>the message date,</p>
<p>дату повідомлення,</p>
</li>
<li>
<p>sender and receiver addresses</p>
<p>адреси відправника та одержувача</p>
</li>
<li>
<p>and message size.</p>
<p>і розмір повідомлення.</p>
</li>
</ul>
<p>All other message, contact and group metadata resides in the end-to-end encrypted part of messages.</p>
<p>Усі інші метадані повідомлень, контактів і груп містяться в наскрізно зашифрованій частині повідомлень.</p>
<h3 id="device-seizure">
@@ -829,36 +798,21 @@ Instead, all group metadata is end-to-end encrypted and stored on end-user devic
</h3>
<p>Both for protecting against metadata-collecting e-mail servers
as well as against the threat of device seizure
we recommend to use a <a href="https://chatmail.at/relays">chatmail relay</a>
to create chat profiles using random e-mail addresses for transport.
Note that Delta Chat apps on all platforms support multiple profiles
so you can easily use situation-specific profiles next to your “main” profile
with the knowledge that all their data, along with all metadata, will be deleted.
Moreover, if a device is seized then chat contacts using short-lived profiles
can not be identified easily.</p>
<p>Для захисту як від серверів електронної пошти, що збирають метадані, так і від загрози вилучення пристрою, ми рекомендуємо використовувати <a href="https://chatmail.at/relays">чатмейл-релей</a> для створення чат-профілів із випадковими адресами електронної пошти для передавання повідомлень. Зверніть увагу, що додатки Delta Chat на всіх платформах підтримують кілька профілів, тому ви можете легко користуватися профілями, створеними для конкретних ситуацій, поруч із вашим «основним» профілем, з упевненістю, що всі їхні дані, включно з усіма метаданими, буде видалено. Більше того, у разі вилучення пристрою ідентифікувати чат-контакти, які використовують короткочасні профілі, буде вкрай складно.</p>
<h3 id="sealedsender">
Does Delta Chat support “Sealed Sender”? <a href="#sealedsender" class="anchor"></a>
Чи підтримує Delta Chat функцію “Запечатаний відправник”? <a href="#sealedsender" class="anchor"></a>
</h3>
<p>No, not yet.</p>
<p>Ні, поки ще ні.</p>
<p>The Signal messenger introduced <a href="https://signal.org/blog/sealed-sender/">Sealed Sender” in 2018</a>
to keep their server infrastructure ignorant of who is sending a message to a set of recipients.
It is particularly important because the Signal server knows the mobile number of each account,
which is usually associated with a passport identity.</p>
<p>Месенджер Signal запровадив <a href="https://signal.org/blog/sealed-sender/">Запечатаного відправника” у 2018 році</a> щоб їхня серверна інфраструктура не знала, хто надсилає повідомлення певній групі одержувачів. Це особливо важливо, оскільки сервер Signal знає номер мобільного телефону кожного акаунта, який зазвичай асоціюється з паспортними даними.</p>
<p>Even if <a href="https://chatmail.at/relays">chatmail relays</a>
do not ask for any private data (including no phone numbers),
it might still be worthwhile to protect relational metadata between addresses.
We dont foresee bigger problems in using random throw-away e-mail addresses for sealed sending
but an implementation has not been agreed as a priority yet.</p>
<p>Навіть якщо <a href="https://chatmail.at/relays">чат-мейл релей</a> не запитує ніяких приватних даних (в тому числі номерів телефонів), все одно може мати сенс захистити реляційні метадані між адресами. Ми не передбачаємо великих проблем у використанні випадкових одноразових адрес електронної пошти для запечатаних відправлень але реалізація такої можливості ще не є пріоритетною.</p>
<h3 id="pfs">
@@ -868,43 +822,28 @@ but an implementation has not been agreed as a priority yet.</p>
</h3>
<p>No, not yet.</p>
<p>Ні, поки ще ні.</p>
<p>Delta Chat today doesnt support Perfect Forward Secrecy (PFS).
This means that if your private decryption key is leaked,
and someone has collected your prior in-transit messages,
they will be able to decrypt and read them using the leaked decryption key.
Note that Forward Secrecy only increases security if you delete messages.
Otherwise, someone obtaining your decryption keys
is typically also able to get all your non-deleted messages
and doesnt even need to decrypt any previously collected messages.</p>
<p>Delta Chat наразі не підтримує ідеальну пряму секретність (Perfect Forward Secrecy, PFS). Це означає, що якщо ваш приватний ключ для розшифрування буде скомпрометовано, а хтось заздалегідь зібрав ваші повідомлення під час передачі, він зможе розшифрувати та прочитати їх, використовуючи зламаний ключ. Зверніть увагу, що пряма секретність підвищує рівень безпеки лише в тому разі, якщо ви видаляєте повідомлення. Інакше, якщо хтось отримує доступ до ваших ключів розшифрування, він зазвичай також має доступ до всіх ваших невидалених повідомлень і навіть не потребує розшифровувати заздалегідь перехоплені дані.</p>
<p>We designed a Forward Secrecy approach that withstood
initial examination from some cryptographers and implementation experts
but is pending a more formal write up
to ascertain it reliably works in federated messaging and with multi-device usage,
before it could be implemented in <a href="https://github.com/chatmail/core">chatmail core</a>,
which would make it available in all <a href="https://chatmail.at/clients">chatmail clients</a>.</p>
<p>Ми розробили підхід Forward Secrecy, який витримав початкову експертизу від деяких криптографів та експертів з реалізації але чекає на більш офіційний звіт щоб переконатися, що він надійно працює в об’єднаних системах обміну повідомленнями та при використанні декількох пристроїв, перш ніж його можна буде реалізувати в <a href="https://github.com/chatmail/core">ядрі чату</a>, що зробить його доступним у всіх <a href="https://chatmail.at/clients">клієнтах чату</a>.</p>
<h3 id="pqc">
Does Delta Chat support Post-Quantum-Cryptography? <a href="#pqc" class="anchor"></a>
Чи підтримує Delta Chat пост-квантову криптографію? <a href="#pqc" class="anchor"></a>
</h3>
<p>No, not yet.</p>
<p>Ні, поки ще ні.</p>
<p>Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
We aim to add PQC support in <a href="https://github.com/chatmail/core">chatmail core</a> after the draft is finalized at the IETF
in collaboration with other OpenPGP implementers.</p>
<p>Delta Chat використовує бібліотеку Rust OpenPGP <a href="https://github.com/rpgp/rpgp">rPGP</a> яка підтримує останню версію <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>. Ми плануємо додати підтримку PQC у <a href="https://github.com/chatmail/core">chatmail core</a> після того, як проект буде завершено у IETF у співпраці з іншими розробниками OpenPGP.</p>
<h3 id="how-can-i-manually-check-encryption-information">
<h3 id="як-я-можу-вручну-перевірити-інформацію-про-шифрування">
How can I manually check encryption information? <a href="#how-can-i-manually-check-encryption-information" class="anchor"></a>
Як я можу вручну перевірити інформацію про шифрування? <a href="#як-я-можу-вручну-перевірити-інформацію-про-шифрування" class="anchor"></a>
</h3>
@@ -1109,16 +1048,13 @@ in collaboration with other OpenPGP implementers.</p>
</h3>
<ul>
<li>webxdc apps can not send data to the Internet, or download anything.</li>
<li>A webxdc app can only exchange data within a Delta Chat chat, with its
copies on the devices of your chat partners. Other than that, its completely
isolated from the Internet.</li>
<li>The privacy a webxdc app offers is the privacy of your chat - as long as you
trust the people you chat with, you can trust the webxdc app as well.</li>
<li>This also means: it can be a privacy risk to open apps in chats with untrusted members.
Just like with e-mail attachments, video calls or plain links:
open them only from senders you trust, and not from spammers.
Spammers can get to know any data you send to them, as well as your IP address.</li>
<li>Додатки webxdc не можуть надсилати дані в Інтернет або завантажувати щось.</li>
<li>Програма webxdc може обмінюватися даними лише в межах чату Delta Chat з її копіями на пристроях ваших партнерів по чату. В іншому, вона повністю ізольована від Інтернету.</li>
<li>Конфіденційність, яку пропонує додаток webxdc, є конфіденційністю вашого чату - доки ви довіряєте людям, з якими ви спілкуєтеся, ви можете довіряти і додатку webxdc.</li>
<li>Це також означає, що відкриття додатків у чатах з користувачами, яким ви не довіряєте, може становити ризик для конфіденційності.
Так само, як і з вкладеннями електронної пошти, відеодзвінками або звичайними посиланнями:
відкривайте їх лише від відправників, яким ви довіряєте, а не від спамерів.
Спамери можуть дізнатися будь-які дані, які ви їм надсилаєте, а також вашу IP-адресу.</li>
</ul>
<h3 id="де-я-можу-отримати-webxdc-додатки">
@@ -1186,10 +1122,9 @@ Spammers can get to know any data you send to them, as well as your IP address.<
</h3>
<p>With a Broadcast List you can send a message to many recipients at once;
the recipients cannot reply in that list.
Broadcast lists are still highly experimental
and will very probably be replaced by something else, stay tuned :)</p>
<p>За допомогою списку розсилки ви можете надіслати повідомлення одразу багатьом одержувачам;
одержувачі не можуть відповідати у цьому списку.
Списки розсилки все ще дуже експериментальні і, ймовірно, будуть замінені чимось іншим, слідкуйте за новинами :)</p>
<h3 id="як-я-можу-поділитися-своїм-місцезнаходженням-зі-своїми-співрозмовниками-в-чаті">
@@ -1235,10 +1170,10 @@ and will very probably be replaced by something else, stay tuned :)</p>
</h3>
<p>Note:
Changing email addresses is temporarily disabled
because of ongoing changes to the DeltaChat core.
It should be available again in a few months.</p>
<p>Примітка:
Зміна адреси електронної пошти тимчасово відключена
через постійні зміни в ядрі DeltaChat.
Ця функція буде знову доступна через кілька місяців.</p>
<ol>
<li>
@@ -1329,19 +1264,40 @@ It should be available again in a few months.</p>
Проте для коректної роботи деяких провайдерів потрібні специфічні налаштування. Дивіться наш <a href="https://providers.delta.chat">огляд провайдерів</a></li>
</ul>
<h3 id="i-want-to-manage-my-own-server-for-delta-chat-what-do-you-recommend">
<h3 id="can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">
I want to manage my own server for Delta Chat. What do you recommend? <a href="#i-want-to-manage-my-own-server-for-delta-chat-what-do-you-recommend" class="anchor"></a>
Can I use Delta Chat in parallel with other E-Mail apps? <a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps" class="anchor"></a>
</h3>
<p>Yes, but it is not recommended.</p>
<p>Parallel usage with the same E-Mail address might lead to the following inconveniences:</p>
<ul>
<li>Next to your Delta Chat notifications,
you might also get notifications for (encrypted, so unreadable) chat mail messages
in your other email app</li>
<li>If Delta Chat is not running
or “Advanced &gt; Move automatically to the DeltaChat Folder” is disabled,
encrypted Delta Chat messages might clutter the Inbox in your other E-Mail apps.</li>
</ul>
<p><a href="https://support.delta.chat/t/sieve-rule-to-move-deltachat-mails-to-deltachat-folder/288/10">Sieve rules</a> can solve these problems.</p>
<h3 id="я-хочу-керувати-власним-сервером-для-delta-chat-що-ви-порекомендуєте">
Я хочу керувати власним сервером для Delta Chat. Що ви порекомендуєте? <a href="#я-хочу-керувати-власним-сервером-для-delta-chat-що-ви-порекомендуєте" class="anchor"></a>
</h3>
<ul>
<li>Most mail servers will work well. But what we personally recommend is a
chatmail relay server, as described <a href="https://delta.chat/en/2023-12-13-chatmail">in this
blogpost</a>.</li>
<li>You can find an <a href="https://github.com/chatmail/relay">installation guide on GitHub</a>.</li>
<li>Більшість поштових серверів будуть працювати добре. Але ми особисто рекомендуємо використовувати сервер ретрансляції чатової пошти, як описано <a href="https://delta.chat/en/2023-12-13-chatmail">в цій статті</a>.</li>
<li>Ви можете знайти <a href="https://github.com/chatmail/relay">посібник зі встановлення на GitHub</a>.</li>
</ul>
<h3 id="чому-я-маю-вводити-пароль-до-моєї-електронної-пошти-у-delta-chat-чи-це-безпечно">
+31 -3
View File
@@ -87,6 +87,7 @@
<ul>
<li><a href="#delta-chat-需要哪些权限">Delta Chat 需要哪些权限?</a></li>
<li><a href="#delta-chat-可用于-我的-电子邮件提供商吗">Delta Chat 可用于 <em>我的</em> 电子邮件提供商吗?</a></li>
<li><a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">Can I use Delta Chat in parallel with other E-Mail apps?</a></li>
<li><a href="#i-want-to-manage-my-own-server-for-delta-chat-what-do-you-recommend">I want to manage my own server for Delta Chat. What do you recommend?</a></li>
<li><a href="#为什么我必须在-delta-chat-中输入我的电子邮件密码-这样安全吗">为什么我必须在 Delta Chat 中输入我的电子邮件密码? 这样安全吗?</a></li>
<li><a href="#哪些消息会在-delta-chat-中出现">哪些消息会在 Delta Chat 中出现?</a></li>
@@ -394,7 +395,11 @@
</h3>
<p>您可以在聊天窗口右上角的聊天设置中通过选择 1 分钟到 5 周之间的时间跨度打开“消息定时销毁”。</p>
<p>You can turn on “disappearing messages”
in the settings of a chat,
at the top right of the chat window,
by selecting a time span
between 5 minutes and 1 year.</p>
<p>在再次关闭该设置之前,
每个聊天成员的 Delta Chat 应用都会负责
@@ -744,8 +749,8 @@ there are no lock or similar markers on end-to-end encrypted messages, anymore.<
it is impossible to receive or send messages without end-to-end encryption.</p>
<p>If you instead create a profile using a classic e-mail server,
you can send and receive messages without end-to-end encryption.
Such messages lacking end-to-end encryption are marked with an e-mail icon
you can send and receive messages with or without end-to-end encryption.
Messages lacking end-to-end encryption are marked with an e-mail icon
<img style="vertical-align:middle; width:1.2em; margin:1px" src="../email-icon.png" alt="email" />.</p>
<h3 id="howtoe2ee">
@@ -1540,6 +1545,29 @@ It should be available again in a few months.</p>
不过,某些提供商需要一些特殊设置才能正常工作,请参阅<a href="https://providers.delta.chat">提供商概览</a></li>
</ul>
<h3 id="can-i-use-delta-chat-in-parallel-with-other-e-mail-apps">
Can I use Delta Chat in parallel with other E-Mail apps? <a href="#can-i-use-delta-chat-in-parallel-with-other-e-mail-apps" class="anchor"></a>
</h3>
<p>Yes, but it is not recommended.</p>
<p>Parallel usage with the same E-Mail address might lead to the following inconveniences:</p>
<ul>
<li>Next to your Delta Chat notifications,
you might also get notifications for (encrypted, so unreadable) chat mail messages
in your other email app</li>
<li>If Delta Chat is not running
or “Advanced &gt; Move automatically to the DeltaChat Folder” is disabled,
encrypted Delta Chat messages might clutter the Inbox in your other E-Mail apps.</li>
</ul>
<p><a href="https://support.delta.chat/t/sieve-rule-to-move-deltachat-mails-to-deltachat-folder/288/10">Sieve rules</a> can solve these problems.</p>
<h3 id="i-want-to-manage-my-own-server-for-delta-chat-what-do-you-recommend">
@@ -0,0 +1,124 @@
/* Autogenerated file, do not edit manually */
package chat.delta.rpc;
import chat.delta.util.SettableFuture;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
/* Basic RPC Transport implementation */
public abstract class BaseTransport implements Rpc.Transport {
private final Map<Integer, SettableFuture<JsonNode>> requestFutures = new ConcurrentHashMap<>();
private int requestId = 0;
private final ObjectMapper mapper = new ObjectMapper();
private Thread worker;
/* Send a Request as raw JSON String to the RPC server */
protected abstract void sendRequest(String jsonRequest);
/* Get next Response as raw JSON String from the RPC server */
protected abstract String getResponse();
public ObjectMapper getObjectMapper() {
return mapper;
}
public void call(String method, JsonNode... params) throws RpcException {
innerCall(method, params);
}
public <T> T callForResult(TypeReference<T> resultType, String method, JsonNode... params) throws RpcException {
try {
JsonNode node = innerCall(method, params);
if (node.isNull()) return null;
return mapper.readValue(node.traverse(), resultType);
} catch (IOException e) {
throw new RpcException(e.getMessage());
}
}
private JsonNode innerCall(String method, JsonNode... params) throws RpcException {
int id;
synchronized (this) {
id = ++requestId;
ensureWorkerThread();
}
try {
String jsonRequest = mapper.writeValueAsString(new Request(method, params, id));
SettableFuture<JsonNode> future = new SettableFuture<>();
requestFutures.put(id, future);
sendRequest(jsonRequest);
return future.get();
} catch (ExecutionException e) {
throw (RpcException)e.getCause();
} catch (InterruptedException e) {
throw new RpcException(e.getMessage());
} catch (JsonProcessingException e) {
throw new RpcException(e.getMessage());
}
}
private void ensureWorkerThread() {
if (worker != null) return;
worker = new Thread(() -> {
while (true) {
try {
processResponse();
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}, "jsonrpcThread");
worker.start();
}
private void processResponse() throws JsonProcessingException {
String jsonResponse = getResponse();
Response response = mapper.readValue(jsonResponse, Response.class);
if (response.id == 0) { // Got JSON-RPC notification/event, ignore
return;
}
SettableFuture<JsonNode> future = requestFutures.remove(response.id);
if (future == null) { // Got a response with unknown ID, ignore
return;
}
if (response.error != null) {
future.setException(new RpcException(response.error.toString()));
} else if (response.result != null) {
future.set(response.result);
} else {
future.setException(new RpcException("Got JSON-RPC response without result or error: " + jsonResponse));
}
}
private static class Request {
private final String jsonrpc = "2.0";
public final String method;
public final JsonNode[] params;
public final int id;
public Request(String method, JsonNode[] params, int id) {
this.method = method;
this.params = params;
this.id = id;
}
}
private static class Response {
public String jsonrpc;
public int id;
public JsonNode result;
public JsonNode error;
}
}
+249
View File
@@ -0,0 +1,249 @@
/* Autogenerated file, do not edit manually */
package chat.delta.rpc;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import chat.delta.rpc.types.*;
public class Rpc {
public interface Transport {
void call(String method, JsonNode... params) throws RpcException;
<T> T callForResult(TypeReference<T> resultType, String method, JsonNode... params) throws RpcException;
ObjectMapper getObjectMapper();
}
public final Transport transport;
private final ObjectMapper mapper;
public Rpc(Transport transport) {
this.transport = transport;
this.mapper = transport.getObjectMapper();
}
public Integer addAccount() throws RpcException {
return transport.callForResult(new TypeReference<Integer>(){}, "add_account");
}
/**
* Set the order of accounts.
* The provided list should contain all account IDs in the desired order.
* If an account ID is missing from the list, it will be appended at the end.
* If the list contains non-existent account IDs, they will be ignored.
*/
public void setAccountsOrder(java.util.List<Integer> order) throws RpcException {
transport.call("set_accounts_order", mapper.valueToTree(order));
}
/* Get the combined filesize of an account in bytes */
public Integer getAccountFileSize(Integer accountId) throws RpcException {
return transport.callForResult(new TypeReference<Integer>(){}, "get_account_file_size", mapper.valueToTree(accountId));
}
/**
* If there was an error while the account was opened
* and migrated to the current version,
* then this function returns it.
* <p>
* This function is useful because the key-contacts migration could fail due to bugs
* and then the account will not work properly.
* <p>
* After opening an account, the UI should call this function
* and show the error string if one is returned.
*/
public String getMigrationError(Integer accountId) throws RpcException {
return transport.callForResult(new TypeReference<String>(){}, "get_migration_error", mapper.valueToTree(accountId));
}
public Integer draftSelfReport(Integer accountId) throws RpcException {
return transport.callForResult(new TypeReference<Integer>(){}, "draft_self_report", mapper.valueToTree(accountId));
}
/* Returns configuration value for the given key. */
public String getConfig(Integer accountId, String key) throws RpcException {
return transport.callForResult(new TypeReference<String>(){}, "get_config", mapper.valueToTree(accountId), mapper.valueToTree(key));
}
/**
* Configures a new email account using the provided parameters
* and adds it as a transport.
* <p>
* If the email address is the same as an existing transport,
* then this existing account will be reconfigured instead of a new one being added.
* <p>
* This function stops and starts IO as needed.
* <p>
* Usually it will be enough to only set `addr` and `password`,
* and all the other settings will be autoconfigured.
* <p>
* During configuration, ConfigureProgress events are emitted;
* they indicate a successful configuration as well as errors
* and may be used to create a progress bar.
* This function will return after configuration is finished.
* <p>
* If configuration is successful,
* the working server parameters will be saved
* and used for connecting to the server.
* The parameters entered by the user will be saved separately
* so that they can be prefilled when the user opens the server-configuration screen again.
* <p>
* See also:
* - [Self::is_configured()] to check whether there is
* at least one working transport.
* - [Self::add_transport_from_qr()] to add a transport
* from a server encoded in a QR code.
* - [Self::list_transports()] to get a list of all configured transports.
* - [Self::delete_transport()] to remove a transport.
*/
public void addOrUpdateTransport(Integer accountId, EnteredLoginParam param) throws RpcException {
transport.call("add_or_update_transport", mapper.valueToTree(accountId), mapper.valueToTree(param));
}
/**
* Adds a new email account as a transport
* using the server encoded in the QR code.
* See [Self::add_or_update_transport].
*/
public void addTransportFromQr(Integer accountId, String qr) throws RpcException {
transport.call("add_transport_from_qr", mapper.valueToTree(accountId), mapper.valueToTree(qr));
}
/**
* Create a new unencrypted group chat.
* <p>
* Same as [`Self::create_group_chat`], but the chat is unencrypted and can only have
* address-contacts.
*/
public Integer createGroupChatUnencrypted(Integer accountId, String name) throws RpcException {
return transport.callForResult(new TypeReference<Integer>(){}, "create_group_chat_unencrypted", mapper.valueToTree(accountId), mapper.valueToTree(name));
}
/**
* Create a new **broadcast channel**
* (called "Channel" in the UI).
* <p>
* Broadcast channels are similar to groups on the sending device,
* however, recipients get the messages in a read-only chat
* and will not see who the other members are.
* <p>
* Called `broadcast` here rather than `channel`,
* because the word "channel" already appears a lot in the code,
* which would make it hard to grep for it.
* <p>
* After creation, the chat contains no recipients and is in _unpromoted_ state;
* see [`CommandApi::create_group_chat`] for more information on the unpromoted state.
* <p>
* Returns the created chat's id.
*/
public Integer createBroadcast(Integer accountId, String chatName) throws RpcException {
return transport.callForResult(new TypeReference<Integer>(){}, "create_broadcast", mapper.valueToTree(accountId), mapper.valueToTree(chatName));
}
/* Returns contact id of the created or existing DM chat with that contact */
public Integer createChatByContactId(Integer accountId, Integer contactId) throws RpcException {
return transport.callForResult(new TypeReference<Integer>(){}, "create_chat_by_contact_id", mapper.valueToTree(accountId), mapper.valueToTree(contactId));
}
/* Sets display name for existing contact. */
public void changeContactName(Integer accountId, Integer contactId, String name) throws RpcException {
transport.call("change_contact_name", mapper.valueToTree(accountId), mapper.valueToTree(contactId), mapper.valueToTree(name));
}
/* Parses a vCard file located at the given path. Returns contacts in their original order. */
public java.util.List<VcardContact> parseVcard(String path) throws RpcException {
return transport.callForResult(new TypeReference<java.util.List<VcardContact>>(){}, "parse_vcard", mapper.valueToTree(path));
}
/**
* Imports contacts from a vCard file located at the given path.
* <p>
* Returns the ids of created/modified contacts in the order they appear in the vCard.
*/
public java.util.List<Integer> importVcard(Integer accountId, String path) throws RpcException {
return transport.callForResult(new TypeReference<java.util.List<Integer>>(){}, "import_vcard", mapper.valueToTree(accountId), mapper.valueToTree(path));
}
/* Returns a vCard containing contacts with the given ids. */
public String makeVcard(Integer accountId, java.util.List<Integer> contacts) throws RpcException {
return transport.callForResult(new TypeReference<String>(){}, "make_vcard", mapper.valueToTree(accountId), mapper.valueToTree(contacts));
}
public void sendWebxdcRealtimeData(Integer accountId, Integer instanceMsgId, java.util.List<Integer> data) throws RpcException {
transport.call("send_webxdc_realtime_data", mapper.valueToTree(accountId), mapper.valueToTree(instanceMsgId), mapper.valueToTree(data));
}
public void sendWebxdcRealtimeAdvertisement(Integer accountId, Integer instanceMsgId) throws RpcException {
transport.call("send_webxdc_realtime_advertisement", mapper.valueToTree(accountId), mapper.valueToTree(instanceMsgId));
}
/**
* Leaves the gossip of the webxdc with the given message id.
* <p>
* NB: When this is called before closing a webxdc app in UIs, it must be guaranteed that
* `send_webxdc_realtime_*()` functions aren't called for the given `instance_message_id`
* anymore until the app is open again.
*/
public void leaveWebxdcRealtime(Integer accountId, Integer instanceMessageId) throws RpcException {
transport.call("leave_webxdc_realtime", mapper.valueToTree(accountId), mapper.valueToTree(instanceMessageId));
}
/* Starts an outgoing call. */
public Integer placeOutgoingCall(Integer accountId, Integer chatId, String placeCallInfo) throws RpcException {
return transport.callForResult(new TypeReference<Integer>(){}, "place_outgoing_call", mapper.valueToTree(accountId), mapper.valueToTree(chatId), mapper.valueToTree(placeCallInfo));
}
/* Accepts an incoming call. */
public void acceptIncomingCall(Integer accountId, Integer msgId, String acceptCallInfo) throws RpcException {
transport.call("accept_incoming_call", mapper.valueToTree(accountId), mapper.valueToTree(msgId), mapper.valueToTree(acceptCallInfo));
}
/* Ends incoming or outgoing call. */
public void endCall(Integer accountId, Integer msgId) throws RpcException {
transport.call("end_call", mapper.valueToTree(accountId), mapper.valueToTree(msgId));
}
/* Returns information about the call. */
public CallInfo callInfo(Integer accountId, Integer msgId) throws RpcException {
return transport.callForResult(new TypeReference<CallInfo>(){}, "call_info", mapper.valueToTree(accountId), mapper.valueToTree(msgId));
}
/* Returns JSON with ICE servers, to be used for WebRTC video calls. */
public String iceServers(Integer accountId) throws RpcException {
return transport.callForResult(new TypeReference<String>(){}, "ice_servers", mapper.valueToTree(accountId));
}
/**
* Makes an HTTP GET request and returns a response.
* <p>
* `url` is the HTTP or HTTPS URL.
*/
public HttpResponse getHttpResponse(Integer accountId, String url) throws RpcException {
return transport.callForResult(new TypeReference<HttpResponse>(){}, "get_http_response", mapper.valueToTree(accountId), mapper.valueToTree(url));
}
/**
* Send a reaction to message.
* <p>
* Reaction is a string of emojis separated by spaces. Reaction to a
* single message can be sent multiple times. The last reaction
* received overrides all previously received reactions. It is
* possible to remove all reactions by sending an empty string.
*/
public Integer sendReaction(Integer accountId, Integer messageId, java.util.List<String> reaction) throws RpcException {
return transport.callForResult(new TypeReference<Integer>(){}, "send_reaction", mapper.valueToTree(accountId), mapper.valueToTree(messageId), mapper.valueToTree(reaction));
}
/* Returns reactions to the message. */
public Reactions getMessageReactions(Integer accountId, Integer messageId) throws RpcException {
return transport.callForResult(new TypeReference<Reactions>(){}, "get_message_reactions", mapper.valueToTree(accountId), mapper.valueToTree(messageId));
}
/* Checks if messages can be sent to a given chat. */
public Boolean canSend(Integer accountId, Integer chatId) throws RpcException {
return transport.callForResult(new TypeReference<Boolean>(){}, "can_send", mapper.valueToTree(accountId), mapper.valueToTree(chatId));
}
}
@@ -0,0 +1,8 @@
/* Autogenerated file, do not edit manually */
package chat.delta.rpc;
public class RpcException extends Exception {
public RpcException(String message) { super(message); }
}
@@ -0,0 +1,19 @@
/* Autogenerated file, do not edit manually */
package chat.delta.rpc.types;
public class CallInfo {
/* True if SDP offer has a video. */
public Boolean hasVideo;
/**
* SDP offer.
* <p>
* Can be used to manually answer the call even if incoming call event was missed.
*/
public String sdpOffer;
/**
* Call state.
* <p>
* For example, if the call is accepted, active, canceled, declined etc.
*/
public CallState state;
}
@@ -0,0 +1,48 @@
/* Autogenerated file, do not edit manually */
package chat.delta.rpc.types;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
@JsonTypeInfo(use=Id.NAME, include=As.PROPERTY, property="kind")
@JsonSubTypes({@Type(value = CallState.Alerting.class, name="Alerting"), @Type(value = CallState.Active.class, name="Active"), @Type(value = CallState.Completed.class, name="Completed"), @Type(value = CallState.Missed.class, name="Missed"), @Type(value = CallState.Declined.class, name="Declined"), @Type(value = CallState.Canceled.class, name="Canceled")})
public abstract class CallState {
/**
* Fresh incoming or outgoing call that is still ringing.
* <p>
* There is no separate state for outgoing call that has been dialled but not ringing on the other side yet as we don't know whether the other side received our call.
*/
public static class Alerting extends CallState {
}
/* Active call. */
public static class Active extends CallState {
}
/* Completed call that was once active and then was terminated for any reason. */
public static class Completed extends CallState {
/* Call duration in seconds. */
public Integer duration;
}
/* Incoming call that was not picked up within a timeout or was explicitly ended by the caller before we picked up. */
public static class Missed extends CallState {
}
/* Incoming call that was explicitly ended on our side before picking up or outgoing call that was declined before the timeout. */
public static class Declined extends CallState {
}
/**
* Outgoing call that has been canceled on our side before receiving a response.
* <p>
* Incoming calls cannot be canceled, on the receiver side canceled calls usually result in missed calls.
*/
public static class Canceled extends CallState {
}
}
@@ -0,0 +1,13 @@
/* Autogenerated file, do not edit manually */
package chat.delta.rpc.types;
public enum EnteredCertificateChecks {
/* `Automatic` means that provider database setting should be taken. If there is no provider database setting for certificate checks, check certificates strictly. */
automatic,
/* Ensure that TLS certificate is valid for the server hostname. */
strict,
/* Accept certificates that are expired, self-signed or otherwise not valid for the server hostname. */
acceptInvalidCertificates,
}
@@ -0,0 +1,51 @@
/* Autogenerated file, do not edit manually */
package chat.delta.rpc.types;
/**
* Login parameters entered by the user.
* <p>
* Usually it will be enough to only set `addr` and `password`, and all the other settings will be autoconfigured.
*/
public class EnteredLoginParam {
/* Email address. */
public String addr;
/* TLS options: whether to allow invalid certificates and/or invalid hostnames. Default: Automatic */
@com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SET)
public EnteredCertificateChecks certificateChecks;
/* Imap server port. */
@com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SET)
public Integer imapPort;
/* Imap socket security. */
@com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SET)
public Socket imapSecurity;
/* Imap server hostname or IP address. */
@com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SET)
public String imapServer;
/* Imap username. */
@com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SET)
public String imapUser;
/* If true, login via OAUTH2 (not recommended anymore). Default: false */
@com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SET)
public Boolean oauth2;
/* Password. */
public String password;
/**
* SMTP Password.
* <p>
* Only needs to be specified if different than IMAP password.
*/
@com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SET)
public String smtpPassword;
/* SMTP server port. */
@com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SET)
public Integer smtpPort;
/* SMTP socket security. */
@com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SET)
public Socket smtpSecurity;
/* SMTP server hostname or IP address. */
@com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SET)
public String smtpServer;
/* SMTP username. */
@com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SET)
public String smtpUser;
}
@@ -0,0 +1,13 @@
/* Autogenerated file, do not edit manually */
package chat.delta.rpc.types;
public class HttpResponse {
/* base64-encoded response body. */
public String blob;
/* Encoding, e.g. "utf-8". */
@com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SET)
public String encoding;
/* MIME type, e.g. "text/plain" or "text/html". */
@com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SET)
public String mimetype;
}
@@ -0,0 +1,12 @@
/* Autogenerated file, do not edit manually */
package chat.delta.rpc.types;
/* A single reaction emoji. */
public class Reaction {
/* Emoji frequency. */
public Integer count;
/* Emoji. */
public String emoji;
/* True if we reacted with this emoji. */
public Boolean isFromSelf;
}
@@ -0,0 +1,10 @@
/* Autogenerated file, do not edit manually */
package chat.delta.rpc.types;
/* Structure representing all reactions to a particular message. */
public class Reactions {
/* Unique reactions and their count, sorted in descending order. */
public java.util.List<Reaction> reactions;
/* Map from a contact to it's reaction to message. */
public java.util.Map<String, java.util.List<String>> reactionsByContact;
}
@@ -0,0 +1,16 @@
/* Autogenerated file, do not edit manually */
package chat.delta.rpc.types;
public enum Socket {
/* Unspecified socket security, select automatically. */
automatic,
/* TLS connection. */
ssl,
/* STARTTLS connection. */
starttls,
/* No TLS, plaintext connection. */
plain,
}
@@ -0,0 +1,20 @@
/* Autogenerated file, do not edit manually */
package chat.delta.rpc.types;
public class VcardContact {
/* Email address. */
public String addr;
/* Contact color as hex string. */
public String color;
/* The contact's name, or the email address if no name was given. */
public String displayName;
/* Public PGP key in Base64. */
@com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SET)
public String key;
/* Profile image in Base64. */
@com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SET)
public String profileImage;
/* Last update timestamp. */
@com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SET)
public Integer timestamp;
}
@@ -1,4 +1,5 @@
package com.b44t.messenger.util.concurrent;
/* Autogenerated file, do not edit manually */
package chat.delta.util;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@@ -10,4 +11,4 @@ public interface ListenableFuture<T> extends Future<T> {
public void onSuccess(T result);
public void onFailure(ExecutionException e);
}
}
}
@@ -1,4 +1,5 @@
package com.b44t.messenger.util.concurrent;
/* Autogenerated file, do not edit manually */
package chat.delta.util;
import java.util.LinkedList;
import java.util.List;
@@ -133,4 +134,4 @@ public class SettableFuture<T> implements ListenableFuture<T> {
if (exception != null) listener.onFailure(new ExecutionException(exception));
else listener.onSuccess(result);
}
}
}
@@ -50,4 +50,14 @@ public class DcAccounts {
private native long getJsonrpcInstanceCPtr ();
private native long getAccountCPtr (int accountId);
private native long getSelectedAccountCPtr ();
public boolean isAllChatmail() {
for (int accountId : getAll()) {
DcContext dcContext = getAccount(accountId);
if (!dcContext.isChatmail()) {
return false;
}
}
return true;
}
}
@@ -31,6 +31,10 @@ public class DcContext {
public final static int DC_EVENT_WEBXDC_INSTANCE_DELETED = 2121;
public final static int DC_EVENT_WEBXDC_REALTIME_DATA = 2150;
public final static int DC_EVENT_ACCOUNTS_BACKGROUND_FETCH_DONE = 2200;
public final static int DC_EVENT_INCOMING_CALL = 2550;
public final static int DC_EVENT_INCOMING_CALL_ACCEPTED = 2560;
public final static int DC_EVENT_OUTGOING_CALL_ACCEPTED = 2570;
public final static int DC_EVENT_CALL_ENDED = 2580;
public final static int DC_IMEX_EXPORT_SELF_KEYS = 1;
public final static int DC_IMEX_IMPORT_SELF_KEYS = 2;
@@ -201,7 +205,6 @@ public class DcContext {
public native boolean resendMsgs (int msg_ids[]);
public native int sendMsg (int chat_id, DcMsg msg);
public native int sendTextMsg (int chat_id, String text);
public native int sendVideochatInvitation(int chat_id);
public native boolean sendWebxdcStatusUpdate(int msg_id, String payload);
public native String getWebxdcStatusUpdates(int msg_id, int last_known_serial);
public native void setWebxdcIntegration (String file);
+2 -4
View File
@@ -18,7 +18,7 @@ public class DcMsg {
public final static int DC_MSG_VOICE = 41;
public final static int DC_MSG_VIDEO = 50;
public final static int DC_MSG_FILE = 60;
public final static int DC_MSG_VIDEOCHAT_INVITATION = 70;
public final static int DC_MSG_CALL = 71;
public final static int DC_MSG_WEBXDC = 80;
public final static int DC_MSG_VCARD = 90;
@@ -155,8 +155,6 @@ public class DcMsg {
public native boolean isInfo ();
public native boolean hasHtml ();
public native String getSetupCodeBegin ();
public native String getVideochatUrl ();
public native int getVideochatType ();
public native void setText (String text);
public native void setSubject (String text);
public native void setHtml (String text);
@@ -196,7 +194,7 @@ public class DcMsg {
public boolean canSave() {
// saving info-messages out of context results in confusion, see https://github.com/deltachat/deltachat-ios/issues/2567
return !isInfo() && getType() != DC_MSG_VIDEOCHAT_INVITATION;
return !isInfo();
}
public File getFileAsFile() {
@@ -0,0 +1,22 @@
package com.b44t.messenger;
import chat.delta.rpc.BaseTransport;
/* RPC transport over C FFI */
public class FFITransport extends BaseTransport {
private final DcJsonrpcInstance dcJsonrpcInstance;
public FFITransport(DcJsonrpcInstance dcJsonrpcInstance) {
this.dcJsonrpcInstance = dcJsonrpcInstance;
}
@Override
protected void sendRequest(String jsonRequest) {
dcJsonrpcInstance.request(jsonRequest);
}
@Override
protected String getResponse() {
return dcJsonrpcInstance.getNextResponse();
}
}
@@ -1,171 +0,0 @@
package com.b44t.messenger.rpc;
public class EnteredLoginParam {
// Email address.
private final String addr;
// Password.
private final String password;
// ============ IMAP settings ============
// Server hostname or IP address.
private final String imapServer;
// Server port.
private final int imapPort;
// Socket security.
private final SocketSecurity imapSecurity;
// Username.
private final String imapUser;
// ============ SMTP settings ============
// Server hostname or IP address.
private final String smtpServer;
// Server port.
private final int smtpPort;
// Socket security.
private final SocketSecurity smtpSecurity;
// Username.
private final String smtpUser;
// SMTP Password. Only needs to be specified if different than IMAP password.
private final String smtpPassword;
// TLS options: whether to allow invalid certificates and/or
// invalid hostnames
private final EnteredCertificateChecks certificateChecks;
// If true, login via OAUTH2 (not recommended anymore)
private final boolean oauth2;
public EnteredLoginParam(String addr,
String password,
String imapServer,
int imapPort,
SocketSecurity imapSecurity,
String imapUser,
String smtpServer,
int smtpPort,
SocketSecurity smtpSecurity,
String smtpUser,
String smtpPassword,
EnteredCertificateChecks certificateChecks,
boolean oauth2) {
this.addr = addr;
this.password = password;
this.imapServer = imapServer;
this.imapPort = imapPort;
this.imapSecurity = imapSecurity;
this.imapUser = imapUser;
this.smtpServer = smtpServer;
this.smtpPort = smtpPort;
this.smtpSecurity = smtpSecurity;
this.smtpUser = smtpUser;
this.smtpPassword = smtpPassword;
this.certificateChecks = certificateChecks;
this.oauth2 = oauth2;
}
public String getAddr() {
return addr;
}
public String getPassword() {
return password;
}
public String getImapServer() {
return imapServer;
}
public int getImapPort() {
return imapPort;
}
public SocketSecurity getImapSecurity() {
return imapSecurity;
}
public String getImapUser() {
return imapUser;
}
public String getSmtpServer() {
return smtpServer;
}
public int getSmtpPort() {
return smtpPort;
}
public SocketSecurity getSmtpSecurity() {
return smtpSecurity;
}
public String getSmtpUser() {
return smtpUser;
}
public String getSmtpPassword() {
return smtpPassword;
}
public EnteredCertificateChecks getCertificateChecks() {
return certificateChecks;
}
public boolean isOauth2() {
return oauth2;
}
public enum EnteredCertificateChecks {
automatic, strict, acceptInvalidCertificates,
}
public static EnteredCertificateChecks certificateChecksFromInt(int position) {
switch (position) {
case 0:
return EnteredCertificateChecks.automatic;
case 1:
return EnteredCertificateChecks.strict;
case 2:
return EnteredCertificateChecks.acceptInvalidCertificates;
}
throw new IllegalArgumentException("Invalid certificate position: " + position);
}
public enum SocketSecurity {
// Unspecified socket security, select automatically.
automatic,
// TLS connection.
ssl,
// STARTTLS connection.
starttls,
// No TLS, plaintext connection.
plain,
}
public static SocketSecurity socketSecurityFromInt(int position) {
switch (position) {
case 0:
return SocketSecurity.automatic;
case 1:
return SocketSecurity.ssl;
case 2:
return SocketSecurity.starttls;
case 3:
return SocketSecurity.plain;
}
throw new IllegalArgumentException("Invalid socketSecurity position: " + position);
}
}
@@ -1,33 +0,0 @@
package com.b44t.messenger.rpc;
import android.util.Base64;
public class HttpResponse {
// base64-encoded response body.
private final String blob;
// MIME type, e.g. "text/plain" or "text/html".
private final String mimetype;
// Encoding, e.g. "utf-8".
private final String encoding;
public HttpResponse(String blob, String mimetype, String encoding) {
this.blob = blob;
this.mimetype = mimetype;
this.encoding = encoding;
}
public byte[] getBlob() {
if (blob == null) {
return null;
}
return Base64.decode(blob, Base64.NO_WRAP | Base64.NO_PADDING);
}
public String getMimetype() {
return mimetype;
}
public String getEncoding() {
return encoding;
}
}
@@ -1,39 +0,0 @@
package com.b44t.messenger.rpc;
import androidx.annotation.Nullable;
public class Reaction {
// The reaction emoji string.
private final String emoji;
// The count of users that have reacted with this reaction.
private final int count;
// true if self-account reacted with this reaction, false otherwise.
private final boolean isFromSelf;
public Reaction(String emoji, int count, boolean isFromSelf) {
this.emoji = emoji;
this.count = count;
this.isFromSelf = isFromSelf;
}
public String getEmoji() {
return emoji;
}
public int getCount() {
return count;
}
public boolean isFromSelf() {
return isFromSelf;
}
@Override
public boolean equals(@Nullable Object obj) {
if (obj instanceof Reaction) {
Reaction reaction = (Reaction) obj;
return emoji.equals(reaction.getEmoji()) && count == reaction.getCount() && isFromSelf == reaction.isFromSelf();
}
return false;
}
}
@@ -1,26 +0,0 @@
package com.b44t.messenger.rpc;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Reactions {
// Map from a contact to it's reaction to message.
private final HashMap<Integer, String[]> reactionsByContact;
// Unique reactions, sorted in descending order.
private final ArrayList<Reaction> reactions;
public Reactions(HashMap<Integer, String[]> reactionsByContact, ArrayList<Reaction> reactions) {
this.reactionsByContact = reactionsByContact;
this.reactions = reactions;
}
public Map<Integer, String[]> getReactionsByContact() {
return reactionsByContact;
}
public List<Reaction> getReactions() {
return reactions;
}
}
@@ -1,203 +0,0 @@
package com.b44t.messenger.rpc;
import android.util.Log;
import com.b44t.messenger.DcJsonrpcInstance;
import com.b44t.messenger.util.concurrent.SettableFuture;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
public class Rpc {
private final static String TAG = Rpc.class.getSimpleName();
private final Map<Integer, SettableFuture<JsonElement>> requestFutures = new ConcurrentHashMap<>();
private final DcJsonrpcInstance dcJsonrpcInstance;
private int requestId = 0;
private boolean started = false;
private final Gson gson = new GsonBuilder().serializeNulls().create();
public Rpc(DcJsonrpcInstance dcJsonrpcInstance) {
this.dcJsonrpcInstance = dcJsonrpcInstance;
}
private void processResponse() throws JsonSyntaxException {
String jsonResponse = dcJsonrpcInstance.getNextResponse();
Response response = gson.fromJson(jsonResponse, Response.class);
if (response == null) {
Log.e(TAG, "Error parsing JSON: " + jsonResponse);
return;
} else if (response.id == 0) {
// Got JSON-RPC notification/event, ignore
return;
}
SettableFuture<JsonElement> future = requestFutures.remove(response.id);
if (future == null) { // Got a response with unknown ID, ignore
return;
}
if (response.error != null) {
String message;
try {
message = response.error.getAsJsonObject().get("message").getAsString();
} catch (Exception e) {
Log.e(TAG, "Can't get response error message: " + e);
message = response.error.toString();
}
future.setException(new RpcException(message));
} else if (response.result != null) {
future.set(response.result);
} else {
future.setException(new RpcException("Got JSON-RPC response without result or error: " + jsonResponse));
}
}
public void start() {
started = true;
new Thread(() -> {
while (true) {
try {
processResponse();
} catch (Exception e) {
e.printStackTrace();
}
}
}, "jsonrpcThread").start();
}
public SettableFuture<JsonElement> call(String method, Object... params) throws RpcException {
if (!started) throw new RpcException("RPC not started yet.");
int id;
synchronized (this) {
id = ++requestId;
}
String jsonRequest = gson.toJson(new Request(method, params, id));
SettableFuture<JsonElement> future = new SettableFuture<>();
requestFutures.put(id, future);
dcJsonrpcInstance.request(jsonRequest);
return future;
}
public JsonElement getResult(String method, Object... params) throws RpcException {
try {
return call(method, params).get();
} catch (ExecutionException e) {
throw (RpcException)e.getCause();
} catch (InterruptedException e) {
throw new RpcException(e.getMessage());
}
}
public List<VcardContact> parseVcard(String path) throws RpcException {
TypeToken<List<VcardContact>> listType = new TypeToken<List<VcardContact>>(){};
return gson.fromJson(getResult("parse_vcard", path), listType.getType());
}
public String makeVcard(int accountId, int... contacts) throws RpcException {
return gson.fromJson(getResult("make_vcard", accountId, contacts), String.class);
}
public List<Integer> importVcard(int accountId, String path) throws RpcException {
TypeToken<List<Integer>> listType = new TypeToken<List<Integer>>(){};
return gson.fromJson(getResult("import_vcard", accountId, path), listType.getType());
}
public HttpResponse getHttpResponse(int accountId, String url) throws RpcException {
return gson.fromJson(getResult("get_http_response", accountId, url), HttpResponse.class);
}
public Reactions getMsgReactions(int accountId, int msgId) throws RpcException {
return gson.fromJson(getResult("get_message_reactions", accountId, msgId), Reactions.class);
}
public int sendReaction(int accountId, int msgId, String... reaction) throws RpcException {
return getResult("send_reaction", accountId, msgId, reaction).getAsInt();
}
public int draftSelfReport(int accountId) throws RpcException {
return getResult("draft_self_report", accountId).getAsInt();
}
public void sendWebxdcRealtimeData(Integer accountId, Integer instanceMsgId, List<Integer> data) throws RpcException {
getResult("send_webxdc_realtime_data", accountId, instanceMsgId, data);
}
public void sendWebxdcRealtimeAdvertisement(Integer accountId, Integer instanceMsgId) throws RpcException {
getResult("send_webxdc_realtime_advertisement", accountId, instanceMsgId);
}
public void leaveWebxdcRealtime(Integer accountId, Integer instanceMessageId) throws RpcException {
getResult("leave_webxdc_realtime", accountId, instanceMessageId);
}
public int getAccountFileSize(int accountId) throws RpcException {
return getResult("get_account_file_size", accountId).getAsInt();
}
public void changeContactName(int accountId, int contactId, String name) throws RpcException {
getResult("change_contact_name", accountId, contactId, name);
}
public int addAccount() throws RpcException {
return getResult("add_account").getAsInt();
}
public void addTransportFromQr(int accountId, String qrCode) throws RpcException {
getResult("add_transport_from_qr", accountId, qrCode);
}
public void addOrUpdateTransport(int accountId, EnteredLoginParam param) throws RpcException {
getResult("add_or_update_transport", accountId, param);
}
public int createBroadcast(int accountId, String chatName) throws RpcException {
return gson.fromJson(getResult("create_broadcast", accountId, chatName), Integer.class);
}
public int createGroupChatUnencrypted(int accountId, String chatName) throws RpcException {
return gson.fromJson(getResult("create_group_chat_unencrypted", accountId, chatName), Integer.class);
}
public void setAccountsOrder(List<Integer> order) throws RpcException {
getResult("set_accounts_order", order);
}
private static class Request {
private final String jsonrpc = "2.0";
public final String method;
public final Object[] params;
public final int id;
public Request(String method, Object[] params, int id) {
this.method = method;
this.params = params;
this.id = id;
}
}
public String getMigrationError(int accountId) throws RpcException {
return gson.fromJson(getResult("get_migration_error", accountId), String.class);
}
private static class Response {
public final int id;
public final JsonElement result;
public final JsonElement error;
public Response(int id, JsonElement result, JsonElement error) {
this.id = id;
this.result = result;
this.error = error;
}
}
}
@@ -1,11 +0,0 @@
package com.b44t.messenger.rpc;
/**
* An exception occurred while processing a request in ArcaneChat core.
**/
public class RpcException extends Exception {
public RpcException(String message) {
super(message);
}
}
@@ -1,60 +0,0 @@
package com.b44t.messenger.rpc;
import android.util.Base64;
public class VcardContact {
// Email address.
private final String addr;
// The contact's name, or the email address if no name was given.
private final String displayName;
// Public PGP key in Base64.
private final String key;
// Profile image in Base64.
private final String profileImage;
// Contact color in HTML color format.
private final String color;
// Last update timestamp.
private final int timestamp;
public VcardContact(String addr, String displayName, String key, String profileImage, String color, int timestamp) {
this.addr = addr;
this.displayName = displayName;
this.key = key;
this.profileImage = profileImage;
this.color = color;
this.timestamp = timestamp;
}
public String getAddr() {
return addr;
}
public String getDisplayName() {
return displayName;
}
public byte[] getKey() {
return key == null? null : Base64.decode(key, Base64.NO_WRAP | Base64.NO_PADDING);
}
public boolean hasProfileImage() {
return profileImage != null;
}
public byte[] getProfileImage() {
return profileImage == null? null : Base64.decode(profileImage, Base64.NO_WRAP | Base64.NO_PADDING);
}
public String getColor() {
return color;
}
public int getTimestamp() {
return timestamp;
}
}
@@ -11,7 +11,6 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.TextView;
import androidx.annotation.NonNull;
@@ -221,16 +220,11 @@ public class AllMediaDocumentsFragment
private class ActionModeCallback implements ActionMode.Callback {
private int originalStatusBarColor;
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.profile_context, menu);
mode.setTitle("1");
Window window = getActivity().getWindow();
originalStatusBarColor = window.getStatusBarColor();
window.setStatusBarColor(getResources().getColor(R.color.action_mode_status_bar));
setCorrectMenuVisibility(menu);
return true;
}
@@ -279,8 +273,6 @@ public class AllMediaDocumentsFragment
public void onDestroyActionMode(ActionMode mode) {
actionMode = null;
getListAdapter().clearSelection();
getActivity().getWindow().setStatusBarColor(originalStatusBarColor);
}
}
}
@@ -11,7 +11,6 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.TextView;
import androidx.annotation.NonNull;
@@ -212,16 +211,11 @@ public class AllMediaGalleryFragment
private class ActionModeCallback implements ActionMode.Callback {
private int originalStatusBarColor;
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.profile_context, menu);
mode.setTitle("1");
Window window = getActivity().getWindow();
originalStatusBarColor = window.getStatusBarColor();
window.setStatusBarColor(getResources().getColor(R.color.action_mode_status_bar));
setCorrectMenuVisibility(menu);
return true;
}
@@ -266,8 +260,6 @@ public class AllMediaGalleryFragment
public void onDestroyActionMode(ActionMode mode) {
actionMode = null;
getListAdapter().clearSelection();
getActivity().getWindow().setStatusBarColor(originalStatusBarColor);
}
}
}
@@ -1,7 +1,5 @@
package org.thoughtcrime.securesms;
import static org.thoughtcrime.securesms.connect.DcHelper.CONFIG_VERIFIED_ONE_ON_ONE_CHATS;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -25,8 +23,7 @@ import com.b44t.messenger.DcAccounts;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcEvent;
import com.b44t.messenger.DcEventEmitter;
import com.b44t.messenger.rpc.Rpc;
import com.b44t.messenger.rpc.RpcException;
import com.b44t.messenger.FFITransport;
import org.thoughtcrime.securesms.connect.AccountManager;
import org.thoughtcrime.securesms.connect.DcEventCenter;
@@ -53,6 +50,9 @@ import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.concurrent.TimeUnit;
import chat.delta.rpc.Rpc;
import chat.delta.rpc.RpcException;
public class ApplicationContext extends MultiDexApplication {
private static final String TAG = ApplicationContext.class.getSimpleName();
@@ -109,8 +109,7 @@ public class ApplicationContext extends MultiDexApplication {
System.loadLibrary("native-utils");
dcAccounts = new DcAccounts(new File(getFilesDir(), "accounts").getAbsolutePath());
rpc = new Rpc(dcAccounts.getJsonrpcInstance());
rpc.start();
rpc = new Rpc(new FFITransport(dcAccounts.getJsonrpcInstance()));
AccountManager.getInstance().migrateToDcAccounts(this);
int[] allAccounts = dcAccounts.getAll();
for (int accountId : allAccounts) {
@@ -149,21 +148,6 @@ public class ApplicationContext extends MultiDexApplication {
Log.i("DeltaChat", "shutting down event handler");
}, "eventThread").start();
// migrating global notifications pref. to per-account config, added 10/July/24
final String NOTIFICATION_PREF = "pref_key_enable_notifications";
boolean isMuted = !Prefs.getBooleanPreference(this, NOTIFICATION_PREF, true);
if (isMuted) {
for (int accId : dcAccounts.getAll()) {
dcAccounts.getAccount(accId).setMuted(true);
}
Prefs.removePreference(this, NOTIFICATION_PREF);
}
// /migrating global notifications
for (int accountId : allAccounts) {
dcAccounts.getAccount(accountId).setConfig(CONFIG_VERIFIED_ONE_ON_ONE_CHATS, "1");
}
// set translations before starting I/O to avoid sending untranslated MDNs (issue #2288)
DcHelper.setStockTranslations(this);
@@ -75,11 +75,14 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarA
@Override
protected void onCreate(Bundle icicle, boolean ready) {
setContentView(R.layout.activity_application_preferences);
//noinspection ConstantConditions
this.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setElevation(0); // TODO: use custom toolbar instead
if (icicle == null) {
initFragment(android.R.id.content, new ApplicationPreferenceFragment());
initFragment(R.id.fragment, new ApplicationPreferenceFragment());
}
}
@@ -91,7 +94,7 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarA
showBackupProvider();
return;
}
Fragment fragment = getSupportFragmentManager().findFragmentById(android.R.id.content);
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment);
fragment.onActivityResult(requestCode, resultCode, data);
}
@@ -271,7 +274,7 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarA
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(android.R.id.content, fragment);
fragmentTransaction.replace(R.id.fragment, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
@@ -7,10 +7,12 @@ import android.view.MenuItem;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import androidx.activity.EdgeToEdge;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.view.WindowCompat;
import androidx.fragment.app.Fragment;
import org.thoughtcrime.securesms.util.DynamicTheme;
@@ -31,7 +33,9 @@ public abstract class BaseActionBarActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
onPreCreate();
EdgeToEdge.enable(this); // docs says to use: WindowCompat.enableEdgeToEdge(getWindow()); but it is not available
super.onCreate(savedInstanceState);
WindowCompat.getInsetsController(getWindow(), getWindow().getDecorView()).setAppearanceLightStatusBars(false); // force white text in status bar
}
@Override
@@ -14,7 +14,6 @@ import androidx.appcompat.app.AlertDialog;
import com.b44t.messenger.DcChat;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcMsg;
import com.b44t.messenger.rpc.Rpc;
import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.recipients.Recipient;
@@ -24,6 +23,8 @@ import org.thoughtcrime.securesms.util.ViewUtil;
import java.util.HashSet;
import java.util.Set;
import chat.delta.rpc.Rpc;
public abstract class BaseConversationItem extends LinearLayout
implements BindableConversationItem
{
@@ -10,9 +10,7 @@ import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;
import android.os.AsyncTask;
import android.view.Menu;
@@ -401,8 +399,6 @@ public abstract class BaseConversationListFragment extends Fragment implements A
mode.setTitle("1");
requireActivity().getWindow().setStatusBarColor(getResources().getColor(R.color.action_mode_status_bar));
return true;
}
@@ -445,10 +441,6 @@ public abstract class BaseConversationListFragment extends Fragment implements A
actionMode = null;
getListAdapter().initializeBatchMode(false);
TypedArray color = requireActivity().getTheme().obtainStyledAttributes(new int[]{android.R.attr.statusBarColor});
requireActivity().getWindow().setStatusBarColor(color.getColor(0, Color.BLACK));
color.recycle();
Context context = getContext();
if (context != null) {
fab.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_add_white_24dp));
@@ -30,9 +30,11 @@ public class BlockedContactsActivity extends PassphraseRequiredActionBarActivity
@Override
public void onCreate(Bundle bundle, boolean ready) {
setContentView(R.layout.activity_blocked_contacts);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle(R.string.pref_blocked_contacts);
initFragment(android.R.id.content, new BlockedAndShareContactsFragment(), getIntent().getExtras());
getSupportActionBar().setElevation(0); // TODO: use custom toolbar instead
initFragment(R.id.fragment, new BlockedAndShareContactsFragment(), getIntent().getExtras());
}
@Override
@@ -23,8 +23,6 @@ import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
@@ -35,7 +33,6 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
@@ -136,7 +133,6 @@ public class ContactSelectionListFragment extends Fragment
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.contact_list, menu);
getActivity().getWindow().setStatusBarColor(getResources().getColor(R.color.action_mode_status_bar));
setCorrectMenuVisibility(menu);
actionMode.setTitle("1");
return true;
@@ -167,10 +163,6 @@ public class ContactSelectionListFragment extends Fragment
public void onDestroyActionMode(ActionMode actionMode) {
ContactSelectionListFragment.this.actionMode = null;
getContactSelectionListAdapter().resetActionModeSelection();
TypedArray color = getActivity().getTheme().obtainStyledAttributes(new int[]{android.R.attr.statusBarColor});
getActivity().getWindow().setStatusBarColor(color.getColor(0, Color.BLACK));
color.recycle();
}
};
@@ -74,10 +74,6 @@ import com.b44t.messenger.DcContact;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcEvent;
import com.b44t.messenger.DcMsg;
import com.b44t.messenger.rpc.Rpc;
import com.b44t.messenger.rpc.RpcException;
import com.b44t.messenger.util.concurrent.ListenableFuture;
import com.b44t.messenger.util.concurrent.SettableFuture;
import org.thoughtcrime.securesms.attachments.Attachment;
import org.thoughtcrime.securesms.attachments.UriAttachment;
@@ -122,13 +118,19 @@ import org.thoughtcrime.securesms.util.concurrent.AssertedSuccessListener;
import org.thoughtcrime.securesms.util.guava.Optional;
import org.thoughtcrime.securesms.util.views.ProgressDialog;
import org.thoughtcrime.securesms.video.recode.VideoRecoder;
import org.thoughtcrime.securesms.videochat.VideochatUtil;
import org.thoughtcrime.securesms.calls.CallUtil;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
import chat.delta.rpc.Rpc;
import chat.delta.rpc.RpcException;
import chat.delta.util.ListenableFuture;
import chat.delta.util.SettableFuture;
/**
* Activity for displaying a message thread, as well as
* composing/sending a new message into that thread.
@@ -448,6 +450,14 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
menu.findItem(R.id.menu_show_map).setVisible(false);
}
menu.findItem(R.id.menu_start_call).setVisible(
Prefs.isCallsEnabled(this)
&& dcChat.canSend()
&& dcChat.isEncrypted()
&& !dcChat.isSelfTalk()
&& !dcChat.isMultiUser()
);
if (!dcChat.isEncrypted() || !dcChat.canSend() || dcChat.isMailingList() ) {
menu.findItem(R.id.menu_ephemeral_messages).setVisible(false);
}
@@ -538,6 +548,9 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
} else if (itemId == R.id.menu_show_map) {
WebxdcActivity.openMaps(this, chatId);
return true;
} else if (itemId == R.id.menu_start_call) {
CallUtil.startCall(this, chatId);
return true;
} else if (itemId == R.id.menu_all_media) {
handleAllMedia();
return true;
@@ -927,6 +940,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
supportActionBar.setCustomView(R.layout.conversation_title_view);
supportActionBar.setDisplayShowCustomEnabled(true);
supportActionBar.setDisplayShowTitleEnabled(false);
supportActionBar.setElevation(0); // TODO: use custom toolbar instead
Toolbar parent = (Toolbar) supportActionBar.getCustomView().getParent();
parent.setPadding(0,0,0,0);
@@ -971,8 +985,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
AttachmentManager.selectGallery(this, PICK_GALLERY); break;
case AttachmentTypeSelector.ADD_DOCUMENT:
AttachmentManager.selectDocument(this, PICK_DOCUMENT); break;
case AttachmentTypeSelector.INVITE_VIDEO_CHAT:
new VideochatUtil().invite(this, chatId); break;
case AttachmentTypeSelector.ADD_CONTACT_INFO:
startContactChooserActivity(); break;
case AttachmentTypeSelector.ADD_LOCATION:
@@ -1011,7 +1023,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
}
try {
byte[] vcard = rpc.makeVcard(dcContext.getAccountId(), contactId).getBytes();
byte[] vcard = rpc.makeVcard(dcContext.getAccountId(), Collections.singletonList(contactId)).getBytes();
String mimeType = "application/octet-stream";
setMedia(PersistentBlobProvider.getInstance().create(this, vcard, mimeType, "vcard.vcf"), MediaType.DOCUMENT);
} catch (RpcException e) {
@@ -1463,7 +1475,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
Recipient author = new Recipient(this, dcContext.getContact(msg.getFromId()));
SlideDeck slideDeck = new SlideDeck();
if (msg.getType() != DcMsg.DC_MSG_TEXT) {
if (msg.hasFile()) {
slideDeck.addSlide(MediaUtil.getSlideForMsg(this, msg));
}
@@ -77,9 +77,8 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
private static final int MESSAGE_TYPE_THUMBNAIL_INCOMING = 6;
private static final int MESSAGE_TYPE_DOCUMENT_OUTGOING = 7;
private static final int MESSAGE_TYPE_DOCUMENT_INCOMING = 8;
private static final int MESSAGE_TYPE_VIDEOCHAT_INVITE = 9;
private static final int MESSAGE_TYPE_STICKER_INCOMING = 10;
private static final int MESSAGE_TYPE_STICKER_OUTGOING = 11;
private static final int MESSAGE_TYPE_STICKER_INCOMING = 9;
private static final int MESSAGE_TYPE_STICKER_OUTGOING = 10;
private final Set<DcMsg> batchSelected = Collections.synchronizedSet(new HashSet<DcMsg>());
@@ -279,7 +278,6 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
case MESSAGE_TYPE_STICKER_INCOMING:
case MESSAGE_TYPE_INCOMING: return R.layout.conversation_item_received;
case MESSAGE_TYPE_INFO: return R.layout.conversation_item_update;
case MESSAGE_TYPE_VIDEOCHAT_INVITE:return R.layout.conversation_item_videochat;
default: throw new IllegalArgumentException("unsupported item view type given to ConversationAdapter");
}
}
@@ -303,9 +301,6 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
else if (type == DcMsg.DC_MSG_STICKER) {
return dcMsg.isOutgoing()? MESSAGE_TYPE_STICKER_OUTGOING : MESSAGE_TYPE_STICKER_INCOMING;
}
else if (type == DcMsg.DC_MSG_VIDEOCHAT_INVITATION) {
return MESSAGE_TYPE_VIDEOCHAT_INVITE;
}
else {
return dcMsg.isOutgoing()? MESSAGE_TYPE_OUTGOING : MESSAGE_TYPE_INCOMING;
}
@@ -33,7 +33,6 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.TextView;
@@ -67,7 +66,7 @@ import org.thoughtcrime.securesms.util.StickyHeaderDecoration;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
import org.thoughtcrime.securesms.util.views.ConversationAdaptiveActionsToolbar;
import org.thoughtcrime.securesms.videochat.VideochatUtil;
import org.thoughtcrime.securesms.calls.CallUtil;
import java.util.Collections;
import java.util.LinkedList;
@@ -368,8 +367,7 @@ public class ConversationFragment extends MessageSelectorFragment
}
static boolean canReplyToMsg(DcMsg dcMsg) {
boolean canReply = dcMsg.getType() != DcMsg.DC_MSG_VIDEOCHAT_INVITATION;
if (canReply && dcMsg.isInfo()) {
if (dcMsg.isInfo()) {
switch (dcMsg.getInfoType()) {
case DcMsg.DC_INFO_GROUP_NAME_CHANGED:
case DcMsg.DC_INFO_GROUP_IMAGE_CHANGED:
@@ -378,16 +376,16 @@ public class ConversationFragment extends MessageSelectorFragment
case DcMsg.DC_INFO_LOCATIONSTREAMING_ENABLED:
case DcMsg.DC_INFO_EPHEMERAL_TIMER_CHANGED:
case DcMsg.DC_INFO_WEBXDC_INFO_MESSAGE:
break;
return true;
default:
canReply = false;
return false;
}
}
return canReply;
return true;
}
static boolean canEditMsg(DcMsg dcMsg) {
return dcMsg.isOutgoing() && !dcMsg.isInfo() && dcMsg.getType() != DcMsg.DC_MSG_VIDEOCHAT_INVITATION && !dcMsg.hasHtml() && !dcMsg.getText().isEmpty();
return dcMsg.isOutgoing() && !dcMsg.isInfo() && dcMsg.getType() != DcMsg.DC_MSG_CALL && !dcMsg.hasHtml() && !dcMsg.getText().isEmpty();
}
public void handleClearChat() {
@@ -759,9 +757,6 @@ public class ConversationFragment extends MessageSelectorFragment
actionMode.setTitleOptionalHint(false); // the title represents important information, also indicating implicitly, more items can be selected
}
}
else if (messageRecord.getType()==DcMsg.DC_MSG_VIDEOCHAT_INVITATION) {
new VideochatUtil().join(getActivity(), messageRecord.getId());
}
else if(DozeReminder.isDozeReminderMsg(getContext(), messageRecord)) {
DozeReminder.dozeReminderTapped(getContext());
}
@@ -877,8 +872,6 @@ public class ConversationFragment extends MessageSelectorFragment
private class ActionModeCallback implements ActionMode.Callback {
private int statusBarColor;
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
@@ -886,10 +879,6 @@ public class ConversationFragment extends MessageSelectorFragment
mode.setTitle("1");
Window window = getActivity().getWindow();
statusBarColor = window.getStatusBarColor();
window.setStatusBarColor(getResources().getColor(R.color.action_mode_status_bar));
Util.redMenuItem(menu, R.id.menu_context_delete_message);
setCorrectMenuVisibility(menu);
ConversationAdaptiveActionsToolbar.adjustMenuActions(menu, 10, requireActivity().getWindow().getDecorView().getMeasuredWidth());
@@ -906,8 +895,6 @@ public class ConversationFragment extends MessageSelectorFragment
((ConversationAdapter)list.getAdapter()).clearSelection();
list.getAdapter().notifyDataSetChanged();
getActivity().getWindow().setStatusBarColor(statusBarColor);
actionMode = null;
hideAddReactionView();
}
@@ -40,14 +40,12 @@ import androidx.appcompat.app.AlertDialog;
import com.b44t.messenger.DcChat;
import com.b44t.messenger.DcContact;
import com.b44t.messenger.DcMsg;
import com.b44t.messenger.rpc.Reactions;
import com.b44t.messenger.rpc.RpcException;
import com.b44t.messenger.rpc.VcardContact;
import org.thoughtcrime.securesms.audio.AudioSlidePlayer;
import org.thoughtcrime.securesms.components.AudioView;
import org.thoughtcrime.securesms.components.AvatarImageView;
import org.thoughtcrime.securesms.components.BorderlessImageView;
import org.thoughtcrime.securesms.components.CallItemView;
import org.thoughtcrime.securesms.components.ConversationItemFooter;
import org.thoughtcrime.securesms.components.ConversationItemThumbnail;
import org.thoughtcrime.securesms.components.DocumentView;
@@ -73,10 +71,17 @@ import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
import org.thoughtcrime.securesms.util.views.Stub;
import org.thoughtcrime.securesms.calls.CallUtil;
import java.util.List;
import java.util.Set;
import chat.delta.rpc.RpcException;
import chat.delta.rpc.types.CallInfo;
import chat.delta.rpc.types.CallState;
import chat.delta.rpc.types.Reactions;
import chat.delta.rpc.types.VcardContact;
/**
* A view that displays an individual conversation item within a conversation
* thread. Used by ComposeMessageActivity's ListActivity via a ConversationAdapter.
@@ -118,6 +123,7 @@ public class ConversationItem extends BaseConversationItem
private @NonNull Stub<WebxdcView> webxdcViewStub;
private Stub<BorderlessImageView> stickerStub;
private Stub<VcardView> vcardViewStub;
private Stub<CallItemView> callViewStub;
private @Nullable EventListener eventListener;
private int measureCalls;
@@ -152,6 +158,7 @@ public class ConversationItem extends BaseConversationItem
this.webxdcViewStub = new Stub<>(findViewById(R.id.webxdc_view_stub));
this.stickerStub = new Stub<>(findViewById(R.id.sticker_view_stub));
this.vcardViewStub = new Stub<>(findViewById(R.id.vcard_view_stub));
this.callViewStub = new Stub<>(findViewById(R.id.call_view_stub));
this.groupSenderHolder = findViewById(R.id.group_sender_holder);
this.quoteView = findViewById(R.id.quote_view);
this.container = findViewById(R.id.container);
@@ -322,6 +329,11 @@ public class ConversationItem extends BaseConversationItem
vcardViewStub.get().setFocusable(!shouldInterceptClicks(messageRecord) && batchSelected.isEmpty());
vcardViewStub.get().setClickable(batchSelected.isEmpty());
}
if (callViewStub.resolved()) {
callViewStub.get().setFocusable(!shouldInterceptClicks(messageRecord) && batchSelected.isEmpty());
callViewStub.get().setClickable(batchSelected.isEmpty());
}
}
private void setContentDescription() {
@@ -338,6 +350,8 @@ public class ConversationItem extends BaseConversationItem
desc += webxdcViewStub.get().getDescription() + "\n";
} else if (vcardViewStub.resolved() && vcardViewStub.get().getVisibility() == View.VISIBLE) {
desc += vcardViewStub.get().getDescription() + "\n";
} else if (callViewStub.resolved() && callViewStub.get().getVisibility() == View.VISIBLE) {
desc += callViewStub.get().getDescription() + "\n";
} else if (mediaThumbnailStub.resolved() && mediaThumbnailStub.get().getVisibility() == View.VISIBLE) {
desc += mediaThumbnailStub.get().getDescription() + "\n";
} else if (stickerStub.resolved() && stickerStub.get().getVisibility() == View.VISIBLE) {
@@ -399,7 +413,7 @@ public class ConversationItem extends BaseConversationItem
String text = messageRecord.getText();
if (text.isEmpty()) {
if (messageRecord.getType() == DcMsg.DC_MSG_CALL || text.isEmpty()) {
bodyText.setVisibility(View.GONE);
}
else {
@@ -490,6 +504,7 @@ public class ConversationItem extends BaseConversationItem
if (webxdcViewStub.resolved()) webxdcViewStub.get().setVisibility(View.GONE);
if (stickerStub.resolved()) stickerStub.get().setVisibility(View.GONE);
if (vcardViewStub.resolved()) vcardViewStub.get().setVisibility(View.GONE);
if (callViewStub.resolved()) callViewStub.get().setVisibility(View.GONE);
//noinspection ConstantConditions
int duration = messageRecord.getDuration();
@@ -515,6 +530,7 @@ public class ConversationItem extends BaseConversationItem
if (webxdcViewStub.resolved()) webxdcViewStub.get().setVisibility(View.GONE);
if (stickerStub.resolved()) stickerStub.get().setVisibility(View.GONE);
if (vcardViewStub.resolved()) vcardViewStub.get().setVisibility(View.GONE);
if (callViewStub.resolved()) callViewStub.get().setVisibility(View.GONE);
//noinspection ConstantConditions
documentViewStub.get().setDocument(new DocumentSlide(context, messageRecord));
@@ -533,6 +549,7 @@ public class ConversationItem extends BaseConversationItem
if (documentViewStub.resolved()) documentViewStub.get().setVisibility(View.GONE);
if (stickerStub.resolved()) stickerStub.get().setVisibility(View.GONE);
if (vcardViewStub.resolved()) vcardViewStub.get().setVisibility(View.GONE);
if (callViewStub.resolved()) callViewStub.get().setVisibility(View.GONE);
webxdcViewStub.get().setWebxdc(messageRecord, context.getString(R.string.webxdc_app));
webxdcViewStub.get().setWebxdcClickListener(new ThumbnailClickListener());
@@ -550,6 +567,7 @@ public class ConversationItem extends BaseConversationItem
if (documentViewStub.resolved()) documentViewStub.get().setVisibility(View.GONE);
if (webxdcViewStub.resolved()) webxdcViewStub.get().setVisibility(View.GONE);
if (stickerStub.resolved()) stickerStub.get().setVisibility(View.GONE);
if (callViewStub.resolved()) callViewStub.get().setVisibility(View.GONE);
vcardViewStub.get().setVcard(glideRequests, new VcardSlide(context, messageRecord), rpc);
vcardViewStub.get().setVcardClickListener(new ThumbnailClickListener());
@@ -561,6 +579,27 @@ public class ConversationItem extends BaseConversationItem
ViewUtil.updateLayoutParams(groupSenderHolder, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
footer.setVisibility(VISIBLE);
}
else if (messageRecord.getType() == DcMsg.DC_MSG_CALL) {
callViewStub.get().setVisibility(View.VISIBLE);
if (mediaThumbnailStub.resolved()) mediaThumbnailStub.get().setVisibility(View.GONE);
if (audioViewStub.resolved()) audioViewStub.get().setVisibility(View.GONE);
if (documentViewStub.resolved()) documentViewStub.get().setVisibility(View.GONE);
if (webxdcViewStub.resolved()) webxdcViewStub.get().setVisibility(View.GONE);
if (stickerStub.resolved()) stickerStub.get().setVisibility(View.GONE);
if (vcardViewStub.resolved()) vcardViewStub.get().setVisibility(View.GONE);
try {
callViewStub.get().setCallItem(messageRecord.isOutgoing(), rpc.callInfo(dcContext.getAccountId(), messageRecord.getId()));
} catch (RpcException e) {
Log.e(TAG, "Error in Rpc.callInfo", e);
}
callViewStub.get().setCallClickListener(new CallClickListener());
callViewStub.get().setOnLongClickListener(passthroughClickListener);
callViewStub.get().setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
ViewUtil.updateLayoutParams(groupSenderHolder, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
else if (hasThumbnail(messageRecord)) {
mediaThumbnailStub.get().setVisibility(View.VISIBLE);
if (audioViewStub.resolved()) audioViewStub.get().setVisibility(View.GONE);
@@ -568,6 +607,7 @@ public class ConversationItem extends BaseConversationItem
if (webxdcViewStub.resolved()) webxdcViewStub.get().setVisibility(View.GONE);
if (stickerStub.resolved()) stickerStub.get().setVisibility(View.GONE);
if (vcardViewStub.resolved()) vcardViewStub.get().setVisibility(View.GONE);
if (callViewStub.resolved()) callViewStub.get().setVisibility(View.GONE);
Slide slide = MediaUtil.getSlideForMsg(context, messageRecord);
@@ -607,6 +647,7 @@ public class ConversationItem extends BaseConversationItem
if (webxdcViewStub.resolved()) webxdcViewStub.get().setVisibility(View.GONE);
if (mediaThumbnailStub.resolved()) mediaThumbnailStub.get().setVisibility(View.GONE);
if (vcardViewStub.resolved()) vcardViewStub.get().setVisibility(View.GONE);
if (callViewStub.resolved()) callViewStub.get().setVisibility(View.GONE);
bodyBubble.setBackgroundColor(Color.TRANSPARENT);
@@ -627,6 +668,7 @@ public class ConversationItem extends BaseConversationItem
if (documentViewStub.resolved()) documentViewStub.get().setVisibility(View.GONE);
if (webxdcViewStub.resolved()) webxdcViewStub.get().setVisibility(View.GONE);
if (vcardViewStub.resolved()) vcardViewStub.get().setVisibility(View.GONE);
if (callViewStub.resolved()) callViewStub.get().setVisibility(View.GONE);
ViewUtil.updateLayoutParams(bodyText, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
ViewUtil.updateLayoutParams(groupSenderHolder, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
@@ -757,11 +799,11 @@ public class ConversationItem extends BaseConversationItem
private void setReactions(@NonNull DcMsg current) {
try {
Reactions reactions = rpc.getMsgReactions(dcContext.getAccountId(), current.getId());
Reactions reactions = rpc.getMessageReactions(dcContext.getAccountId(), current.getId());
if (reactions == null) {
reactionsView.clear();
} else {
reactionsView.setReactions(reactions.getReactions());
reactionsView.setReactions(reactions.reactions);
reactionsView.setOnClickListener(view -> {
if (eventListener != null && batchSelected.isEmpty()) {
eventListener.onReactionClicked(current);
@@ -780,6 +822,8 @@ public class ConversationItem extends BaseConversationItem
return stickerStub.get().getFooter();
} else if (hasOnlyThumbnail(messageRecord) && TextUtils.isEmpty(messageRecord.getText())) {
return mediaThumbnailStub.get().getFooter();
} else if (messageRecord.getType() == DcMsg.DC_MSG_CALL) {
return callViewStub.get().getFooter();
} else {
return footer;
}
@@ -881,6 +925,7 @@ public class ConversationItem extends BaseConversationItem
else if (documentViewStub.resolved()) documentViewStub.get().performClick();
else if (webxdcViewStub.resolved()) webxdcViewStub.get().performClick();
else if (vcardViewStub.resolved()) vcardViewStub.get().performClick();
else if (callViewStub.resolved()) callViewStub.get().performClick();
}
/// Event handlers
@@ -896,7 +941,7 @@ public class ConversationItem extends BaseConversationItem
String path = slide.asAttachment().getRealPath(context);
VcardContact vcardContact = rpc.parseVcard(path).get(0);
new AlertDialog.Builder(context)
.setMessage(context.getString(R.string.ask_start_chat_with, vcardContact.getDisplayName()))
.setMessage(context.getString(R.string.ask_start_chat_with, vcardContact.displayName))
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
try {
List<Integer> contactIds = rpc.importVcard(dcContext.getAccountId(), path);
@@ -942,4 +987,21 @@ public class ConversationItem extends BaseConversationItem
}
}
}
private class CallClickListener implements CallItemView.CallClickListener {
public void onClick(final View v, final CallInfo callInfo) {
if (shouldInterceptClicks(messageRecord) || !batchSelected.isEmpty()) {
performClick();
} else {
int accId = dcContext.getAccountId();
int chatId = messageRecord.getChatId();
if (!messageRecord.isOutgoing() && callInfo.state instanceof CallState.Alerting) {
int callId = messageRecord.getId();
CallUtil.openCall(getContext(), accId, chatId, callId, callInfo.sdpOffer);
} else {
CallUtil.startCall(getContext(), accId, chatId);
}
}
}
}
}
@@ -204,7 +204,8 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
String archProperty = System.getProperty("os.arch");
String arch;
if (archProperty.startsWith("armv7")) arch = "armeabi-v7a";
// armv8l is 32 bit mode in 64 bit CPU:
if (archProperty.startsWith("armv7") || archProperty.startsWith("armv8l")) arch = "armeabi-v7a";
else if (archProperty.equals("aarch64")) arch = "arm64-v8a";
else if (archProperty.equals("i686")) arch = "x86";
else if (archProperty.equals("x86_64")) arch = "x86_64";
@@ -21,7 +21,9 @@ public class ConversationListArchiveActivity extends PassphraseRequiredActionBar
{
@Override
protected void onCreate(Bundle icicle, boolean ready) {
setContentView(R.layout.activity_conversation_list_archive);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setElevation(0); // TODO: use custom toolbar instead
if (isRelayingMessageContent(this)) {
getSupportActionBar().setTitle(isSharing(this) ? R.string.chat_share_with_title : R.string.forward_to);
getSupportActionBar().setSubtitle(R.string.chat_archived_label);
@@ -31,7 +33,7 @@ public class ConversationListArchiveActivity extends PassphraseRequiredActionBar
Bundle bundle = new Bundle();
bundle.putBoolean(ConversationListFragment.ARCHIVE, true);
initFragment(android.R.id.content, new ConversationListFragment(), bundle);
initFragment(R.id.fragment, new ConversationListFragment(), bundle);
}
@Override
@@ -35,7 +35,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.amulyakhare.textdrawable.TextDrawable;
import com.annimon.stream.Stream;
import com.b44t.messenger.DcChat;
import com.b44t.messenger.DcContact;
import com.b44t.messenger.DcContext;
@@ -55,7 +54,6 @@ import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
import java.util.Collections;
import java.util.List;
import java.util.Set;
public class ConversationListItem extends RelativeLayout
@@ -134,7 +132,7 @@ public class ConversationListItem extends RelativeLayout
this.fromView.setText(recipient, state!=DcMsg.DC_STATE_IN_FRESH);
}
subjectView.setVisibility(VISIBLE);
subjectView.setVisibility(chatId == DcChat.DC_CHAT_ID_ARCHIVED_LINK? GONE : VISIBLE);
this.subjectView.setText(thread.getDisplayBody());
this.subjectView.setTypeface(state==DcMsg.DC_STATE_IN_FRESH ? BOLD_TYPEFACE : LIGHT_TYPEFACE);
this.subjectView.setTextColor(state==DcMsg.DC_STATE_IN_FRESH ? ThemeUtil.getThemedColor(getContext(), R.attr.conversation_list_item_unread_color)
@@ -329,15 +327,12 @@ public class ConversationListItem extends RelativeLayout
String normalizedValue = value.toLowerCase(Util.getLocale());
String normalizedTest = highlight.toLowerCase(Util.getLocale());
List<String> testTokens;
try (Stream<String> stream = Stream.of(normalizedTest.split(" "))) {
testTokens = stream.filter(s -> !s.trim().isEmpty()).toList();
}
Spannable spanned = new SpannableString(value);
int searchStartIndex = 0;
for (String token : testTokens) {
for (String token : normalizedTest.split(" ")) {
if (token.trim().isEmpty()) continue;
if (searchStartIndex >= spanned.length()) {
break;
}
@@ -1,99 +0,0 @@
package org.thoughtcrime.securesms;
import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.b44t.messenger.DcChat;
import com.b44t.messenger.DcContact;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcMsg;
import org.thoughtcrime.securesms.components.AvatarImageView;
import org.thoughtcrime.securesms.components.ConversationItemFooter;
import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
import java.util.Set;
public class ConversationVideochatItem extends LinearLayout
implements BindableConversationItem
{
private TextView body;
private ConversationItemFooter footer;
private AvatarImageView contactPhoto;
private ViewGroup contactPhotoHolder;
private DcMsg dcMsg;
public ConversationVideochatItem(Context context) {
super(context);
}
public ConversationVideochatItem(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onFinishInflate() {
super.onFinishInflate();
this.body = findViewById(R.id.conversation_update_body);
this.footer = findViewById(R.id.conversation_item_footer);
this.contactPhoto = findViewById(R.id.contact_photo);
this.contactPhotoHolder = findViewById(R.id.contact_photo_container);
}
@Override
public void bind(@NonNull DcMsg dcMsg,
@NonNull DcChat dcChat,
@NonNull GlideRequests glideRequests,
@NonNull Set<DcMsg> batchSelected,
@NonNull Recipient conversationRecipient,
boolean pulseUpdate)
{
this.dcMsg = dcMsg;
DcContext dcContext = DcHelper.getContext(getContext());
DcContact dcContact = dcContext.getContact(dcMsg.getFromId());
CharSequence line1 = dcMsg.isOutgoing()? getContext().getString(R.string.videochat_you_invited_hint) :
getContext().getString(R.string.videochat_contact_invited_hint, dcContact.getDisplayName());
CharSequence line2 = Util.getBoldedString(dcMsg.isOutgoing()? getContext().getString(R.string.videochat_tap_to_open) :
getContext().getString(R.string.videochat_tap_to_join));
body.setText(TextUtils.concat(line1, "\n", line2));
contactPhoto.setAvatar(glideRequests, new Recipient(getContext(), dcContact), true);
setSelected(batchSelected.contains(dcMsg));
setFooter(dcMsg);
}
private void setFooter(@NonNull DcMsg dcMsg) {
ViewUtil.updateLayoutParams(footer, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
footer.setVisibility(VISIBLE);
footer.setMessageRecord(dcMsg);
}
@Override
public void setEventListener(@Nullable EventListener listener) {
// No events to report yet
}
@Override
public DcMsg getMessageRecord() {
return dcMsg;
}
@Override
public void unbind() {
}
}
@@ -38,7 +38,6 @@ import org.thoughtcrime.securesms.mms.AttachmentManager;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.permissions.Permissions;
import org.thoughtcrime.securesms.profiles.AvatarHelper;
import org.thoughtcrime.securesms.profiles.ProfileMediaConstraints;
import org.thoughtcrime.securesms.scribbles.ScribbleActivity;
import org.thoughtcrime.securesms.util.Prefs;
import org.thoughtcrime.securesms.util.ViewUtil;
@@ -80,6 +79,7 @@ public class CreateProfileActivity extends BaseActionBarActivity {
getSupportActionBar().setTitle(R.string.pref_profile_info_headline);
getSupportActionBar().setDisplayHomeAsUpEnabled(!this.fromWelcome);
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_close_white_24dp);
getSupportActionBar().setElevation(0); // TODO: use custom toolbar instead
attachmentManager = new AttachmentManager(this, () -> {});
avatarChanged = false;
@@ -147,14 +147,13 @@ public class CreateProfileActivity extends BaseActionBarActivity {
}
private void setAvatarView(Uri output) {
final ProfileMediaConstraints constraints = new ProfileMediaConstraints();
GlideApp.with(this)
.asBitmap()
.load(output)
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.centerCrop()
.override(constraints.getImageMaxWidth(this), constraints.getImageMaxHeight(this))
.override(AvatarHelper.AVATAR_SIZE, AvatarHelper.AVATAR_SIZE)
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
@@ -60,13 +60,12 @@ public class EphemeralMessagesDialog {
.setPositiveButton(R.string.ok, (dialog, which) -> {
final long burnAfter;
switch (selectedChoice[0]) {
case 1: burnAfter = TimeUnit.MINUTES.toSeconds(1); break;
case 2: burnAfter = TimeUnit.MINUTES.toSeconds(5); break;
case 3: burnAfter = TimeUnit.MINUTES.toSeconds(30); break;
case 4: burnAfter = TimeUnit.HOURS.toSeconds(1); break;
case 5: burnAfter = TimeUnit.DAYS.toSeconds(1); break;
case 6: burnAfter = TimeUnit.DAYS.toSeconds(7); break;
case 7: burnAfter = TimeUnit.DAYS.toSeconds(35); break;
case 1: burnAfter = TimeUnit.MINUTES.toSeconds(5); break;
case 2: burnAfter = TimeUnit.HOURS.toSeconds(1); break;
case 3: burnAfter = TimeUnit.DAYS.toSeconds(1); break;
case 4: burnAfter = TimeUnit.DAYS.toSeconds(7); break;
case 5: burnAfter = TimeUnit.DAYS.toSeconds(35); break;
case 6: burnAfter = TimeUnit.DAYS.toSeconds(365); break;
default: burnAfter = 0; break;
}
listener.onTimeSelected(burnAfter);
@@ -83,27 +82,23 @@ public class EphemeralMessagesDialog {
if (timespan == 0) {
return 0; // off
}
// Choose timespan close to the current one out of available options.
if (timespan < TimeUnit.MINUTES.toSeconds(5)) {
return 1; // 1 minute
}
if (timespan < TimeUnit.MINUTES.toSeconds(30)) {
return 2; // 5 minutes
}
if (timespan < TimeUnit.HOURS.toSeconds(1)) {
return 3; // 30 minutes
return 1; // 5 minutes
}
if (timespan < TimeUnit.DAYS.toSeconds(1)) {
return 4; // 1 hour
return 2; // 1 hour
}
if (timespan < TimeUnit.DAYS.toSeconds(7)) {
return 5; // 1 day
return 3; // 1 day
}
if (timespan < TimeUnit.DAYS.toSeconds(35)) {
return 6; // 1 week
return 4; // 1 week
}
return 7; // 5 weeks
if (timespan < TimeUnit.DAYS.toSeconds(365)) {
return 5; // 5 weeks
}
return 6; // 1 year
}
}
@@ -13,17 +13,19 @@ import android.webkit.WebView;
import androidx.appcompat.app.AlertDialog;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.rpc.HttpResponse;
import com.b44t.messenger.rpc.Rpc;
import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.JsonUtils;
import org.thoughtcrime.securesms.util.Prefs;
import org.thoughtcrime.securesms.util.Util;
import java.io.ByteArrayInputStream;
import java.lang.ref.WeakReference;
import chat.delta.rpc.Rpc;
import chat.delta.rpc.types.HttpResponse;
public class FullMsgActivity extends WebViewActivity
{
public static final String MSG_ID_EXTRA = "msg_id";
@@ -227,11 +229,12 @@ public class FullMsgActivity extends WebViewActivity
throw new Exception("no url specified");
}
HttpResponse httpResponse = rpc.getHttpResponse(dcContext.getAccountId(), url);
String mimeType = httpResponse.getMimetype();
String mimeType = httpResponse.mimetype;
if (mimeType == null) {
mimeType = "application/octet-stream";
}
res = new WebResourceResponse(mimeType, httpResponse.getEncoding(), new ByteArrayInputStream(httpResponse.getBlob()));
byte[] blob = JsonUtils.decodeBase64(httpResponse.blob);
res = new WebResourceResponse(mimeType, httpResponse.encoding, new ByteArrayInputStream(blob));
} catch (Exception e) {
e.printStackTrace();
res = new WebResourceResponse("text/plain", "UTF-8", new ByteArrayInputStream(("Error: " + e.getMessage()).getBytes()));
@@ -23,7 +23,6 @@ import androidx.loader.app.LoaderManager;
import com.b44t.messenger.DcChat;
import com.b44t.messenger.DcContact;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.rpc.RpcException;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;
@@ -33,6 +32,7 @@ import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.contacts.avatars.ResourceContactPhoto;
import org.thoughtcrime.securesms.mms.AttachmentManager;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.permissions.Permissions;
import org.thoughtcrime.securesms.profiles.AvatarHelper;
import org.thoughtcrime.securesms.scribbles.ScribbleActivity;
import org.thoughtcrime.securesms.util.SelectedContactsAdapter;
@@ -44,6 +44,8 @@ import java.io.File;
import java.util.ArrayList;
import java.util.Objects;
import chat.delta.rpc.RpcException;
public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
implements ItemClickListener
{
@@ -54,7 +56,6 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
public static final String CLONE_CHAT_EXTRA = "clone_chat";
private static final int PICK_CONTACT = 1;
public static final int AVATAR_SIZE = 210;
private static final int REQUEST_CODE_AVATAR = 2759;
private DcContext dcContext;
@@ -81,6 +82,7 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
unencrypted = getIntent().getBooleanExtra(UNENCRYPTED, false);
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_close_white_24dp);
getSupportActionBar().setElevation(0); // TODO: use custom toolbar instead
groupChatId = getIntent().getIntExtra(EDIT_GROUP_CHAT_ID, 0);
attachmentManager = new AttachmentManager(this, () -> {});
@@ -340,6 +342,12 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
return ret;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
Permissions.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
}
@Override
public void onActivityResult(int reqCode, int resultCode, final Intent data) {
super.onActivityResult(reqCode, resultCode, data);
@@ -376,7 +384,7 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.centerCrop()
.override(AVATAR_SIZE, AVATAR_SIZE)
.override(AvatarHelper.AVATAR_SIZE, AvatarHelper.AVATAR_SIZE)
.into(new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
@@ -34,8 +34,6 @@ import androidx.loader.app.LoaderManager;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcEvent;
import com.b44t.messenger.DcLot;
import com.b44t.messenger.rpc.Rpc;
import com.b44t.messenger.rpc.RpcException;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;
@@ -51,7 +49,6 @@ import org.thoughtcrime.securesms.mms.AttachmentManager;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.permissions.Permissions;
import org.thoughtcrime.securesms.profiles.AvatarHelper;
import org.thoughtcrime.securesms.profiles.ProfileMediaConstraints;
import org.thoughtcrime.securesms.proxy.ProxySettingsActivity;
import org.thoughtcrime.securesms.qr.RegistrationQrActivity;
import org.thoughtcrime.securesms.scribbles.ScribbleActivity;
@@ -65,6 +62,9 @@ import java.io.IOException;
import java.security.SecureRandom;
import java.util.Objects;
import chat.delta.rpc.Rpc;
import chat.delta.rpc.RpcException;
public class InstantOnboardingActivity extends BaseActionBarActivity implements DcEventCenter.DcEventDelegate {
private static final String TAG = InstantOnboardingActivity.class.getSimpleName();
@@ -90,7 +90,10 @@ public class InstantOnboardingActivity extends BaseActionBarActivity implements
private AttachmentManager attachmentManager;
private Bitmap avatarBmp;
private @Nullable ProgressDialog progressDialog;
private boolean cancelled;
private DcContext dcContext;
@Override
@@ -101,6 +104,7 @@ public class InstantOnboardingActivity extends BaseActionBarActivity implements
Objects.requireNonNull(getSupportActionBar()).setTitle(R.string.onboarding_create_instant_account);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setElevation(0); // TODO: use custom toolbar instead
boolean fromWelcome = getIntent().getBooleanExtra(FROM_WELCOME, false);
if (DcHelper.getContext(this).isConfigured() == 1) {
@@ -286,14 +290,13 @@ public class InstantOnboardingActivity extends BaseActionBarActivity implements
}
private void setAvatarView(Uri output) {
final ProfileMediaConstraints constraints = new ProfileMediaConstraints();
GlideApp.with(this)
.asBitmap()
.load(output)
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.centerCrop()
.override(constraints.getImageMaxWidth(this), constraints.getImageMaxHeight(this))
.override(AvatarHelper.AVATAR_SIZE, AvatarHelper.AVATAR_SIZE)
.into(new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
@@ -423,7 +426,6 @@ public class InstantOnboardingActivity extends BaseActionBarActivity implements
}
private void progressSuccess() {
DcHelper.getEventCenter(this).endCaptureNextError();
if (progressDialog != null) {
progressDialog.dismiss();
}
@@ -482,11 +484,14 @@ public class InstantOnboardingActivity extends BaseActionBarActivity implements
progressDialog = null;
}
cancelled = false;
progressDialog = new ProgressDialog(this);
progressDialog.setMessage(getResources().getString(R.string.one_moment));
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setCancelable(false);
progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getResources().getString(android.R.string.cancel), (dialog, which) -> {
cancelled = true;
dcContext.stopOngoingProcess();
});
progressDialog.show();
@@ -497,9 +502,13 @@ public class InstantOnboardingActivity extends BaseActionBarActivity implements
Rpc rpc = DcHelper.getRpc(this);
try {
rpc.addTransportFromQr(dcContext.getAccountId(), qrCode);
DcHelper.getEventCenter(this).endCaptureNextError();
progressSuccess();
} catch (RpcException e) {
Util.runOnMain(() -> progressError(e.getMessage()));
DcHelper.getEventCenter(this).endCaptureNextError();
if (!cancelled) {
Util.runOnMain(() -> progressError(e.getMessage()));
}
}
}).start();
}
@@ -36,6 +36,7 @@ public class LogViewActivity extends BaseActionBarActivity {
transaction.commit();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setElevation(0); // TODO: use custom toolbar instead
}
@Override
@@ -86,7 +86,7 @@ public abstract class MessageSelectorFragment
.setCancelable(true)
.setNeutralButton(android.R.string.cancel, null)
.setPositiveButton(positiveBtnLabel, (d, which) -> {
dcContext.deleteMsgs(messageIds);
Util.runOnAnyBackgroundThread(() -> dcContext.deleteMsgs(messageIds));
if (actionMode != null) actionMode.finish();
});
@@ -23,8 +23,6 @@ import com.b44t.messenger.DcChat;
import com.b44t.messenger.DcContact;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcEvent;
import com.b44t.messenger.rpc.Rpc;
import com.b44t.messenger.rpc.RpcException;
import org.thoughtcrime.securesms.connect.DcEventCenter;
import org.thoughtcrime.securesms.connect.DcHelper;
@@ -36,6 +34,9 @@ import org.thoughtcrime.securesms.util.ViewUtil;
import java.io.File;
import chat.delta.rpc.Rpc;
import chat.delta.rpc.RpcException;
public class ProfileActivity extends PassphraseRequiredActionBarActivity
implements DcEventCenter.DcEventDelegate
{
@@ -109,7 +110,7 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
if (chatId != 0) {
DcChat dcChat = dcContext.getChat(chatId);
menu.findItem(R.id.menu_clone).setVisible(chatIsMultiUser && !chatIsMailingList && dcChat.isEncrypted());
menu.findItem(R.id.menu_clone).setVisible(chatIsMultiUser && !chatIsInBroadcast && !chatIsMailingList);
if (chatIsDeviceTalk) {
menu.findItem(R.id.edit_name).setVisible(false);
menu.findItem(R.id.show_encr_info).setVisible(false);
@@ -315,12 +316,12 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
String profileImagePath;
String title;
Uri profileImageUri;
boolean chatIsEncrypted = true;
boolean enlargeAvatar = true;
if(chatId!=0) {
DcChat dcChat = dcContext.getChat(chatId);
profileImagePath = dcChat.getProfileImage();
title = dcChat.getName();
chatIsEncrypted = dcChat.isEncrypted();
enlargeAvatar = dcChat.isEncrypted() && !dcChat.isSelfTalk() && !dcChat.isDeviceTalk();
} else {
DcContact dcContact = dcContext.getContact(contactId);
profileImagePath = dcContact.getProfileImage();
@@ -329,7 +330,7 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
File file = new File(profileImagePath);
if (chatIsEncrypted && file.exists()) {
if (enlargeAvatar && file.exists()) {
profileImageUri = Uri.fromFile(file);
String type = "image/" + profileImagePath.substring(profileImagePath.lastIndexOf(".") + 1);
@@ -390,7 +391,12 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
private void onShare() {
Intent composeIntent = new Intent();
RelayUtil.setSharedContactId(composeIntent, contactId);
DcContact dcContact = dcContext.getContact(contactId);
if (dcContact.isKeyContact()) {
RelayUtil.setSharedContactId(composeIntent, contactId);
} else {
RelayUtil.setSharedText(composeIntent, dcContact.getAddr());
}
ConversationListRelayingActivity.start(this, composeIntent);
}
@@ -278,6 +278,7 @@ public class ProfileAdapter extends RecyclerView.Adapter
itemDataStatusText = "";
isOutBroadcast = dcChat != null && dcChat.isOutBroadcast();
boolean isMailingList = dcChat != null && dcChat.isMailingList();
boolean isInBroadcast = dcChat != null && dcChat.isInBroadcast();
boolean isSelfTalk = dcChat != null && dcChat.isSelfTalk();
boolean isDeviceTalk = dcChat != null && dcChat.isDeviceTalk();
memberCount = memberList!=null ? memberList.length : 0;
@@ -311,7 +312,7 @@ public class ProfileAdapter extends RecyclerView.Adapter
}
*/
if (memberList!=null && !isMailingList) {
if (memberList!=null && !isInBroadcast && !isMailingList) {
itemData.add(new ItemData(ITEM_DIVIDER, null, 0));
if (dcChat != null) {
if (dcChat.canSend() && dcChat.isEncrypted()) {
@@ -3,14 +3,12 @@ package org.thoughtcrime.securesms;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.Toast;
import androidx.annotation.NonNull;
@@ -249,8 +247,6 @@ public class ProfileFragment extends Fragment
private class ActionModeCallback implements ActionMode.Callback {
private int originalStatusBarColor;
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.profile_context, menu);
@@ -263,9 +259,6 @@ public class ProfileFragment extends Fragment
menu.findItem(R.id.menu_select_all).setVisible(false);
mode.setTitle("1");
Window window = requireActivity().getWindow();
originalStatusBarColor = window.getStatusBarColor();
window.setStatusBarColor(getResources().getColor(R.color.action_mode_status_bar));
return true;
}
@@ -306,7 +299,6 @@ public class ProfileFragment extends Fragment
public void onDestroyActionMode(ActionMode mode) {
actionMode = null;
adapter.clearSelection();
requireActivity().getWindow().setStatusBarColor(originalStatusBarColor);
}
}
@@ -46,11 +46,6 @@ import androidx.constraintlayout.widget.Group;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcEvent;
import com.b44t.messenger.DcProvider;
import com.b44t.messenger.rpc.EnteredLoginParam;
import com.b44t.messenger.rpc.Rpc;
import com.b44t.messenger.rpc.RpcException;
import com.b44t.messenger.util.concurrent.ListenableFuture;
import com.b44t.messenger.util.concurrent.SettableFuture;
import com.google.android.material.textfield.TextInputEditText;
import org.thoughtcrime.securesms.connect.DcEventCenter;
@@ -66,6 +61,14 @@ import org.thoughtcrime.securesms.util.views.ProgressDialog;
import java.lang.ref.WeakReference;
import java.util.concurrent.ExecutionException;
import chat.delta.rpc.Rpc;
import chat.delta.rpc.RpcException;
import chat.delta.rpc.types.EnteredCertificateChecks;
import chat.delta.rpc.types.EnteredLoginParam;
import chat.delta.rpc.types.Socket;
import chat.delta.util.ListenableFuture;
import chat.delta.util.SettableFuture;
public class RegistrationActivity extends BaseActionBarActivity implements DcEventCenter.DcEventDelegate {
private enum VerificationType {
@@ -87,6 +90,7 @@ public class RegistrationActivity extends BaseActionBarActivity implements DcEve
private Group advancedGroup;
private ImageView advancedIcon;
private ProgressDialog progressDialog;
private boolean cancelled = false;
Spinner imapSecurity;
Spinner smtpSecurity;
@@ -135,6 +139,7 @@ public class RegistrationActivity extends BaseActionBarActivity implements DcEve
actionBar.setTitle(R.string.login_header);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(R.drawable.ic_close_white_24dp);
actionBar.setElevation(0); // TODO: use custom toolbar instead
}
emailInput.addTextChangedListener(new TextWatcher() {
@@ -562,6 +567,7 @@ public class RegistrationActivity extends BaseActionBarActivity implements DcEve
return;
}
cancelled = false;
setupConfig();
if (progressDialog != null) {
@@ -573,7 +579,10 @@ public class RegistrationActivity extends BaseActionBarActivity implements DcEve
progressDialog.setMessage(getString(R.string.one_moment));
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setCancelable(false);
progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getString(android.R.string.cancel), (dialog, which) -> stopLoginProcess());
progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getString(android.R.string.cancel), (dialog, which) -> {
cancelled = true;
DcHelper.getContext(this).stopOngoingProcess();
});
progressDialog.show();
}
@@ -583,24 +592,49 @@ public class RegistrationActivity extends BaseActionBarActivity implements DcEve
&& !passwordInput.getText().toString().isEmpty();
}
private EnteredCertificateChecks certificateChecksFromInt(int position) {
switch (position) {
case 0:
return EnteredCertificateChecks.automatic;
case 1:
return EnteredCertificateChecks.strict;
case 2:
return EnteredCertificateChecks.acceptInvalidCertificates;
}
throw new IllegalArgumentException("Invalid certificate position: " + position);
}
public static Socket socketSecurityFromInt(int position) {
switch (position) {
case 0:
return Socket.automatic;
case 1:
return Socket.ssl;
case 2:
return Socket.starttls;
case 3:
return Socket.plain;
}
throw new IllegalArgumentException("Invalid socketSecurity position: " + position);
}
private void setupConfig() {
DcHelper.getEventCenter(this).captureNextError();
EnteredLoginParam param = new EnteredLoginParam(
getParam(R.id.email_text, true),
getParam(R.id.password_text, false),
getParam(R.id.imap_server_text, true),
Util.objectToInt(getParam(R.id.imap_port_text, true)),
EnteredLoginParam.socketSecurityFromInt(imapSecurity.getSelectedItemPosition()),
getParam(R.id.imap_login_text, false),
getParam(R.id.smtp_server_text, true),
Util.objectToInt(getParam(R.id.smtp_port_text, true)),
EnteredLoginParam.socketSecurityFromInt(smtpSecurity.getSelectedItemPosition()),
getParam(R.id.smtp_login_text, false),
getParam(R.id.smtp_password_text, false),
EnteredLoginParam.certificateChecksFromInt(certCheck.getSelectedItemPosition()),
authMethod.getSelectedItemPosition() == 1
);
EnteredLoginParam param = new EnteredLoginParam();
param.addr = getParam(R.id.email_text, true);
param.password = getParam(R.id.password_text, false);
param.imapServer = getParam(R.id.imap_server_text, true);
param.imapPort = Util.objectToInt(getParam(R.id.imap_port_text, true));
param.imapSecurity = socketSecurityFromInt(imapSecurity.getSelectedItemPosition());
param.imapUser = getParam(R.id.imap_login_text, false);
param.smtpServer = getParam(R.id.smtp_server_text, true);
param.smtpPort = Util.objectToInt(getParam(R.id.smtp_port_text, true));
param.smtpSecurity = socketSecurityFromInt(smtpSecurity.getSelectedItemPosition());
param.smtpUser = getParam(R.id.smtp_login_text, false);
param.smtpPassword = getParam(R.id.smtp_password_text, false);
param.certificateChecks = certificateChecksFromInt(certCheck.getSelectedItemPosition());
param.oauth2 = authMethod.getSelectedItemPosition() == 1;
new Thread(() -> {
Rpc rpc = DcHelper.getRpc(this);
@@ -612,11 +646,13 @@ public class RegistrationActivity extends BaseActionBarActivity implements DcEve
startActivity(conversationList);
finish();
} catch (RpcException e) {
Util.runOnMain(() -> {
DcHelper.getEventCenter(this).endCaptureNextError();
progressDialog.dismiss();
WelcomeActivity.maybeShowConfigurationError(this, e.getMessage());
});
DcHelper.getEventCenter(this).endCaptureNextError();
if (!cancelled) {
Util.runOnMain(() -> {
progressDialog.dismiss();
WelcomeActivity.maybeShowConfigurationError(this, e.getMessage());
});
}
}
}).start();
}
@@ -630,10 +666,6 @@ public class RegistrationActivity extends BaseActionBarActivity implements DcEve
return value.isEmpty()? null : value;
}
private void stopLoginProcess() {
DcHelper.getContext(this).stopOngoingProcess();
}
@Override
public void handleEvent(@NonNull DcEvent event) {
if (event.getId()==DcContext.DC_EVENT_CONFIGURE_PROGRESS) {
@@ -34,6 +34,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.pm.ShortcutManagerCompat;
import com.b44t.messenger.DcContext;
@@ -217,6 +218,16 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity implement
int chatId = intent.getIntExtra(EXTRA_CHAT_ID, -1);
String msgType = intent.getStringExtra(EXTRA_MSG_TYPE);
// the intent coming from shortcuts in the share selector might not include the custom extras but the shortcut ID
String shortcutId = intent.getStringExtra(ShortcutManagerCompat.EXTRA_SHORTCUT_ID);
if ((chatId == -1 || accId == -1) && shortcutId != null && shortcutId.startsWith("chat-")) {
String[] args = shortcutId.split("-");
if (args.length == 3) {
accId = Integer.parseInt(args[1]);
chatId = Integer.parseInt(args[2]);
}
}
String[] extraEmail = getIntent().getStringArrayExtra(Intent.EXTRA_EMAIL);
/*
usually, external app will try to start "e-mail sharing" intent, providing it:
@@ -55,6 +55,7 @@ public class WebViewActivity extends PassphraseRequiredActionBarActivity
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setElevation(0); // TODO: use custom toolbar instead
}
webView = findViewById(R.id.webview);
@@ -38,8 +38,6 @@ import com.b44t.messenger.DcChat;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcEvent;
import com.b44t.messenger.DcMsg;
import com.b44t.messenger.rpc.Rpc;
import com.b44t.messenger.rpc.RpcException;
import com.google.common.base.Charsets;
import org.json.JSONObject;
@@ -63,6 +61,9 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import chat.delta.rpc.Rpc;
import chat.delta.rpc.RpcException;
public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcEventDelegate {
private static final String TAG = WebxdcActivity.class.getSimpleName();
private static final String EXTRA_ACCOUNT_ID = "accountId";
@@ -17,13 +17,11 @@ import android.widget.Toast;
import androidx.appcompat.app.ActionBar;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.rpc.HttpResponse;
import com.b44t.messenger.rpc.Rpc;
import com.b44t.messenger.rpc.RpcException;
import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.providers.PersistentBlobProvider;
import org.thoughtcrime.securesms.util.IntentUtils;
import org.thoughtcrime.securesms.util.JsonUtils;
import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.Prefs;
import org.thoughtcrime.securesms.util.Util;
@@ -31,6 +29,10 @@ import org.thoughtcrime.securesms.util.Util;
import java.io.ByteArrayInputStream;
import java.util.HashMap;
import chat.delta.rpc.Rpc;
import chat.delta.rpc.RpcException;
import chat.delta.rpc.types.HttpResponse;
public class WebxdcStoreActivity extends PassphraseRequiredActionBarActivity {
private static final String TAG = WebxdcStoreActivity.class.getSimpleName();
@@ -48,6 +50,7 @@ public class WebxdcStoreActivity extends PassphraseRequiredActionBarActivity {
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle(R.string.webxdc_apps);
actionBar.setElevation(0); // TODO: use custom toolbar instead
}
webView.setWebViewClient(new WebViewClient() {
@@ -58,7 +61,8 @@ public class WebxdcStoreActivity extends PassphraseRequiredActionBarActivity {
Util.runOnAnyBackgroundThread(() -> {
try {
HttpResponse httpResponse = rpc.getHttpResponse(dcContext.getAccountId(), url);
Uri uri = PersistentBlobProvider.getInstance().create(WebxdcStoreActivity.this, httpResponse.getBlob(), "application/octet-stream", "app.xdc");
byte[] blob = JsonUtils.decodeBase64(httpResponse.blob);
Uri uri = PersistentBlobProvider.getInstance().create(WebxdcStoreActivity.this, blob, "application/octet-stream", "app.xdc");
Intent intent = new Intent();
intent.setData(uri);
setResult(Activity.RESULT_OK, intent);
@@ -107,13 +111,14 @@ public class WebxdcStoreActivity extends PassphraseRequiredActionBarActivity {
throw new Exception("no url specified");
}
HttpResponse httpResponse = rpc.getHttpResponse(dcContext.getAccountId(), url);
String mimeType = httpResponse.getMimetype();
String mimeType = httpResponse.mimetype;
if (mimeType == null) {
mimeType = "application/octet-stream";
}
ByteArrayInputStream data = new ByteArrayInputStream(httpResponse.getBlob());
res = new WebResourceResponse(mimeType, httpResponse.getEncoding(), data);
byte[] blob = JsonUtils.decodeBase64(httpResponse.blob);
ByteArrayInputStream data = new ByteArrayInputStream(blob);
res = new WebResourceResponse(mimeType, httpResponse.encoding, data);
} catch (Exception e) {
e.printStackTrace();
ByteArrayInputStream data = new ByteArrayInputStream(("Could not load apps. Are you online?\n\n" + e.getMessage()).getBytes());
@@ -26,8 +26,6 @@ import com.b44t.messenger.DcAccounts;
import com.b44t.messenger.DcContact;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcEvent;
import com.b44t.messenger.rpc.Rpc;
import com.b44t.messenger.rpc.RpcException;
import org.thoughtcrime.securesms.ConnectivityActivity;
import org.thoughtcrime.securesms.ConversationListActivity;
@@ -43,6 +41,9 @@ import org.thoughtcrime.securesms.util.ViewUtil;
import java.util.Arrays;
import chat.delta.rpc.Rpc;
import chat.delta.rpc.RpcException;
public class AccountSelectionListFragment extends DialogFragment implements DcEventCenter.DcEventDelegate
{
private static final String TAG = AccountSelectionListFragment.class.getSimpleName();
@@ -8,9 +8,6 @@ import android.util.Pair;
import androidx.annotation.NonNull;
import com.b44t.messenger.util.concurrent.ListenableFuture;
import com.b44t.messenger.util.concurrent.SettableFuture;
import org.thoughtcrime.securesms.providers.PersistentBlobProvider;
import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.ThreadUtil;
@@ -19,6 +16,9 @@ import org.thoughtcrime.securesms.util.Util;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import chat.delta.util.ListenableFuture;
import chat.delta.util.SettableFuture;
public class AudioRecorder {
private static final String TAG = AudioRecorder.class.getSimpleName();
@@ -0,0 +1,203 @@
package org.thoughtcrime.securesms.calls;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
import android.view.Menu;
import android.webkit.JavascriptInterface;
import android.webkit.PermissionRequest;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import androidx.annotation.NonNull;
import com.b44t.messenger.DcChat;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcEvent;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.WebViewActivity;
import org.thoughtcrime.securesms.connect.DcEventCenter;
import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.permissions.Permissions;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.AvatarUtil;
import org.thoughtcrime.securesms.util.Util;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import chat.delta.rpc.Rpc;
import chat.delta.rpc.RpcException;
public class CallActivity extends WebViewActivity implements DcEventCenter.DcEventDelegate {
private static final String TAG = CallActivity.class.getSimpleName();
public static final String EXTRA_ACCOUNT_ID = "acc_id";
public static final String EXTRA_CHAT_ID = "chat_id";
public static final String EXTRA_CALL_ID = "call_id";
public static final String EXTRA_HASH = "hash";
private DcContext dcContext;
private Rpc rpc;
private int accId;
private int chatId;
private int callId;
private boolean ended = false;
@SuppressLint("SetJavaScriptEnabled")
@Override
protected void onCreate(Bundle state, boolean ready) {
super.onCreate(state, ready);
Bundle bundle = getIntent().getExtras();
assert bundle != null;
String hash = bundle.getString(EXTRA_HASH, "");
accId = bundle.getInt(EXTRA_ACCOUNT_ID, -1);
chatId = bundle.getInt(EXTRA_CHAT_ID, 0);
callId = bundle.getInt(EXTRA_CALL_ID, 0);
rpc = DcHelper.getRpc(this);
dcContext = DcHelper.getAccounts(this).getAccount(accId);
DcHelper.getNotificationCenter(this).removeCallNotification(accId, callId);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setMediaPlaybackRequiresUserGesture(false);
webView.addJavascriptInterface(new InternalJSApi(), "calls");
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onPermissionRequest(PermissionRequest request) {
Util.runOnMain(() -> request.grant(request.getResources()));
}
});
DcEventCenter eventCenter = DcHelper.getEventCenter(getApplicationContext());
eventCenter.addObserver(DcContext.DC_EVENT_OUTGOING_CALL_ACCEPTED, this);
eventCenter.addObserver(DcContext.DC_EVENT_CALL_ENDED, this);
Util.runOnAnyBackgroundThread(() -> {
final DcChat chat = dcContext.getChat(chatId);
Util.runOnMain(() -> Objects.requireNonNull(getSupportActionBar()).setTitle(chat.getName()));
});
Permissions.with(this)
.request(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO)
.ifNecessary()
.withPermanentDenialDialog(getString(R.string.perm_explain_access_to_camera_denied))
.onAllGranted(() -> {
String url = "file:///android_asset/calls/index.html";
webView.loadUrl(url + hash);
}).onAnyDenied(this::finish)
.execute();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
Permissions.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
}
@Override
protected void onDestroy() {
DcHelper.getEventCenter(this).removeObservers(this);
if (callId != 0 && !ended) {
try {
rpc.endCall(accId, callId);
} catch (RpcException e) {
Log.e(TAG, "Error", e);
}
}
super.onDestroy();
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
// do not call super.onPrepareOptionsMenu() as the default "Search" menu is not needed
return true;
}
@Override
protected boolean openOnlineUrl(String url) {
finish();
return true;
}
@Override
public void handleEvent(@NonNull DcEvent event) {
switch (event.getId()) {
case DcContext.DC_EVENT_OUTGOING_CALL_ACCEPTED:
if (event.getData1Int() == callId) {
try {
String base64 = Base64.encodeToString(event.getData2Str().getBytes(StandardCharsets.UTF_8), Base64.NO_WRAP);
String hash = "#onAnswer=" + URLEncoder.encode(base64, "UTF-8");
webView.evaluateJavascript("window.location.hash = `"+hash+"`", null);
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "Error", e);
}
}
break;
case DcContext.DC_EVENT_CALL_ENDED:
if (event.getData1Int() == callId) {
ended = true;
finish();
}
break;
}
}
class InternalJSApi {
@JavascriptInterface
public String getIceServers() {
try {
return rpc.iceServers(accId);
} catch (RpcException e) {
Log.e(TAG, "Error", e);
return null;
}
}
@JavascriptInterface
public void startCall(String payload) {
try {
callId = rpc.placeOutgoingCall(accId, chatId, payload);
} catch (RpcException e) {
Log.e(TAG, "Error", e);
}
}
@JavascriptInterface
public void acceptCall(String payload) {
try {
rpc.acceptIncomingCall(accId, callId, payload);
} catch (RpcException e) {
Log.e(TAG, "Error", e);
}
}
@JavascriptInterface
public void endCall() {
finish();
}
@JavascriptInterface
public String getAvatar() {
final Context context = CallActivity.this;
final DcChat dcChat = dcContext.getChat(chatId);
if (!TextUtils.isEmpty(dcChat.getProfileImage())) {
return AvatarUtil.asDataUri(dcChat.getProfileImage());
} else {
final Recipient recipient = new Recipient(context, dcChat);
return AvatarUtil.asDataUri(recipient.getFallbackAvatarDrawable(context, false));
}
}
}
}
@@ -0,0 +1,60 @@
package org.thoughtcrime.securesms.calls;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.util.Base64;
import android.util.Log;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.permissions.Permissions;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class CallUtil {
private static final String TAG = CallUtil.class.getSimpleName();
public static void startCall(Activity activity, int chatId) {
Permissions.with(activity)
.request(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO)
.ifNecessary()
.withPermanentDenialDialog(activity.getString(R.string.perm_explain_access_to_camera_denied))
.onAllGranted(() -> {
int accId = DcHelper.getContext(activity).getAccountId();
startCall(activity, accId, chatId);
})
.execute();
}
public static void startCall(Context context, int accId, int chatId) {
Intent intent = new Intent(context, CallActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.putExtra(CallActivity.EXTRA_ACCOUNT_ID, accId);
intent.putExtra(CallActivity.EXTRA_CHAT_ID, chatId);
intent.putExtra(CallActivity.EXTRA_HASH, "#startCall");
context.startActivity(intent);
}
public static void openCall(Context context, int accId, int chatId, int callId, String payload) {
String base64 = Base64.encodeToString(payload.getBytes(StandardCharsets.UTF_8), Base64.NO_WRAP);
String hash = "";
try {
hash = "#offerIncomingCall=" + URLEncoder.encode(base64, "UTF-8");
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "Error", e);
}
Intent intent = new Intent(context, CallActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.putExtra(CallActivity.EXTRA_ACCOUNT_ID, accId);
intent.putExtra(CallActivity.EXTRA_CHAT_ID, chatId);
intent.putExtra(CallActivity.EXTRA_CALL_ID, callId);
intent.putExtra(CallActivity.EXTRA_HASH, hash);
context.startActivity(intent);
}
}
@@ -35,19 +35,17 @@ public class AttachmentTypeSelector extends PopupWindow {
public static final int ADD_GALLERY = 1;
public static final int ADD_DOCUMENT = 2;
public static final int INVITE_VIDEO_CHAT = 3;
public static final int ADD_CONTACT_INFO = 4;
public static final int TAKE_PHOTO = 5;
public static final int ADD_LOCATION = 6;
public static final int RECORD_VIDEO = 7;
public static final int ADD_WEBXDC = 8;
public static final int ADD_CONTACT_INFO = 3;
public static final int TAKE_PHOTO = 4;
public static final int ADD_LOCATION = 5;
public static final int RECORD_VIDEO = 6;
public static final int ADD_WEBXDC = 7;
private static final int ANIMATION_DURATION = 300;
private final @NonNull LoaderManager loaderManager;
private final @NonNull RecentPhotoViewRail recentRail;
private final @NonNull ImageView imageButton;
private final @NonNull ImageView videoChatButton;
private final @NonNull ImageView documentButton;
private final @NonNull ImageView contactButton;
//private final @NonNull ImageView cameraButton;
@@ -70,7 +68,6 @@ public class AttachmentTypeSelector extends PopupWindow {
this.chatId = chatId;
this.recentRail = ViewUtil.findById(layout, R.id.recent_photos);
this.imageButton = ViewUtil.findById(layout, R.id.gallery_button);
this.videoChatButton = ViewUtil.findById(layout, R.id.invite_video_chat_button);
this.documentButton = ViewUtil.findById(layout, R.id.document_button);
this.contactButton = ViewUtil.findById(layout, R.id.contact_button);
//this.cameraButton = ViewUtil.findById(layout, R.id.camera_button);
@@ -79,7 +76,6 @@ public class AttachmentTypeSelector extends PopupWindow {
this.webxdcButton = ViewUtil.findById(layout, R.id.webxdc_button);
this.imageButton.setOnClickListener(new PropagatingClickListener(ADD_GALLERY));
this.videoChatButton.setOnClickListener(new PropagatingClickListener(INVITE_VIDEO_CHAT));
this.documentButton.setOnClickListener(new PropagatingClickListener(ADD_DOCUMENT));
this.contactButton.setOnClickListener(new PropagatingClickListener(ADD_CONTACT_INFO));
//this.cameraButton.setOnClickListener(new PropagatingClickListener(TAKE_PHOTO));
@@ -137,7 +133,6 @@ public class AttachmentTypeSelector extends PopupWindow {
animateButtonIn(locationButton, ANIMATION_DURATION / 4);
animateButtonIn(documentButton, ANIMATION_DURATION / 4);
animateButtonIn(webxdcButton, 0);
animateButtonIn(videoChatButton, 0);
}
@Override
@@ -0,0 +1,103 @@
package org.thoughtcrime.securesms.components;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import org.thoughtcrime.securesms.R;
import chat.delta.rpc.types.CallInfo;
import chat.delta.rpc.types.CallState;
public class CallItemView extends FrameLayout {
private static final String TAG = CallItemView.class.getSimpleName();
private final @NonNull ImageView icon;
private final @NonNull TextView title;
private final @NonNull ConversationItemFooter footer;
private CallInfo callInfo;
private CallClickListener viewListener;
public CallItemView(Context context) {
this(context, null);
}
public CallItemView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CallItemView(final Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
inflate(context, R.layout.call_item_view, this);
this.icon = findViewById(R.id.call_icon);
this.title = findViewById(R.id.title);
this.footer = findViewById(R.id.footer);
setOnClickListener(v -> {
if (viewListener != null && callInfo != null) {
viewListener.onClick(v, callInfo);
}
});
}
public void setCallClickListener(CallClickListener listener) {
viewListener = listener;
}
public void setCallItem(boolean isOutgoing, CallInfo callInfo) {
this.callInfo = callInfo;
if (callInfo.state instanceof CallState.Completed) {
footer.setCallDuration(((CallState.Completed) callInfo.state).duration);
} else {
footer.setCallDuration(0); // reset
}
if (callInfo.state instanceof CallState.Missed) {
title.setText(R.string.missed_call);
} else if (callInfo.state instanceof CallState.Canceled) {
title.setText(R.string.canceled_call);
} else if (callInfo.state instanceof CallState.Declined) {
title.setText(R.string.declined_call);
} else {
title.setText(isOutgoing? R.string.outgoing_call : R.string.incoming_call);
}
int[] attrs;
if (isOutgoing) {
attrs = new int[]{
R.attr.conversation_item_outgoing_text_primary_color,
R.attr.conversation_item_outgoing_text_secondary_color,
};
} else {
attrs = new int[]{
R.attr.conversation_item_incoming_text_primary_color,
R.attr.conversation_item_incoming_text_secondary_color,
};
}
try (TypedArray ta = getContext().obtainStyledAttributes(attrs)) {
icon.setColorFilter(ta.getColor(0, Color.BLACK));
footer.setTextColor(ta.getColor(1, Color.BLACK));
}
}
public ConversationItemFooter getFooter() {
return footer;
}
public String getDescription() {
return title.getText() + "\n" + footer.getDescription();
}
public interface CallClickListener {
void onClick(View v, CallInfo callInfo);
}
}
@@ -26,6 +26,7 @@ public class ConversationItemFooter extends LinearLayout {
private ImageView locationIndicatorView;
private DeliveryStatusView deliveryStatusView;
private Integer textColor = null;
private int callDuration = 0;
public ConversationItemFooter(Context context) {
super(context);
@@ -54,12 +55,16 @@ public class ConversationItemFooter extends LinearLayout {
if (attrs != null) {
try (TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.ConversationItemFooter, 0, 0)) {
textColor = typedArray.getInt(R.styleable.ConversationItemFooter_footer_text_color, getResources().getColor(R.color.core_white));
setTextColor(textColor);
setTextColor(typedArray.getInt(R.styleable.ConversationItemFooter_footer_text_color, getResources().getColor(R.color.core_white)));
}
}
}
/* Call duration in seconds. Only >0 if this is a call message */
public void setCallDuration(int duration) {
callDuration = duration;
}
public void setMessageRecord(@NonNull DcMsg messageRecord) {
presentDate(messageRecord);
boolean bookmark = messageRecord.getOriginalMsgId() != 0 || messageRecord.getSavedMsgId() != 0;
@@ -77,7 +82,8 @@ public class ConversationItemFooter extends LinearLayout {
presentDeliveryStatus(messageRecord);
}
private void setTextColor(int color) {
public void setTextColor(int color) {
textColor = color;
dateView.setTextColor(color);
editedView.setTextColor(color);
bookmarkIndicatorView.setColorFilter(color);
@@ -86,18 +92,29 @@ public class ConversationItemFooter extends LinearLayout {
deliveryStatusView.setTint(color);
}
private void presentDate(@NonNull DcMsg messageRecord) {
private void presentDate(@NonNull DcMsg dcMsg) {
dateView.forceLayout();
dateView.setText(DateUtils.getExtendedRelativeTimeSpanString(getContext(), messageRecord.getTimestamp()));
Context context = getContext();
String date = dcMsg.getType() == DcMsg.DC_MSG_CALL?
DateUtils.getExtendedTimeSpanString(context, dcMsg.getTimestamp())
: DateUtils.getExtendedRelativeTimeSpanString(context, dcMsg.getTimestamp());
if (callDuration > 0) {
String duration = DateUtils.getFormattedCallDuration(context, callDuration);
dateView.setText(context.getString(R.string.call_date_and_duration, date, duration));
} else {
dateView.setText(date);
}
}
private void presentDeliveryStatus(@NonNull DcMsg messageRecord) {
// isDownloading is temporary and should be checked first.
boolean isDownloading = messageRecord.getDownloadState() == DcMsg.DC_DOWNLOAD_IN_PROGRESS;
boolean isCall = messageRecord.getType() == DcMsg.DC_MSG_CALL;
if (isDownloading) deliveryStatusView.setDownloading();
else if (messageRecord.isPending()) deliveryStatusView.setPending();
else if (messageRecord.isFailed()) deliveryStatusView.setFailed();
else if (!messageRecord.isOutgoing()) deliveryStatusView.setNone();
else if (!messageRecord.isOutgoing() || isCall) deliveryStatusView.setNone();
else if (messageRecord.isRemoteRead()) deliveryStatusView.setRead();
else if (messageRecord.isDelivered()) deliveryStatusView.setSent();
else if (messageRecord.isPreparing()) deliveryStatusView.setPreparing();
@@ -16,8 +16,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import com.b44t.messenger.util.concurrent.ListenableFuture;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.database.AttachmentDatabase;
import org.thoughtcrime.securesms.mms.GlideRequests;
@@ -28,6 +26,8 @@ import org.thoughtcrime.securesms.util.Util;
import java.util.concurrent.ExecutionException;
import chat.delta.util.ListenableFuture;
public class ConversationItemThumbnail extends FrameLayout {
private static final Paint LIGHT_THEME_OUTLINE_PAINT = new Paint();
@@ -5,9 +5,10 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.widget.ImageView;
import com.b44t.messenger.util.concurrent.SettableFuture;
import com.bumptech.glide.request.target.DrawableImageViewTarget;
import chat.delta.util.SettableFuture;
public class GlideDrawableListeningTarget extends DrawableImageViewTarget {
private final SettableFuture<Boolean> loaded;
@@ -23,8 +23,6 @@ import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.b44t.messenger.DcMsg;
import com.b44t.messenger.util.concurrent.ListenableFuture;
import com.b44t.messenger.util.concurrent.SettableFuture;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.animation.AnimationCompleteListener;
@@ -42,6 +40,9 @@ import org.thoughtcrime.securesms.util.guava.Optional;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import chat.delta.util.ListenableFuture;
import chat.delta.util.SettableFuture;
public class InputPanel extends ConstraintLayout
implements MicrophoneRecorderView.Listener,
KeyboardAwareLinearLayout.OnKeyboardShownListener,
@@ -17,11 +17,8 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.annimon.stream.Stream;
import com.b44t.messenger.DcContact;
import com.b44t.messenger.DcMsg;
import com.b44t.messenger.rpc.RpcException;
import com.b44t.messenger.rpc.VcardContact;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import org.json.JSONObject;
@@ -42,6 +39,9 @@ import org.thoughtcrime.securesms.util.Util;
import java.util.List;
import chat.delta.rpc.RpcException;
import chat.delta.rpc.types.VcardContact;
public class QuoteView extends FrameLayout implements RecipientForeverObserver {
private static final String TAG = QuoteView.class.getSimpleName();
@@ -197,18 +197,17 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
}
private void setQuoteAttachment(@NonNull GlideRequests glideRequests, @NonNull SlideDeck slideDeck) {
List<Slide> thumbnailSlides = Stream.of(slideDeck.getSlides()).filter(s -> s.hasImage() || s.hasVideo() || s.hasSticker() || s.isWebxdcDocument() || s.isVcard()).limit(1).toList();
List<Slide> audioSlides = Stream.of(slideDeck.getSlides()).filter(s -> s.hasAudio()).limit(1).toList();
List<Slide> documentSlides = Stream.of(attachments.getSlides()).filter(Slide::hasDocument).limit(1).toList();
List<Slide> slides = slideDeck.getSlides();
Slide slide = slides.isEmpty()? null : slides.get(0);
attachmentVideoOverlayView.setVisibility(GONE);
if (!thumbnailSlides.isEmpty() && thumbnailSlides.get(0).getUri() != null) {
if (slide != null && slide.hasQuoteThumbnail()) {
thumbnailView.setVisibility(VISIBLE);
attachmentContainerView.setVisibility(GONE);
dismissView.setBackgroundResource(R.drawable.dismiss_background);
if (thumbnailSlides.get(0).isWebxdcDocument()) {
if (slide.isWebxdcDocument()) {
try {
JSONObject info = quotedMsg.getWebxdcInfo();
byte[] blob = quotedMsg.getWebxdcBlob(info.getString("icon"));
@@ -221,7 +220,7 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
Log.e(TAG, "failed to get webxdc icon", e);
thumbnailView.setVisibility(GONE);
}
} else if (thumbnailSlides.get(0).isVcard()) {
} else if (slide.isVcard()) {
try {
VcardContact vcardContact = DcHelper.getRpc(getContext()).parseVcard(quotedMsg.getFile()).get(0);
Recipient recipient = new Recipient(getContext(), vcardContact);
@@ -236,22 +235,24 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
thumbnailView.setVisibility(GONE);
}
} else {
Uri thumbnailUri = thumbnailSlides.get(0).getUri();
if (thumbnailSlides.get(0).hasVideo()) {
Uri thumbnailUri = slide.getUri();
if (slide.hasVideo()) {
attachmentVideoOverlayView.setVisibility(VISIBLE);
MediaUtil.createVideoThumbnailIfNeeded(getContext(), thumbnailSlides.get(0).getUri(), thumbnailSlides.get(0).getThumbnailUri(), null);
thumbnailUri = thumbnailSlides.get(0).getThumbnailUri();
MediaUtil.createVideoThumbnailIfNeeded(getContext(), slide.getUri(), slide.getThumbnailUri(), null);
thumbnailUri = slide.getThumbnailUri();
}
if (thumbnailUri != null) {
glideRequests.load(new DecryptableUri(thumbnailUri))
.centerCrop()
.override(getContext().getResources().getDimensionPixelSize(R.dimen.quote_thumb_size))
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.into(thumbnailView);
}
glideRequests.load(new DecryptableUri(thumbnailUri))
.centerCrop()
.override(getContext().getResources().getDimensionPixelSize(R.dimen.quote_thumb_size))
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.into(thumbnailView);
}
} else if(!audioSlides.isEmpty()) {
} else if(slide != null && slide.hasAudio()) {
thumbnailView.setVisibility(GONE);
attachmentContainerView.setVisibility(GONE);
} else if (!documentSlides.isEmpty()) {
} else if (slide != null && slide.hasDocument()) {
thumbnailView.setVisibility(GONE);
attachmentContainerView.setVisibility(VISIBLE);
} else {
@@ -14,8 +14,6 @@ import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.UiThread;
import com.b44t.messenger.util.concurrent.ListenableFuture;
import com.b44t.messenger.util.concurrent.SettableFuture;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import org.thoughtcrime.securesms.R;
@@ -32,6 +30,9 @@ import java.util.Locale;
import static com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions.withCrossFade;
import chat.delta.util.ListenableFuture;
import chat.delta.util.SettableFuture;
public class ThumbnailView extends FrameLayout {
private static final String TAG = ThumbnailView.class.getSimpleName();
@@ -9,16 +9,16 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.b44t.messenger.rpc.Rpc;
import com.b44t.messenger.rpc.RpcException;
import com.b44t.messenger.rpc.VcardContact;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.mms.SlideClickListener;
import org.thoughtcrime.securesms.mms.VcardSlide;
import org.thoughtcrime.securesms.recipients.Recipient;
import chat.delta.rpc.Rpc;
import chat.delta.rpc.RpcException;
import chat.delta.rpc.types.VcardContact;
public class VcardView extends FrameLayout {
private static final String TAG = VcardView.class.getSimpleName();
@@ -60,8 +60,8 @@ public class VcardView extends FrameLayout {
public void setVcard(@NonNull GlideRequests glideRequests, final @NonNull VcardSlide slide, final @NonNull Rpc rpc) {
try {
VcardContact vcardContact = rpc.parseVcard(slide.asAttachment().getRealPath(getContext())).get(0);
name.setText(vcardContact.getDisplayName());
address.setText(vcardContact.getAddr());
name.setText(vcardContact.displayName);
address.setText(vcardContact.addr);
avatar.setAvatar(glideRequests, new Recipient(getContext(), vcardContact), false);
this.slide = slide;
} catch (RpcException e) {
@@ -109,18 +109,9 @@ public class DozeReminder {
}
}
private static boolean isAllChatmail() {
for (int accountId : ApplicationContext.dcAccounts.getAll()) {
DcContext context = ApplicationContext.dcAccounts.getAccount(accountId);
if (!context.isChatmail()) {
return false;
}
}
return true;
}
private static boolean isPushAvailableAndSufficient() {
return isAllChatmail() && FcmReceiveService.getToken() != null;
return ApplicationContext.dcAccounts.isAllChatmail()
&& FcmReceiveService.getToken() != null;
}
public static void maybeAskDirectly(Context context) {

Some files were not shown because too many files have changed in this diff Show More