Compare commits

...

340 Commits

Author SHA1 Message Date
adbenitez e1c92712a0 Merge remote-tracking branch 'upstream/main' 2025-02-04 16:18:00 +01:00
adb 6ec0f1bfce Merge pull request #3580 from deltachat/adb/issue-3566
align avatar to message bubble instead of parent bottom
2025-02-03 23:41:12 +01:00
adbenitez db410d8b44 align avatar to message bubble instead of parent bottom 2025-02-03 23:08:32 +01:00
B. Petersen cd07f3de96 update translations 2025-02-03 11:58:06 +01:00
B. Petersen 12072a0342 'exiting' may be misleading as others can create new groups with blocked contacts. try to clarify that aspect 2025-02-03 11:51:58 +01:00
B. Petersen c6f3761bb9 simplify unblock wording, it is somehow clear it is the opposite, other apps do not even clarify one way 2025-02-03 11:51:58 +01:00
B. Petersen 673f0e78b1 be more clear about the impact of blocked contacts 2025-02-03 11:51:58 +01:00
B. Petersen 65c8960ec8 update translations 2025-02-03 11:45:19 +01:00
adb 089ecc67d1 Merge pull request #3576 from deltachat/r10s/empty-apps-wording
tweak wording in empty "all apps" and "all files" views
2025-02-03 00:49:01 +01:00
B. Petersen 0f84af5b32 adapt empty-hint also for 'files' 2025-02-02 18:52:31 +01:00
B. Petersen 710ed6dd56 in 'All Apps' tap, do not say 'Media will be shared here', but 'Apps will be shown here' 2025-02-02 18:37:49 +01:00
adb 335aabd4ff Merge pull request #3570 from deltachat/adb/update-changelog-31/1/25
update changelog header for v1.52.1
2025-02-01 00:24:47 +01:00
adbenitez 98c97a8aed update changelog header for v1.52.1 2025-01-31 22:24:44 +01:00
adbenitez 23d18d2ac5 Merge remote-tracking branch 'upstream/main' 2025-01-31 21:28:47 +01:00
adbenitez a136b8b1e5 update version 2025-01-31 21:28:08 +01:00
adbenitez 7f8b71cf28 tweak attachment selector layout temporarily 2025-01-31 21:27:19 +01:00
adbenitez 9e5f2b18b9 update .github/FUNDING.yml 2025-01-31 19:50:37 +01:00
adbenitez bdfeddecd5 add "get it on google play" 2025-01-31 14:19:32 +01:00
B. Petersen 23cbe63cd4 update translations 2025-01-31 12:37:57 +01:00
B. Petersen f0f53455a5 do not deprecate string for smoother adaption of other OS 2025-01-31 12:26:09 +01:00
B. Petersen d8b49f57a9 always colorize 'Reset' as destructive-red 2025-01-31 12:26:09 +01:00
B. Petersen 7eaaf3bbb4 refine QR reset wording 2025-01-31 12:26:09 +01:00
adbenitez d4f83cd38b Merge remote-tracking branch 'upstream/main' 2025-01-30 02:03:47 +01:00
adbenitez 9eca5f518e disable location streaming for now 2025-01-30 02:02:42 +01:00
B. Petersen d17bed02e6 update translations 2025-01-29 14:47:03 +01:00
B. Petersen b4b194a59b add app-picker-strings needed for iOS 2025-01-29 14:47:03 +01:00
adb c6f62a2b81 Merge pull request #3565 from deltachat/prep-1.52.1
Prep 1.52.1
2025-01-28 17:24:22 +01:00
adbenitez e3a9f42a56 update changelog 2025-01-28 17:23:56 +01:00
adb 323bcef1fe Update CHANGELOG.md
Co-authored-by: Hocuri <hocuri@gmx.de>
2025-01-28 17:13:54 +01:00
adbenitez 095b92b498 bump version number 2025-01-28 16:50:46 +01:00
adbenitez 18c2ccd66c update changelog 2025-01-28 16:36:39 +01:00
adb 28fdeac01c Merge pull request #3564 from deltachat/update-core-and-stuff-28/1/25
Update translations and core to 1.155.1
2025-01-28 16:31:11 +01:00
adbenitez a7e4267b9b update translations 2025-01-28 16:28:24 +01:00
adbenitez d6837aa121 update deltachat-core-rust to 'chore(release): prepare for 1.155.1' of 'v1.155.1' 2025-01-28 16:25:23 +01:00
adbenitez 5a2913b36f delete unused file 2025-01-28 02:37:25 +01:00
adbenitez 20180fa89c Merge remote-tracking branch 'upstream/main' 2025-01-27 22:06:04 +01:00
Hocuri c6b89055d8 File deduplication, Android part (#3513) 2025-01-27 18:40:44 +01:00
adb bfda7ab2c3 Merge pull request #3562 from deltachat/adb/remove-android-crop-dep
remove unused com.soundcloud.android:android-crop dependency
2025-01-27 18:13:04 +01:00
adb 953ce32bea Merge branch 'main' into adb/remove-android-crop-dep 2025-01-27 17:40:34 +01:00
adbenitez 961fa5ffe6 remove unused com.soundcloud.android:android-crop dependency 2025-01-27 17:37:14 +01:00
adbenitez b1b2959bcb add .github/FUNDING.yml 2025-01-26 05:23:27 +01:00
link2xt 70ef715dc6 build(nix): update build tools from 33.0.1 to 34.0.0 2025-01-25 13:48:41 +00:00
adbenitez ffa58aae34 update bots index 2025-01-24 22:09:54 +01:00
adbenitez 24f5209c03 always create protected groups 2025-01-24 20:34:49 +01:00
adbenitez 7fd96732d6 Merge remote-tracking branch 'upstream/main' 2025-01-24 20:27:40 +01:00
adb 6e0759f719 Merge pull request #3560 from deltachat/prep-1.52.0
prepare 1.52.0
2025-01-23 23:37:01 +01:00
adbenitez 63434e1e2f prepare 1.52.0 2025-01-23 20:03:59 +01:00
adb 9c17bc412a Merge pull request #3559 from deltachat/update-core-and-stuff-23/1/25
Update core and stuff 23/1/25
2025-01-23 19:21:15 +01:00
adb d40144d50c Merge branch 'main' into update-core-and-stuff-23/1/25 2025-01-23 19:19:43 +01:00
adbenitez 131c0f5a37 update strings 2025-01-23 19:17:18 +01:00
adbenitez 7086314d8b update deltachat-core-rust to 'chore(release): prepare for 1.155.0' of 'v1.155.0' 2025-01-23 19:11:11 +01:00
adb d75b2c2bb7 Merge pull request #3558 from deltachat/adb/issue-3557
pass account ID in chat shortcuts and properly switch to account
2025-01-23 13:23:00 +01:00
adbenitez c46d174869 update strings 2025-01-23 05:37:55 +01:00
adbenitez 17e03f2903 update buid.gradle 2025-01-23 04:38:58 +01:00
adbenitez 2c12a34051 improve instant onboarding 2025-01-23 04:33:23 +01:00
adbenitez 2d3dde2101 pass account ID in chat shortcuts and properly switch to account 2025-01-23 03:45:57 +01:00
adbenitez d539f5ecf2 Merge remote-tracking branch 'upstream/main' 2025-01-23 02:45:56 +01:00
adbenitez b17d6be4fc update build.gradle 2025-01-23 00:52:48 +01:00
B. Petersen 3c737f2360 streamline help menu
- use clear "Delta Chat Homepage" for opening our homepage
  (instead of unclear "Learn more about Delta Chat",
  which is esp. weird, when used from inside the help)

- do not "promote" GitHub in our menu entry,
  instead of "Contribute on GitHub", just say "Contribute".
  destination URL is our contribute page then -
  that is also more useful for ppl doing eg. translations
2025-01-23 00:51:06 +01:00
adb 9ac5e714b8 Merge pull request #3555 from deltachat/adb/update-deps-22/1/25
update some dependencies
2025-01-22 13:40:08 +01:00
adbenitez 94defa3091 update some dependencies 2025-01-22 01:43:21 +01:00
adbenitez 052ada221e update some deps 2025-01-22 01:42:21 +01:00
adbenitez 1d5e4cf2a9 update README 2025-01-22 00:54:00 +01:00
adbenitez c46aef3ea0 Merge remote-tracking branch 'upstream/main' 2025-01-22 00:52:57 +01:00
adb d30e141693 Merge pull request #3554 from deltachat/adb/issue-3542
avoid crash in MediaPreviewActivity.onPageUnselected
2025-01-21 20:09:51 +01:00
adb 305940396e Merge branch 'main' into adb/issue-3542 2025-01-21 19:39:33 +01:00
adbenitez 2ab567a9d3 use Log instead of stack trace 2025-01-21 19:38:43 +01:00
adb a9c488ff03 Merge pull request #3365 from deltachat/adb/issue-3361
revert #3177
2025-01-21 19:01:18 +01:00
adbenitez 8817b50c95 avoid crash in MediaPreviewActivity.onPageUnselected 2025-01-21 18:56:59 +01:00
adb 84c3710a35 Merge pull request #3553 from deltachat/adb/issue-3550
avoid ANR in ConversationFragment.manageMessageSeenState()
2025-01-21 18:51:00 +01:00
adbenitez be7be9bba4 avoid ANR in ConversationFragment.manageMessageSeenState() 2025-01-21 18:13:54 +01:00
adb b50ae284fb Merge pull request #3551 from deltachat/adb/issue-3549
fix: make animated webp animated again
2025-01-21 17:38:52 +01:00
adbenitez 97716d5c26 fix: make animated webp animated again 2025-01-21 16:57:03 +01:00
bjoern e77253c843 update translations (#3548)
* add string 'Unsave'

* pull translations
2025-01-20 15:14:54 +01:00
adbenitez 6aed8d003f deprecate string 2025-01-18 20:53:56 +01:00
adbenitez 0083e60c49 revert #3177 2025-01-18 20:53:56 +01:00
adbenitez 0fc79fd845 Merge remote-tracking branch 'upstream/main' 2025-01-18 20:39:03 +01:00
B. Petersen a7c3bc7ac5 add missing desktop strings 2025-01-17 17:40:35 +01:00
B. Petersen 83b16e5f4b do not force ppl to create blank issues
see https://github.com/deltachat/deltachat-ios/pull/2525
for screenshots and reasoning
2025-01-17 10:39:10 +01:00
adbenitez ee17c6d75e Merge remote-tracking branch 'upstream/main' 2025-01-16 21:10:25 +01:00
adb c0525ac69c Merge pull request #3544 from deltachat/adb/issue-3543
avoid null in attachment filename
2025-01-16 20:42:41 +01:00
adbenitez e9d2a39098 avoid null in attachment filename 2025-01-16 20:03:43 +01:00
adb 4d6fd16767 Merge pull request #3541 from deltachat/adb/issue-3540
avoid race condition in onPlayerStateChanged inside AudioSlidePlayer.requestDuration
2025-01-16 14:55:07 +01:00
adb b398870823 Merge pull request #3535 from deltachat/adb/issue-3534
fix IntentUtils.showBrowserIntent() and use it everywhere
2025-01-15 21:02:01 +01:00
adbenitez e68c50d614 avoid race condition in onPlayerStateChanged inside AudioSlidePlayer.requestDuration 2025-01-15 20:56:32 +01:00
adbenitez f6a27718a2 rename showBrowserIntent to showInBrowser 2025-01-15 20:33:16 +01:00
Hocuri f136fa3e3a Update the core submodule so that we can have nightlies again (#3539)
* Remove jsonrpc feature

* Update submodule to latest main
2025-01-15 16:18:43 +00:00
Hocuri 8e55a3dbf3 fix: Use getFilename() instead of the actual filename on disk (#3521)
* fix: Use msg.getFilename() instead of the file's name in some cases

* fix: Use msg.getFilename() instead of the file's name in initializeDraft()

* fix: Use msg.getFilename() instead of the file's name in MediaItem

* fix: Use the correct file name in MediaView

* refactor: `msg` param of `getManuallyCalculatedSlideInfo()` was always null

* Improve comment

* Revert "refactor: `msg` param of `getManuallyCalculatedSlideInfo()` was always null"

We will unfortunately need getManuallyCalculatedSlideInfo() with `msg`
param

This reverts commit 60e8248db32dc22812d3f23da194bab644802045.

* fix: Fix drafting images

This fixes a bug introduced in 14f69f87e8b11a7d0568e58593946a1f1c01e75e:
When you drafted an image, pressed Back, and opened the chat again, then
the height of the drafted image was wrong and tapping the image opened a
preview for the wrong image.

I do think that theoretically it would be nicer to use getSlideForMsg
here, because we already have a DcMsg, but this didn't work because a)
the width and height wasn't gotten from the msg and instead 0 was passed
and b) the code tries to save a msgId instead of the message instead,
and loading the message from the database fails later since it's just a
draft.

I didn't want to try and fix these things, because they might be bigger
refactorings and I don't know the code.

* fix: Use the original message's filemime if there is one

...instead of trying to guess the mimetype from the uri
2025-01-15 16:40:23 +01:00
B. Petersen 923227a0e8 update translations 2025-01-14 11:49:07 +01:00
adbenitez 14ecafe0e2 fix IntentUtils.showBrowserIntent() and use it everywhere 2025-01-11 19:45:37 +01:00
adb b93f8323ab Merge pull request #3532 from deltachat/prep-1.50.5
prepare 1.50.5 release
2025-01-10 19:37:38 +01:00
adbenitez 77f43cde9a prepare 1.50.5 release 2025-01-10 18:48:53 +01:00
adb e4d018393d Merge pull request #3531 from deltachat/adb/update-translations-10/01/25
update translations
2025-01-10 18:44:58 +01:00
adbenitez 9a816090de Merge remote-tracking branch 'upstream/main' 2025-01-10 18:44:47 +01:00
adbenitez 4b04aa65be update translations 2025-01-10 18:42:31 +01:00
B. Petersen 489bb55788 detach Android and iOS releases 2025-01-10 17:26:16 +01:00
adb 9d244611bc Merge pull request #3526 from deltachat/adb/issue-3525
use synchronized block to avoid IllegalMonitorStateException
2025-01-10 16:06:13 +01:00
Hocuri 3533916149 Put the synchronized around the whole while loop 2025-01-10 11:05:44 +01:00
adbenitez 46bc3e7f72 Merge remote-tracking branch 'upstream/main' 2025-01-10 01:36:50 +01:00
adbenitez ed0f0107e3 update to new gplay app id and key 2025-01-10 01:31:42 +01:00
adbenitez a855d7043a fix FetchForegroundService 2025-01-10 00:49:30 +01:00
adbenitez 66fd795763 try to fix CI 2025-01-09 19:06:15 +01:00
B. Petersen 05da43484f remove deprecated strings 2025-01-09 19:03:21 +01:00
adbenitez a58de2278b use synchronized block to avoid IllegalMonitorStateException 2025-01-09 18:36:12 +01:00
adbenitez 6743df23e9 update google-services.json 2025-01-09 18:01:16 +01:00
bjoern 35ec0d05e2 update translations (#3524)
* add new iOS notification strings

* update translations
2025-01-09 16:08:18 +01:00
bjoern 6ead7207ec update translations (#3522)
* update translations

* add new iOS widget strings

* add hints for terms 'Shortcut' and 'Widget'

* update translations
2025-01-09 15:26:42 +01:00
adbenitez 0d5223036d Merge remote-tracking branch 'upstream/main' 2025-01-07 16:36:45 +01:00
adbenitez 640fc433b8 add gdpr.md 2025-01-07 16:29:03 +01:00
adbenitez 35d814c3f6 update build.gradle 2025-01-06 21:26:22 +01:00
adbenitez f8b9d2b0d9 update core 2025-01-06 20:50:30 +01:00
adb 3390b865e0 Merge pull request #3519 from deltachat/prep-1.50.4
Prep 1.50.4
2025-01-06 15:40:55 +01:00
adbenitez 883486da9c tweak changelog 2025-01-06 15:26:49 +01:00
adbenitez d048203f45 update version number 2025-01-06 15:19:17 +01:00
adbenitez f9d70d1196 update changelog 2025-01-06 15:18:54 +01:00
adb 4413b7b4fb Merge pull request #3518 from deltachat/update-core-and-stuff-6/1/25
Update translations and core to v1.153.0
2025-01-06 14:58:14 +01:00
adbenitez 7a4f263a62 update translations 2025-01-06 14:55:55 +01:00
adbenitez 1a360d5282 update deltachat-core-rust to 'chore(release): prepare for 1.153.0' of 'v1.153.0' 2025-01-06 14:16:09 +01:00
Hocuri dc785fc116 fix: Remove long stacktrace that flooded the logcat (#3512)
Everytime I attached an image, I got a super long stacktrace in the
logcat. I found it to be [this problem](https://stackoverflow.com/questions/71746801/getting-failed-to-inflate-colorstatelist-leaving-it-to-the-framework-when-usi)
and applied the fix described there.
2025-01-04 19:13:45 +01:00
adbenitez 009593f7cc remove dead code 2025-01-04 16:06:40 +01:00
adb 884be3a93e Merge pull request #3516 from deltachat/adb/avoid-npe-in-reactions
avoid NullPointerException when using result of Rpc.getMsgReactions
2025-01-04 16:02:49 +01:00
adbenitez 9a25328787 avoid NullPointerException when using result of Rpc.getMsgReactions 2025-01-04 12:50:25 +01:00
adbenitez 2d8ec490b1 Merge remote-tracking branch 'upstream/main' 2025-01-04 12:21:28 +01:00
B. Petersen 3b19ca99e1 simpler copyright, it is anyways questionable by law, it is just a hint, that there is 'sth', this will do also without year 2025-01-03 19:58:55 +01:00
B. Petersen f751a48568 update local help 2025-01-03 16:48:52 +01:00
B. Petersen 4549989a63 update translations 2025-01-03 16:48:52 +01:00
B. Petersen 19e2c4e051 add info string that is shown by iOS system when asking for accessing Face ID 2025-01-03 15:03:54 +01:00
adbenitez 6f5e90be53 update build.gradle 2024-12-21 03:11:47 +01:00
adbenitez 34fa0620ab update full_description 2024-12-21 03:04:53 +01:00
adbenitez fe37af1a3f allow to jump to POI 2024-12-21 02:54:54 +01:00
adbenitez 3459802d67 update core 2024-12-20 19:52:40 +01:00
adbenitez b8bf847941 fix contact selection list 2024-12-20 19:51:59 +01:00
adbenitez 5b6024584a force sending sticker 2024-12-20 17:47:45 +01:00
adb 4833a44542 Merge pull request #3509 from deltachat/adb/issue-3488
try to avoid FILL500 getting stuck in some devices
2024-12-20 12:40:59 +01:00
adbenitez eb93e2bb7e add comment 2024-12-19 16:39:52 +01:00
adbenitez 291700dfc7 update lastOpenTime in onDestroy() 2024-12-19 16:30:58 +01:00
adbenitez 7a4913b394 tweak code 2024-12-19 15:52:16 +01:00
adbenitez 0dae71f4b7 try to avoid FILL500 getting stuck in some devices 2024-12-19 15:48:57 +01:00
Hocuri 08e4229533 Make the attachment background the same as the input bar background (#3477)
* Make the attachment background the same as the input bar background

Two different users recently complained that they find drafting images confusing. One of them thought that they had already sent it, the other one didn't know how to send it (both of them figured it out after ~10s, but still, it's nicer to avoid such confusion). In both cases, the problem was that the background of the attached file is the same as the chat background, not the same as the input bar, even though the attached file belongs to the input bar and not to the chat.

* Add a stroke around the to-be attachment
2024-12-19 13:30:24 +01:00
adbenitez 101a31628d lowercase Bot string for English and Spanish 2024-12-18 19:34:29 +01:00
adbenitez 2a2ce883b4 Merge remote-tracking branch 'upstream/main' 2024-12-18 19:33:04 +01:00
adbenitez 5a0e26bdb5 show last-seen status in contact list 2024-12-18 19:20:34 +01:00
B. Petersen 0c9277dfd0 remove email-address unconditionally from title
the email-address was removed for guaranteed-e2ee chats quite a while ago
(https://github.com/deltachat/deltachat-android/pull/2916) reason was, among others,
that these addresses are often chatmail and therefore random.
(despite expecting otherwise, that was fine for most users).

this PR removes the email-adress unconditionally:

- having the email-address sometimes shown and sometimes not is confusing,
  and easily looks like a bug.
  this has become worse with the added vcard-support
  (before, there were rare non-guaranteed chats in chatmail) -
  resulting in more random addresses being shown

- _always_ protect against over-the-shoulder attacks

- better privacy in screenshots sent around without thinking much before
  (cmp. https://github.com/deltachat/deltachat-ios/pull/2329)

- wrt impersonation attacks:
  the pure email address in the subtitle did never protect against impersonation,
  one could always get sth. trustworthy looking there,
  it is better to check the profile with additional information (eg. other chats) if in doubt

- general cleaner, uncluttered layout

- pave the way of the upcoming multi-addresses

drawback is that sometimes one more tap is needed to access the email-address -
however, as it is _always_ one tap away now,
this can also go easily to the finger memory.
2024-12-18 18:31:43 +01:00
adb 37886cf296 Merge pull request #3506 from deltachat/adb/issue-3502
run SendRelayedMessageUtil.sendMultipleMsgs() in background
2024-12-18 17:19:34 +01:00
adbenitez df5ba2eced call SendRelayedMessageUtil.sendMultipleMsgs() in background 2024-12-18 17:17:46 +01:00
adbenitez 3c2ddb96b3 update full_description 2024-12-18 16:04:30 +01:00
Hocuri e2a825dfb2 fix(ANR): Mark messages as seen asynchronously (#3505)
Mark messages as seen in a background thread instead of on the UI
thread in order to fix #3504.
2024-12-18 15:41:44 +01:00
Hocuri 8d49c7e595 fix: Fetch synchronously in the background if no foreground service is allowed (#3501)
Fix #3500.
2024-12-18 13:19:47 +01:00
B. Petersen 966d5dac24 do not lowercase string 'Bot'
it is regarded as a bug
and esp. weird in translations.

it was regarded to be a bit 'nerdy' that time to write it lowercase,
but it seems we have to get more serious now.
2024-12-17 17:43:21 +01:00
adb 7f684f4d2e Merge pull request #3499 from deltachat/adb/issue-3498
avoid IllegalArgumentException dismissing dialog
2024-12-17 17:07:03 +01:00
adb 1510f7f3a8 Merge pull request #3497 from deltachat/adb/issue-3496
avoid NPE in ConversationListActivity.onNewIntent()
2024-12-17 16:32:45 +01:00
adbenitez 6916becf7f avoid IllegalArgumentException dismissing dialog 2024-12-17 16:13:37 +01:00
adbenitez ad5b496f5c avoid NPE in ConversationListActivity.onNewIntent() 2024-12-17 15:00:25 +01:00
adb e647401db4 Merge pull request #3491 from deltachat/adb/issue-3490
improve emoji pickers
2024-12-17 14:47:43 +01:00
adbenitez 3113f9c3ab optimize onConfigurationChanged() 2024-12-16 17:19:34 +01:00
adbenitez a1e47865c5 improve emoji pickers 2024-12-16 15:27:13 +01:00
adbenitez 3a5f9b3fed update app name to avoid confusion in f-droid 2024-12-13 22:48:31 +01:00
adbenitez 5ffbc19d03 Merge remote-tracking branch 'upstream/main' 2024-12-13 22:42:20 +01:00
adb d9db4b818a Merge pull request #3487 from deltachat/prep-1.50.3
Prepare 1.50.3
2024-12-13 20:12:04 +01:00
adbenitez 693efdbd0f add back device message 2024-12-13 20:10:45 +01:00
adbenitez 399b783437 update changelog 2024-12-13 19:30:34 +01:00
adbenitez 4bc574dfbe change version name 2024-12-13 19:29:47 +01:00
adbenitez 294af0981d disable previous version's device message 2024-12-13 18:28:25 +01:00
adbenitez e8c7014993 update changelog 2024-12-13 18:27:25 +01:00
adbenitez 0edc8303c1 update version number 2024-12-13 14:21:20 +01:00
adb 8c89c3e225 Merge pull request #3484 from deltachat/adb/issue-3479
download .xdc files in background
2024-12-13 14:12:42 +01:00
adb a93c8ab055 Merge pull request #3485 from deltachat/adb/issue-3481
add missing webxdc api
2024-12-13 14:00:12 +01:00
adbenitez c5cb79d116 add missing webxdc api 2024-12-13 13:42:39 +01:00
adbenitez b3c50b9571 download .xdc files in background 2024-12-13 13:18:40 +01:00
adb 41579de502 Merge pull request #3483 from deltachat/update-core-and-stuff-13/12/24
Update core to 1.152.0
2024-12-13 12:50:54 +01:00
adbenitez e6f735b8bc update scripts/update-core.sh 2024-12-13 12:50:24 +01:00
adbenitez 70b6f2cdfa update strings 2024-12-13 12:36:09 +01:00
adbenitez c1e716d6a3 update deltachat-core-rust to 'chore(release): prepare for 1.152.0' of 'v1.152.0' 2024-12-13 12:36:09 +01:00
adb dde59b4673 Merge pull request #3482 from deltachat/link2xt/update-rust-1.83
Update Rust to 1.83.0
2024-12-13 12:33:51 +01:00
link2xt 9d77920adf build: update Rust to 1.83.0 2024-12-12 13:28:33 +00:00
link2xt 6f50ee0cfb build(nix): remove ndk-bundle 2024-12-12 13:28:33 +00:00
link2xt 4c86d6d49e chore: nix flake update 2024-12-12 12:47:08 +00:00
Hocuri 963327dd64 Remove prepareMsg (and OUT_PREPARING message state) (#3468)
This PR removes prepareMsg, which put messages into the OUT_PREPARING state and was used while videos were recoded. It also removes the now-unused method isIncreation().
- It was buggy because when you forwarded a message while it was InPreparation, or when the app was killed while a message is InPreparation, the message would stay InPreparation forever.
- Android is the only UI using this InPreparation (according to @r10s, I didn't check this myself), so we can simplify some things in core, which will also make it easier to deduplicate blob files.
2024-12-11 13:53:36 +01:00
adbenitez 5cba1ccd98 remove duplicate realtime preference 2024-12-09 11:57:51 +01:00
adbenitez de8e6b6852 remove store from main menu 2024-12-07 17:37:01 +01:00
adbenitez 811089f3b3 Merge remote-tracking branch 'upstream/main' 2024-12-07 17:11:55 +01:00
adbenitez e045a09d36 Merge remote-tracking branch 'upstream/main' 2024-12-07 17:10:18 +01:00
B. Petersen a3a6919b08 center attachment icons
this PR centers the icons in the attachment selector,
the right-aligned ones looks esp. odd when no experiments are enabled.

the default now looks good,
and when all experiments are enabled, things are perfect as well.
but even if only one experiment is enabled, things are better imo
(but we anyway should optimize for default and not for experimental options)
2024-12-07 16:59:33 +01:00
adbenitez cbee839a43 Merge remote-tracking branch 'upstream/main' 2024-12-07 14:29:12 +01:00
adb efdd92b6a1 Merge pull request #3463 from deltachat/adb/webxdc-picker
add webxdc picker
2024-12-07 14:19:27 +01:00
adb 75296e189a Merge pull request #3456 from deltachat/adb/improve-notifications
notify webxdc events, replies and reactions to own messages even if chat is muted
2024-12-06 15:33:51 +01:00
adb 708a68119e Merge pull request #3476 from deltachat/adb/fix-upload-relese-script
fix scripts/upload-release.sh
2024-12-06 10:57:55 +01:00
adbenitez 1d5ab98892 fix scripts/upload-release.sh 2024-12-06 07:59:49 +01:00
adb 07753e211d Merge pull request #3475 from deltachat/prep-1.50.2
prepare 1.50.2
2024-12-06 07:47:10 +01:00
adbenitez 8135d96300 update build.gradle 2024-12-06 07:44:00 +01:00
adbenitez d151e825da update changelog 2024-12-06 07:42:34 +01:00
adb d5289cc3df Merge pull request #3474 from deltachat/adb/update-translations-6/12/24
update translations
2024-12-06 07:40:29 +01:00
adbenitez af40a8b57e update translations 2024-12-06 07:39:00 +01:00
B. Petersen 529139099e fix starting of webxdc
the issue is that unset `EXTRA_HREF` is passed around as an empty string,
however `Bundle.getString(href, "index.html")` returns `index.html` only when `href` is `NULL`,
which is mostly never the case.

this results in webxdc never started with index.html,
and then not started at all
2024-12-06 01:19:44 +01:00
B. Petersen b4aa18abae amend 1.50 changelog 2024-12-05 21:40:28 +01:00
adb a7cee63d1c Merge pull request #3469 from deltachat/update-core-and-stuff-5.12.25
Update core to 1.151.5
2024-12-05 17:47:34 +01:00
adbenitez eda735925a update local help and translations 2024-12-05 17:46:03 +01:00
adbenitez 46650c8cc3 update deltachat-core-rust to 'chore(release): prepare for 1.151.5' of 'v1.151.5' 2024-12-05 16:34:26 +01:00
adbenitez fbab156d22 tweak apps icon 2024-12-05 15:50:14 +01:00
adb 539cb670f1 Merge pull request #3465 from deltachat/adb/force-base-url-in-webxdc-href
always prefix href with baseURL
2024-12-04 16:54:32 +01:00
adb 2a6aba110b Update src/main/java/org/thoughtcrime/securesms/WebxdcStoreActivity.java
Co-authored-by: Hocuri <hocuri@gmx.de>
2024-12-04 16:40:02 +01:00
adb 0351a1e974 Update src/main/res/values/strings.xml
Co-authored-by: bjoern <r10s@b44t.com>
2024-12-04 16:06:32 +01:00
adbenitez d48ab128a0 open clicked non-xdc URLs in external browsers instead of internally 2024-12-04 16:01:49 +01:00
adbenitez ef67585529 remove label 2024-12-04 14:59:10 +01:00
adbenitez 953e7c6da0 don't export WebxdcStoreActivity 2024-12-04 14:57:12 +01:00
adbenitez ab5a9c9d60 rename config name and meaning 2024-12-04 13:55:02 +01:00
adb af91cf7413 Update src/main/res/values/strings.xml
Co-authored-by: bjoern <r10s@b44t.com>
2024-12-04 12:59:18 +01:00
adbenitez 6a618986d0 rename to ui.notify_mentions_if_muted and improve code 2024-12-04 12:59:18 +01:00
adbenitez 9eefcacbc1 add option to disable notifying "mentions" in muted chats 2024-12-04 12:59:18 +01:00
adbenitez e245e29058 notify webxdc events, replies and reactions to own messages even if chat is muted 2024-12-04 12:59:18 +01:00
adbenitez 7d879f8d1f always prefix href with baseURL 2024-12-04 11:24:13 +01:00
adbenitez f7963a56e9 add App Picker URL setting 2024-12-03 19:32:36 +01:00
adbenitez 0a73877c25 add app picker to attachments menu 2024-12-03 18:52:15 +01:00
adb 1b57880be3 Merge pull request #3464 from deltachat/adb/fix-strings
fix strings.xml
2024-12-03 14:07:59 +01:00
adbenitez f54144e7e8 fix strings.xml 2024-12-03 13:41:09 +01:00
adb b735759bd0 Merge pull request #3462 from deltachat/prep-1.50.0
prepare 1.50.0
2024-12-03 13:22:29 +01:00
adb a7199ecedf Update src/main/res/values/strings.xml
Co-authored-by: bjoern <r10s@b44t.com>
2024-12-03 13:22:10 +01:00
adbenitez 2cb529be32 update ndk-make.sh 2024-12-03 12:05:30 +01:00
adbenitez 235038027b Merge remote-tracking branch 'upstream/main' 2024-12-03 11:54:39 +01:00
adbenitez e8eb036594 prepare 1.50.0 2024-12-03 11:36:26 +01:00
adb d531eb8b47 Merge pull request #3461 from deltachat/update-core-and-stuff-3.12.24
update core to 1.151.3
2024-12-03 11:02:46 +01:00
adbenitez a88a619099 update deltachat-core-rust to 'chore(release): prepare for 1.151.3' of 'v1.151.3' 2024-12-03 10:56:47 +01:00
adb 00bc429f20 Merge pull request #3460 from deltachat/adb/dont-notify-open-webxdc
do not notify if the webxdc is open
2024-12-02 18:40:31 +01:00
adbenitez 3f25d002e4 do not notify if the webxdc is open 2024-12-02 18:01:50 +01:00
adb 74c6f20c3e Merge pull request #3457 from deltachat/adb/fix-callJavascriptFunction
fix WebxdcActivity.callJavaScriptFunction()
2024-12-02 14:41:05 +01:00
B. Petersen 8728a0a39b remove dead code
these RPC calls are probably a relict of first tries,
they are not exhaustive in their area are nor were ever used,
maybe not even working.
if we decide to go that way at some point anyways much more is needed :)
2024-12-02 13:30:38 +01:00
adbenitez dcf5cf7f54 translate mention pref to Spanish 2024-11-30 18:21:35 +01:00
adbenitez 7f89ecea5c Merge remote-tracking branch 'upstream/adb/improve-notifications' 2024-11-30 13:17:01 +01:00
adbenitez 30a63dd13b allow to toggle direct mentions notifications in muted chats 2024-11-30 13:16:05 +01:00
adbenitez a5d2642c37 do not notify mentions in muted 1:1 chats 2024-11-30 13:13:50 +01:00
adbenitez 79e5eedab0 Merge remote-tracking branch 'upstream/adb/improve-notifications' 2024-11-30 12:21:20 +01:00
adbenitez 27da217eb7 Merge remote-tracking branch 'upstream/adb/fix-callJavascriptFunction' 2024-11-30 12:20:07 +01:00
adbenitez a0c71a5387 fix WebxdcActivity.callJavaScriptFunction()
now even if internet access is enabled, the index.html is wrapped in
an iframe
2024-11-30 12:03:44 +01:00
adbenitez 4d19a59cb6 improve notifications handling 2024-11-29 20:10:49 +01:00
adbenitez 819a9f415a Merge remote-tracking branch 'upstream/main' 2024-11-29 19:38:43 +01:00
adbenitez dff1ef3778 update CI 2024-11-29 16:49:15 +01:00
B. Petersen 7131f5774e adapt to changed deltachat-pages output folder 2024-11-27 20:36:46 +01:00
adb aa572508dc prepare 1.49.0 (#3453)
* update changelog

* update build.gradle

* update changelog

* update scripts/upload-beta.sh
2024-11-27 20:36:30 +01:00
adb 1f880efb3f Merge pull request #3454 from deltachat/adb/update-link-generation
remove Util.QrDataToInviteURL()
2024-11-27 19:15:41 +01:00
adbenitez 72ace5c156 remove Util.QrDataToInviteURL() 2024-11-27 19:01:49 +01:00
B. Petersen 2f34a6ffa4 do not quote a dedicated message; current android shows them grouped and you do not really know what the message refers to 2024-11-27 18:02:07 +01:00
adbenitez afdfe7bbaa update strings 2024-11-27 14:37:29 +01:00
adbenitez 14f43f2a79 update deltachat-core-rust to 'chore(release): prepare for 1.151.2 (#6267)' of 'v1.151.2' 2024-11-27 14:37:29 +01:00
B. Petersen f3353cf6e9 update local help 2024-11-27 14:36:33 +01:00
adb 722f2cad1e Merge pull request #3449 from deltachat/adb/update-deeplink-api-impl
update to new deep-link API specs
2024-11-26 16:23:09 +01:00
adbenitez b135093628 update to new deep-link API specs 2024-11-26 13:24:35 +01:00
adb be44789b01 Merge pull request #3447 from deltachat/adb/issue-3444
add "show in chat" to webxdc menu
2024-11-26 12:35:22 +01:00
B. Petersen 233197095b remove dead code 2024-11-25 20:42:46 +01:00
adb 494cb728c3 Update src/main/res/menu/webxdc.xml
Co-authored-by: bjoern <r10s@b44t.com>
2024-11-25 19:59:51 +01:00
Hocuri 60e9a9101a Don't always show the sender in notifications (#3441), Always show "~" before overridden sender names (#3442)
* Don't always show the sender in notifications

In 1:1 chats, don't prepend the sender name to every line. The exception is when the display name is not equal to the chat name (i.e. there is an OverwriteSenderDisplayname), in this case we still prepend it.

* Always show the "~" before the sender name if it's overridden

When we introduced this, I assume that we weren't sure whether we should
do it and only showed it in some places. But I think it's nicer to
show the same sender name everywhere, i.e. always add the "~".
2024-11-25 14:44:31 +01:00
adbenitez c23dac6f99 add "show in chat" to webxdc menu 2024-11-25 00:57:45 +01:00
adb 3965319ef4 Merge pull request #3446 from deltachat/adb/deprecate-desc-param-of-sendUpdate
remove 'description' parameter from webxdc's sendUpdate()
2024-11-25 00:56:16 +01:00
adb c4db7c515f Merge pull request #3443 from deltachat/adb/issue-3439
notify DC_EVENT_INCOMING_WEBXDC_NOTIFY
2024-11-24 21:37:15 +01:00
adbenitez fbf88e102b remove 'description' parameter from webxdc's sendUpdate()
the 'description' parameter is about to be deprecated,
see https://github.com/deltachat/deltachat-core-rust/issues/6245
2024-11-24 21:34:22 +01:00
adb d5ea043893 Merge pull request #3440 from deltachat/hoc/reverse-notification-inbox
Reverse order of the tiny inbox in notifications
2024-11-24 21:20:34 +01:00
adbenitez f70c79ba4a fix notifyWebxdc 2024-11-24 03:46:50 +01:00
adb 0b2a26e2f1 Merge pull request #3438 from deltachat/adb/webxdc-deeplink
allow to open deep-link to webxdc
2024-11-24 00:33:59 +01:00
adbenitez b968ba67b3 avoid NullPointerException 2024-11-24 00:33:22 +01:00
adbenitez e234cc864b don't play in-chat sound 2024-11-23 23:11:34 +01:00
adbenitez b47e75eed6 use new selfAddr 2024-11-23 23:11:34 +01:00
adbenitez 6b684bf030 notify DC_EVENT_INCOMING_WEBXDC_NOTIFY 2024-11-23 23:11:34 +01:00
adbenitez ea89d37461 open webxdc when clicking info-message, pass deeplink/href 2024-11-23 23:09:01 +01:00
adbenitez 814af177d1 fix: make getWebxdcHref public 2024-11-23 23:09:01 +01:00
adbenitez 1ccbb7177f add DcMsg.getWebxdcHref() 2024-11-23 23:09:01 +01:00
adbenitez 3118dbd32b allow to open deep-link to webxdc 2024-11-23 23:09:01 +01:00
adb 1a5e062dac Merge pull request #3445 from deltachat/update-core-to-1.151.0
update core to 1.151.0
2024-11-23 23:04:44 +01:00
B. Petersen 0bcaea6f01 update deltachat-core-rust to 'chore(release): prepare for 1.151.0' of 'v1.151.0' 2024-11-23 23:01:56 +01:00
Hocuri 8283a6c4ad Reverse order of the tiny inbox in notifications 2024-11-23 20:01:46 +01:00
adb cd159bac6c Merge pull request #3377 from deltachat/r10s/notify-reactions
notify reactions added
2024-11-23 18:22:49 +01:00
adb 21f917004f Merge pull request #3436 from deltachat/adb/remove-android-4-code
remove android 4 dead code (SDK<21)
2024-11-22 23:07:12 +01:00
adb 0abf2ff00c Merge pull request #3435 from deltachat/adb/allow-to-open-http-link
allow to open in browser http links that look like proxies
2024-11-21 01:31:11 +01:00
adbenitez 0ca92ec6b5 remove android 4 compatibility code 2024-11-21 01:16:20 +01:00
adbenitez e66fa53537 allow to open in browser http links that look like proxies 2024-11-20 19:36:18 +01:00
Hocuri a51013cc00 fix: Show composite emojis enlarged, too (#3427)
fix: Show composite emojis enlarged, too

There are a lot of composite emojis like the flags and the family emojis.
Here, the grapheme starts with an emoji, but then come some other
characters that modify the first emoji (e.g. all flags start with the
flag emoji).

This PR shows those as big, too, by checking whether a grapheme _starts_
with an emoji to determine whether it's an emoji.


---------

Co-authored-by: adb <adb@merlinux.eu>
2024-11-20 13:59:50 +01:00
Hocuri 171500a97d fix: Don't change display name when starting to create a new account and going back (#3434) 2024-11-19 13:24:10 +01:00
link2xt 9a4851961e fix: check draft.isOk() instead of comparing to null
dcContext.getDraft() never returns null.
2024-11-19 10:38:08 +00:00
adbenitez e5ddbacb2e update build.gradle 2024-11-15 22:45:17 +01:00
adbenitez 03c7d78e2b Merge remote-tracking branch 'upstream/main' 2024-11-15 22:45:10 +01:00
adb 00498b02b3 Merge pull request #3424 from deltachat/adb/issue-3423
remove internal font scaling preference
2024-11-15 22:01:51 +01:00
adbenitez ad6e2d1a9f fix typo 2024-11-15 21:20:40 +01:00
adbenitez 5cfa71cd72 add some protection against theoretical 0 value from ViewUtil.pxToSp() 2024-11-15 20:57:33 +01:00
adbenitez 0551044ef9 remove internal font size setting 2024-11-15 18:02:42 +01:00
adb 5126b3eeb2 Merge pull request #3422 from deltachat/adb/issue-3421
change proxy protocol label position
2024-11-15 04:27:31 +01:00
B. Petersen 8d7078f96f fix playing inChatSounds 2024-11-14 14:10:17 +01:00
B. Petersen c446440537 save one database call 2024-11-14 14:10:17 +01:00
B. Petersen 333e4c9eca notify reactions 2024-11-14 14:10:17 +01:00
B. Petersen fb1f5df234 fix ticker line 2024-11-14 14:10:17 +01:00
Hocuri cc419a9f62 perf: Return early in getTextScale() if text is empty or starts with letter (#3426)
Not sure why, but `setText()` seems to be called with an empty string
very often - for this case it's nice if getTextScale() returns early.

If the text starts with a letter, we can also return early.
2024-11-13 20:08:31 +01:00
adbenitez 2469b6efef update originalFontSize on setTextSize() 2024-11-13 17:20:14 +01:00
adbenitez b7446c9a93 update build.gradle 2024-11-13 04:29:58 +01:00
adbenitez 0c9b5bbaf4 Merge remote-tracking branch 'upstream/main' 2024-11-13 04:29:08 +01:00
adbenitez 3126544f00 fix "show full message" button 2024-11-13 04:28:13 +01:00
adbenitez ccdad0469d Merge remote-tracking branch 'upstream/main' 2024-11-13 01:45:40 +01:00
B. Petersen 9f3eeb3d0d calculate account size in background
calculation may take a moment,
do this in background.

it is totally fine to just display nothing before,
that avoids flickering (WHAT was this? i cannot look so fast!) -
and in most cases, it is close to instant.
2024-11-13 00:16:52 +01:00
adbenitez 92bc53b672 change proxy protocol label position 2024-11-12 23:12:37 +01:00
adb 1355303360 Merge pull request #3411 from deltachat/adb/issue-3399
remove old emojis
2024-11-12 20:34:59 +01:00
adbenitez 7227f513a5 don't use unnecessary "" in build.gradle 2024-11-12 20:33:41 +01:00
adb 4933d66000 Update src/main/res/layout/reactions_pill.xml
Co-authored-by: bjoern <r10s@b44t.com>
2024-11-12 20:23:55 +01:00
adbenitez 977b21618c increase accepted lenght for scalling to 21
also avoid unnecessary iteration over graphemes if limit is exceeded already
2024-11-12 19:45:33 +01:00
adb 5cecd5bec3 Update src/main/java/org/thoughtcrime/securesms/components/InputPanel.java
Co-authored-by: Hocuri <hocuri@gmx.de>
2024-11-12 19:29:38 +01:00
adbenitez d8db39f9c7 add comment on regex 2024-11-12 19:28:25 +01:00
adbenitez 736fc44870 fix onEmojiPicked() 2024-11-12 19:23:49 +01:00
adb 537127ec4e Merge pull request #3419 from deltachat/adb/issue-3291
don't increase reaction selector's font size according to system
2024-11-12 15:29:17 +01:00
B. Petersen a5167f3739 log a warning if index gets out of bounds 2024-11-12 10:02:15 +01:00
B. Petersen d481541ad8 crash precaution by checking Spinner bounds
Spinner is very picky about bad selections,
this is an accident waiting to happen -
eg. if new values are introduces
or someone thinks, the "deprecated" case can be removed.

better do not trust incoming data.
2024-11-12 10:02:15 +01:00
adbenitez 7ab19fb8af scale emojis 2024-11-12 05:41:54 +01:00
adbenitez 715a2c0653 don't increase reaction selector's font size according to system 2024-11-12 03:33:36 +01:00
link2xt 350cd0539c build: update NDK to r27
If we are dropping Android 4 support anyway,
can as well upgrade to the current LTS NDK
which requires API level 21 (Android 5.0).
2024-11-11 16:22:55 +00:00
adb 9f8fe08c75 Merge pull request #3400 from deltachat/adb/issue-3395
improve msg_action_button
2024-11-11 16:11:44 +01:00
Hocuri 5048239563 Rename "Back up Chats to External Storage" to "Export Backup" (#3416) 2024-11-11 16:08:59 +01:00
link2xt 6e135e06a9 Opt out of webview metrics collection 2024-11-11 15:05:06 +00:00
B. Petersen d52647b288 tweak phased rollout instructions 2024-11-09 17:32:46 +01:00
B. Petersen c0a729978c update huawei instructions 2024-11-08 12:54:26 +01:00
adbenitez 041c95c6d2 remove jemoji, it adds +13MB 2024-11-06 16:39:17 +01:00
adbenitez 8de0fed18e update build.gradle 2024-11-05 23:33:09 +01:00
adbenitez dd75a8e858 enlarge font size when text is only a few emojis 2024-11-05 23:04:25 +01:00
adbenitez 2e77db23d5 remove more unused code 2024-11-05 22:24:29 +01:00
adbenitez 04a4a02235 remove transparency from emoji in pills and reactions details 2024-11-05 19:36:42 +01:00
adbenitez 2910730bc1 remove unused emoji attrs and layouts 2024-11-05 19:18:32 +01:00
Hocuri 23458a6c64 Don't show "0%" at the beginning when being added as second device (#3409) 2024-11-05 15:32:34 +01:00
Hocuri 9679b22072 fix: Accept the deprecated 3 as an alias for 2 (#3410) 2024-11-05 15:28:50 +01:00
adbenitez 3fae301ec2 remove old emojis components 2024-11-05 02:00:42 +01:00
adbenitez d08069f7b0 remove old emojis 2024-11-04 23:29:28 +01:00
B. Petersen 56a0607a5e update RELEASE.md to changed store ui 2024-11-01 14:43:56 +01:00
B. Petersen 9c08617f7d bump version to 1.48.3 2024-10-31 21:35:26 +01:00
B. Petersen 812dc8d738 update CHANGELOG for 1.48.3 2024-10-31 21:35:26 +01:00
B. Petersen d8b278a1f5 update translations 2024-10-31 21:06:00 +01:00
bjoern 4368a4f63e update translations (#3402) 2024-10-31 18:07:55 +01:00
adb 72ae90ae93 change realtime preference position (#3398)
* change realtime preference position

* tweak realtime explaination

* Update src/main/res/values/strings.xml

Co-authored-by: bjoern <r10s@b44t.com>

* tweak realtime strings

* show warning if realtime is disabled and apps need it

* update realtime warning message

* Update src/main/res/values/strings.xml

Co-authored-by: Hocuri <hocuri@gmx.de>

* Update src/main/res/values/strings.xml

Co-authored-by: Hocuri <hocuri@gmx.de>

* update strings.xml

* update strings.xml

* revert dialog

---------

Co-authored-by: bjoern <r10s@b44t.com>
Co-authored-by: Hocuri <hocuri@gmx.de>
2024-10-31 18:00:20 +01:00
B. Petersen c36ce7a8ab update deltachat-core-rust to 'chore(release): prepare for 1.148.6' of 'v1.148.6' 2024-10-31 17:53:33 +01:00
adbenitez 404097fe30 keep old style for "show full message" 2024-10-30 18:22:21 +01:00
adbenitez 07d5c719d4 improve mst_action_button 2024-10-29 20:47:33 +01:00
adb 13a43473cc improve logging: always log events for accId=0 (#3391)
improve logging: always log events for all accounts including previously ignored accId=0
2024-10-29 17:45:33 +01:00
B. Petersen 5a84198829 bump version to 1.48.2 2024-10-29 00:43:48 +01:00
B. Petersen 1f443cd87c update CHANGELOG for 1.48.2 2024-10-29 00:43:48 +01:00
B. Petersen 4901b92ee2 update local help 2024-10-28 23:41:18 +01:00
B. Petersen cd48e15071 update translations 2024-10-28 23:41:18 +01:00
B. Petersen 2d4b570f48 update deltachat-core-rust to 'chore(release): prepare for 1.148.5' of 'v1.148.5' 2024-10-28 23:41:18 +01:00
B. Petersen 3f0b36bd4b 'message info' just shows the file name
from the view of the user, this is just the 'file name'.
calling it 'original file name' there is maybe correct internally,
as we add a random number for $reasons.
however, some users were alarmed about what the heck is transferred here.
2024-10-27 15:28:11 +01:00
B. Petersen b342fb9c30 update translations 2024-10-27 11:51:00 +01:00
328 changed files with 5323 additions and 7489 deletions
+3
View File
@@ -0,0 +1,3 @@
ko_fi: adbenitez
liberapay: adbenitez
custom: "https://arcanechat.me/#contribute"
+1 -1
View File
@@ -1 +1 @@
blank_issues_enabled: true
blank_issues_enabled: false
+2 -2
View File
@@ -35,7 +35,7 @@ jobs:
- uses: nttld/setup-ndk@v1
id: setup-ndk
with:
ndk-version: r23c
ndk-version: r27
- name: Compile core
env:
@@ -51,7 +51,7 @@ jobs:
run: ./gradlew --no-daemon -PABI_FILTER=armeabi-v7a assembleFossDebug
- name: Upload APK
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: app-preview.apk
path: 'build/outputs/apk/foss/debug/*.apk'
+8 -7
View File
@@ -37,7 +37,7 @@ jobs:
- uses: nttld/setup-ndk@v1
id: setup-ndk
with:
ndk-version: r23c
ndk-version: r27
- name: Compile core
env:
@@ -49,11 +49,12 @@ jobs:
- name: Build APK
run: |
mkdir -p ~/.gradle
echo -n ${{ secrets.SIGNING_KEY }} | base64 -d >> ~/app.keystore
echo "DC_RELEASE_STORE_FILE=$HOME/app.keystore" >> ~/.gradle/gradle.properties
echo "DC_RELEASE_STORE_PASSWORD=${{ secrets.KEY_STORE_PASSWORD }}" >> ~/.gradle/gradle.properties
echo "DC_RELEASE_KEY_ALIAS=${{ secrets.ALIAS }}" >> ~/.gradle/gradle.properties
echo "DC_RELEASE_KEY_PASSWORD=${{ secrets.KEY_PASSWORD }}" >> ~/.gradle/gradle.properties
echo -n ${{ secrets.KEYSTORE_FILE }} | base64 -d >> ~/keystore.jks
echo "DC_RELEASE_STORE_FILE=$HOME/keystore.jks" >> ~/.gradle/gradle.properties
echo "DC_RELEASE_STORE_PASSWORD=${{ secrets.KEYSTORE_PASSWORD }}" >> ~/.gradle/gradle.properties
echo "DC_RELEASE_KEY_ALIAS_FDROID=${{ secrets.ALIAS_FDROID }}" >> ~/.gradle/gradle.properties
echo "DC_RELEASE_KEY_ALIAS_GPLAY=${{ secrets.ALIAS_GPLAY }}" >> ~/.gradle/gradle.properties
echo "DC_RELEASE_KEY_PASSWORD=${{ secrets.KEYSTORE_PASSWORD }}" >> ~/.gradle/gradle.properties
./gradlew assembleFossRelease
rm build/outputs/apk/foss/release/*universal*
./gradlew assembleGplayRelease
@@ -63,7 +64,7 @@ jobs:
uses: softprops/action-gh-release@v1
with:
token: "${{ secrets.GITHUB_TOKEN }}"
body: '[<img src="store/get-it-on-fdroid.png" alt="Get it on F-Droid" height="48">](https://f-droid.org/packages/chat.delta.lite) [<img src="store/get-it-on-IzzyOnDroid.png" alt="Get it on IzzyOnDroid" height="48">](https://apt.izzysoft.de/fdroid/index/apk/chat.delta.lite) [<img src="store/get-it-on-apklis.png" alt="Disponible en Apklis" height="48">](https://www.apklis.cu/application/chat.delta.lite) [<img src="store/get-it-on-github.png" alt="Get it on GitHub" height="48">](https://github.com/ArcaneChat/android/releases/latest/download/ArcaneChat-gplay.apk)'
body: '[<img src="store/get-it-on-gplay.png" alt="Get it on Google Play" height="48">](https://play.google.com/store/apps/details?id=com.github.arcanechat) [<img src="store/get-it-on-fdroid.png" alt="Get it on F-Droid" height="48">](https://f-droid.org/packages/chat.delta.lite) [<img src="store/get-it-on-IzzyOnDroid.png" alt="Get it on IzzyOnDroid" height="48">](https://apt.izzysoft.de/fdroid/index/apk/chat.delta.lite) [<img src="store/get-it-on-apklis.png" alt="Disponible en Apklis" height="48">](https://www.apklis.cu/application/chat.delta.lite) [<img src="store/get-it-on-github.png" alt="Get it on GitHub" height="48">](https://github.com/ArcaneChat/android/releases/latest/download/ArcaneChat-gplay.apk)'
prerelease: ${{ contains(github.event.ref, '-beta') }}
fail_on_unmatched_files: true
files: build/outputs/apk/foss/release/*.apk
+99 -3
View File
@@ -1,6 +1,94 @@
# ArcaneChat Android Changelog
## v1.48.1
## v1.52.1
2025-01
* the app now requires less storage on your SD card by deduplicating newly received/sent files
* some small bug fixes
* update translations
* update to core 1.155.1
## v1.52.0
2025-01
* new group consistency algorithm
* fix: don't show animated .webp stickers as static stickers
* fix the chat shortcuts (created via long-press in launcher) to properly support multi-profile
* fix some small bugs in certain android versions and special situations
* avoid the app freezing in slow phones in some situations
* improve menu in the help screen
* update translations
* update to core 1.155.0
## v1.50.5
2025-01
* fix push-notifications handling for certain devices where it was not working correctly
* update translations
* using core 1.153.0
## v1.50.4
2025-01
* properly send as animated stickers GIF files selected from keyboard
* improve emoji picker in landscape mode and when changing from landscape to portrait
* avoid crash when receiving push notifications if the user restricted the app from working in background
* improve UI when attaching a file or image to easily recognize it is attached but not sent yet
* avoid slow loading of in-chat apps in some devices when quickly re-opening an app after closing it
* allow to select multiple images at once in the media picker via "Gallery" button
* mark holiday notice messages as bot-generated
* don't mark contacts as bot when receiving location-only and sync messages
* prefer to encrypt even if peers have their preference to "no preference"
* start ephemeral messages timers when the chat is archived or noticed
* several bug fixes and updated translations
* update to core 1.153.0
## v1.50.3
2024-12
* Add in-chat apps picker to attachments options
* Notify replies and reactions to your messages in muted chats (can be disabled in settings)
* Cache HTTP GET requests (ex. when loading images from HTML messages)
* update to core 1.152.0
## v1.50.2
2024-12
* Encrypt notification tokens
* update to core 1.151.5
## v1.50.0
2024-12
* New emoji picker with support for more emojis
* Webxdc apps can now trigger notifications
* Webxdc apps can now deep-link to internal sections when you click their info-messages in chat
* Add "Show in Chat" to the menu of opened Webxdc apps
* Reverse order of messages in the notification group
* Notify reactions to own messages
* Improve the button to start Webxdc apps
* Make account deletion confirmation dialog faster
* Rename "Back up Chats to External Storage" to "Export Backup"
* Improve compatibility with classic email clients in the outgoing messages
* Removed internal font scaling setting in favor of the better system settings
* Use privacy-preserving webxdc addresses
* Use Rustls for connections with strict TLS
* QR codes for adding contacts and joining groups provide help when opened in a normal browser
* Mark Saved Messages chat as protected
* Allow the user to replace maps integration
* fix: Trim whitespace from scanned QR codes
* fix quotes: Line-before-quote may be up to 120 character long instead of 80
* fix: Prevent accidental wrong-password-notifications
* fix: Remove footers from "Show Full Message..."
* fix: Only add "member added/removed" messages if they actually do that
* fix: Update state of message when fully downloading it
* fix: send message: Do not fail if the message does not exist anymore
* fix: Do not percent-encode dot when passing to autoconfig server (so, fix handling of some servers)
* fix displaynames not being updated when intially scanned by a QR code
* several bug fixes
* update to core 1.151.3
## v1.48.3
2024-10
* new Proxy settings screen available at "Advanced / Proxy"
@@ -10,6 +98,8 @@
* scan Proxies' QR code and use them
* make Proxy URLs inside Delta Chat tappable
* open Delta Chat when tapping Proxy URLs in other apps
* support for realtime webxdc apps moved out of experimental and enabled by default
* realtime webxdc apps can be disabled at "Settings / Advanced"
* "New Contact / Link" button to view, share or copy the invite line
* "New Contact / Scan" button to easier access the scanner functionality
* open "New Contact" scan/show activities directly, do not try to be too smart and open the last active tab
@@ -44,8 +134,10 @@
* assign messages to ad-hoc group with matching name and members
* use stricter TLS checks for HTTPS downloads (images in HTML mails, Autoconfig)
* improve logging for failed QR code scans, AEAP, Autocrypt, notification permissions and sending errors
* improve logging of multi account setup (log account ID)
* show more context for the "Cannot establish guaranteed..." info message
* show original file name in "Message Info"
* show file name in "Message Info"
* show root SMTP connection failure in connectivity view
* fix: Sort received outgoing message down if it's fresher than all non fresh messages
* fix: avoid app being killed when processing a PUSH notification
* fix crash when refreshing avatar
@@ -65,8 +157,12 @@
* fix: normalize proxy URLs
* fix connections getting stuck in "Updating..." sometimes
* fix scanning "add second device" QR code from scanner above chatlist
* fix warning about wrong password
* fix app getting stale when receiving a PUSH notifications takes longer
* fix app getting stale on network changes
* fix: skip IDLE if we got unsolicited FETCH
* update translations and local help
* update to core 1.148.4
* update to core 1.148.6
## v1.46.14
+3 -3
View File
@@ -34,10 +34,10 @@ ENV PATH ${PATH}:${ANDROID_SDK_ROOT}/cmdline-tools/bin
# Install NDK manually. Other SDK parts are installed automatically by gradle.
#
# If you change the NDK version here, also change it in `flake.nix`.
# NDK version r23c LTS aka 23.2.8568313
RUN sdkmanager --sdk_root=${ANDROID_SDK_ROOT} 'ndk;23.2.8568313'
# NDK version r27 LTS aka 27.0.11902837
RUN sdkmanager --sdk_root=${ANDROID_SDK_ROOT} 'ndk;27.0.11902837'
ENV ANDROID_NDK_ROOT ${ANDROID_SDK_ROOT}/ndk/23.2.8568313
ENV ANDROID_NDK_ROOT ${ANDROID_SDK_ROOT}/ndk/27.0.11902837
ENV PATH ${PATH}:${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64/bin/
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain none
+2 -1
View File
@@ -1,7 +1,8 @@
## ArcaneChat Android Client
A [Delta Chat](https://delta.chat/) client for Android.
A [Delta Chat](https://delta.chat/) client for Android. Learn more at: https://arcanechat.me
[<img src="store/get-it-on-gplay.png" alt="Get it on Google Play" height="48">](https://play.google.com/store/apps/details?id=com.github.arcanechat)
[<img src="store/get-it-on-fdroid.png" alt="Get it on F-Droid" height="48">](https://f-droid.org/packages/chat.delta.lite)
[<img src="store/get-it-on-IzzyOnDroid.png" alt="Get it on IzzyOnDroid" height="48">](https://apt.izzysoft.de/fdroid/index/apk/chat.delta.lite)
[<img src="store/get-it-on-apklis.png" alt="Disponible en Apklis" height="48">](https://www.apklis.cu/application/chat.delta.lite)
+13 -8
View File
@@ -48,7 +48,8 @@ the following steps are done in a PR called `prep-VERSION` (no leading "v"):
6. build APKs:
a) generate debug APK at "Build / Build Bundle(s)/APK / Build APK(s)"
b) generate release APK at "Build / Generate Signed Bundle or APK",
select "APK", add keys, flavor `gplayRelease`
select "APK", add keys, flavor `gplayRelease`.
this APK will go to the stores and is located at `gplay/release`
## Push Test Releases
@@ -79,16 +80,21 @@ only afterwards, push the APK to stores. **consider a blog post.**
on <https://play.google.com/apps/publish/>:
9. a) open "Delta Chat/Release/Production"
then "Create new release" and upload APK from above
9. a) open "Delta Chat / Test and release / Production"
then "Create new release" and upload APK from above
b) fill out "Release details/Release notes" (500 chars), add the line
"These features will roll out over the coming days. Thanks for using Delta Chat!";
release name should be default ("123 (1.2.3)")
c) click "Next", set "Rollout Percentage" to 1% (later 2%, 5%, 10%, 20%, 50%, 100%),
click "Save"
c) click "Next", set "Rollout Percentage" to 50%, click "Save"
d) Go to "Publishing Overview", "Managed publishing" is usually off;
click "Send change for review", confirm
2 days later, change "Rollout Percentage" to 99%. Two more days later to 100%.
Rollout is anyways slower in practise, however,
only as long as we do not enter 100%, we can retract the version
(Once we reach 100%, we have to submit a new version for approval.
During these up to 4 days, sometimes longer, we cannot do anything on existing rollout)
## Tag for F-Droid and create Github release
@@ -111,9 +117,8 @@ on <https://developer.amazon.com/dashboard>:
12. a) for "Delta Chat", select "Add upcoming version" on the left
b) at "Step 1 / Existing file(s)" hit "Replace", upload the APK from above
c) on the "Step 1" page, add "Release notes" from CHANGELOG.md, hit "Next"
d) on "Step 2" page: "Does your app collect or transfer user data to third parties?" -> No, then "Next"
e) on "Step 3" page: "Next"
f) on "Step 4" page: "Submit app"
d) on "Step 2" and "Step 3" pages, hit "Next"
e) on "Step 4" page: "Submit app"
## Release on Huawei AppGallery
+45 -27
View File
@@ -1,5 +1,5 @@
plugins {
id 'com.android.application' version '8.1.4'
id 'com.android.application' version '8.5.2'
id 'com.google.gms.google-services' version '4.4.1'
}
@@ -29,12 +29,12 @@ android {
// > Task :stripFatDebugDebugSymbols
// Unable to strip the following libraries, packaging them as they are: libanimation-decoder-gif.so, libnative-utils.so.
// See <https://issuetracker.google.com/issues/237187538> for details.
ndkVersion "23.2.8568313"
ndkVersion "27.0.12077973"
useLibrary 'org.apache.http.legacy'
defaultConfig {
versionCode 30000694
versionName "1.48.2"
versionCode 30000708
versionName "1.52.2"
applicationId "chat.delta.lite"
multiDexEnabled true
@@ -87,15 +87,45 @@ android {
storeFile file(DC_DEBUG_STORE_FILE )
}
}
release {
releaseFdroid {
// can be defined at `~/.gradle/gradle.properties` or at "Build/Generate signed APK"
if(project.hasProperty("DC_RELEASE_STORE_FILE")) {
storeFile file(DC_RELEASE_STORE_FILE)
storePassword DC_RELEASE_STORE_PASSWORD
keyAlias DC_RELEASE_KEY_ALIAS
keyAlias DC_RELEASE_KEY_ALIAS_FDROID
keyPassword DC_RELEASE_KEY_PASSWORD
}
}
releaseApk {
// can be defined at `~/.gradle/gradle.properties` or at "Build/Generate signed APK"
if(project.hasProperty("DC_RELEASE_STORE_FILE")) {
storeFile file(DC_RELEASE_STORE_FILE)
storePassword DC_RELEASE_STORE_PASSWORD
keyAlias DC_RELEASE_KEY_ALIAS_GPLAY
keyPassword DC_RELEASE_KEY_PASSWORD
}
}
releaseBundle {
if(project.hasProperty("DC_BUNDLE_STORE_FILE")) {
storeFile file(DC_BUNDLE_STORE_FILE)
storePassword DC_BUNDLE_STORE_PASSWORD
keyAlias DC_BUNDLE_KEY_ALIAS
keyPassword DC_BUNDLE_STORE_PASSWORD
}
}
}
productFlavors {
foss {
dimension "none"
buildConfigField "boolean", "USE_PLAY_SERVICES", "false"
}
gplay {
dimension "none"
apply plugin: "com.google.gms.google-services"
buildConfigField "boolean", "USE_PLAY_SERVICES", "true"
applicationId "com.github.arcanechat"
}
}
buildTypes {
@@ -114,23 +144,12 @@ android {
// nb: it is highly recommended to use the same settings in debug+release -
// otherwise problems might be noticed delayed only
minifyEnabled true
signingConfig signingConfigs.release
productFlavors.foss.signingConfig signingConfigs.releaseFdroid
productFlavors.gplay.signingConfig signingConfigs.releaseApk
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
productFlavors {
foss {
dimension "none"
buildConfigField "boolean", "USE_PLAY_SERVICES", "false"
}
gplay {
dimension "none"
apply plugin: "com.google.gms.google-services"
buildConfigField "boolean", "USE_PLAY_SERVICES", "true"
}
}
if(!project.hasProperty("ABI_FILTER")) {
splits {
abi {
@@ -190,7 +209,7 @@ dependencies {
implementation 'com.airbnb.android:lottie:4.2.2' // Lottie animations support.
implementation 'androidx.sharetarget:sharetarget:1.2.0'
implementation 'androidx.webkit:webkit:1.11.0'
implementation 'androidx.webkit:webkit:1.12.1'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'com.google.android.material:material:1.12.0'
@@ -206,11 +225,11 @@ dependencies {
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.6.2'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2'
implementation 'androidx.work:work-runtime:2.9.1'
implementation 'androidx.emoji2:emoji2-emojipicker:1.4.0'
implementation 'androidx.emoji2:emoji2-emojipicker:1.5.0'
implementation 'com.google.guava:guava:31.1-android'
implementation 'com.google.android.exoplayer:exoplayer-core:2.19.1' // plays video and audio
implementation 'com.google.android.exoplayer:exoplayer-ui:2.19.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.constraintlayout:constraintlayout:2.2.0'
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
@@ -218,14 +237,13 @@ dependencies {
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.chrisbanes:PhotoView:2.1.3' // does the zooming on photos / media
implementation 'com.github.penfeizhou.android.animation:glide-plugin:2.25.0' // APNG & animated webp support.
implementation 'com.github.penfeizhou.android.animation:glide-plugin:3.0.2' // APNG & 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'
annotationProcessor 'androidx.annotation:annotation:1.8.2'
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.soundcloud.android:android-crop:1.0.1@aar' // used for profile and group avatar selection in Android SDK<19
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
@@ -240,7 +258,7 @@ dependencies {
// <https://github.com/cketti/SafeContentResolver>
implementation 'de.cketti.safecontentresolver:safe-content-resolver-v14:1.0.0'
gplayImplementation('com.google.firebase:firebase-messaging:24.0.0') { // for PUSH notifications
gplayImplementation('com.google.firebase:firebase-messaging:24.1.0') { // for PUSH notifications
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'
@@ -254,7 +272,7 @@ dependencies {
testImplementation 'org.powermock:powermock-module-junit4-rule:1.6.1'
testImplementation 'org.powermock:powermock-classloading-xstream:1.6.1'
androidTestImplementation 'androidx.test:runner:1.6.1'
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'
@@ -17,19 +17,21 @@ ArcaneChat is a Delta Chat client and was created with a focus on usability, goo
<b>Main differences with official Delta Chat client:</b>
<ul>
<li>Basic markdown support (bold, italic, strike, etc.)</li>
<li>Support for some markdown styles in text messages (bold, italic, strike, etc.)</li>
<li>Support for displaying Telegram's animated stickers (.tgs files)</li>
<li>Support for SVG images previews</li>
<li>Multiple color themes/skins</li>
<li>It is possible to disable accounts to completely disconnect them to save data/bandwidth</li>
<li>It is possible to disable profiles to completely disconnect them saving data/bandwidth</li>
<li>You can easily see the connection status of all your profiles in the profile switcher</li>
<li>A videochat instance is set by default</li>
<li>Replies to your messages in muted groups trigger notifications</li>
<li>Location streaming feature enabled by default and extra option to share location for 12 hours</li>
<li>Clicking on a message with a POI location, will open the POI on the map</li>
<li>Last-seen status of contacts is shown in your contact list, like in WhatsApp, Telegram, etc.</li>
<li>Videos are played in loop, useful for short GIF videos</li>
<li>Verified icon is shown in the chat list for the "Device Messages" chat</li>
<li>Voice messages have more aggressive compression in "worse quality" mode to save data plan</li>
<li>Automatic download of messages limited to 640KB by default</li>
<li>Account's display name is always shown in the app's title bar instead of the name of the app</li>
<li>Profile's display name is always shown in the app's title bar instead of the name of the app</li>
<li>Your avatar is visible to other users in Mailing Lists</li>
<li>Can be selected as app to open .xdc files</li>
<li>For mini-apps developers: there are some extra features in the WebXDC API, check https://github.com/ArcaneChat/android/#webxdc</li>
Generated
+26 -94
View File
@@ -3,15 +3,15 @@
"android": {
"inputs": {
"devshell": "devshell",
"flake-utils": "flake-utils_2",
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1710633978,
"narHash": "sha256-yemnwSvW7cdWtXGpivFA5jDO35rGPs6fqxlQ4l6ODXs=",
"lastModified": 1733948466,
"narHash": "sha256-o/uq/tU458Ykudi8Zk3sRga5iazkuSczt9wDOCUDOSU=",
"owner": "tadfisher",
"repo": "android-nixpkgs",
"rev": "e91fb3d8517538e5ad9b422c9a4f604b56008a9e",
"rev": "0bf99ffaea6a7c0948ae10cf2e40c2905e4e4d6b",
"type": "github"
},
"original": {
@@ -22,18 +22,17 @@
},
"devshell": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": [
"android",
"nixpkgs"
]
},
"locked": {
"lastModified": 1708939976,
"narHash": "sha256-O5+nFozxz2Vubpdl1YZtPrilcIXPcRAjqNdNE8oCRoA=",
"lastModified": 1728330715,
"narHash": "sha256-xRJ2nPOXb//u1jaBnDP56M7v5ldavjbtR6lfGqSvcKg=",
"owner": "numtide",
"repo": "devshell",
"rev": "5ddecd67edbd568ebe0a55905273e56cc82aabe3",
"rev": "dd6b80932022cea34a019e2bb32f6fa9e494dfef",
"type": "github"
},
"original": {
@@ -47,11 +46,11 @@
"systems": "systems"
},
"locked": {
"lastModified": 1701680307,
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
@@ -65,47 +64,11 @@
"systems": "systems_2"
},
"locked": {
"lastModified": 1709126324,
"narHash": "sha256-q6EQdSeUZOG26WelxqkmR7kArjgWCdw5sfJVHPH/7j8=",
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "d465f4819400de7c8d874d50b982301f28a84605",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_3": {
"inputs": {
"systems": "systems_3"
},
"locked": {
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_4": {
"inputs": {
"systems": "systems_4"
},
"locked": {
"lastModified": 1705309234,
"narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
@@ -116,11 +79,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1709237383,
"narHash": "sha256-cy6ArO4k5qTx+l5o+0mL9f5fa86tYUX3ozE1S+Txlds=",
"lastModified": 1733759999,
"narHash": "sha256-463SNPWmz46iLzJKRzO3Q2b0Aurff3U1n0nYItxq7jU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "1536926ef5621b09bba54035ae2bb6d806d72ac8",
"rev": "a73246e2eef4c6ed172979932bc80e1404ba2d56",
"type": "github"
},
"original": {
@@ -132,11 +95,11 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1710889954,
"narHash": "sha256-Pr6F5Pmd7JnNEMHHmspZ0qVqIBVxyZ13ik1pJtm2QXk=",
"lastModified": 1733749988,
"narHash": "sha256-+5qdtgXceqhK5ZR1YbP1fAUsweBIrhL38726oIEAtDs=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "7872526e9c5332274ea5932a0c3270d6e4724f3b",
"rev": "bc27f0fde01ce4e1bfec1ab122d72b7380278e68",
"type": "github"
},
"original": {
@@ -148,11 +111,11 @@
},
"nixpkgs_3": {
"locked": {
"lastModified": 1706487304,
"narHash": "sha256-LE8lVX28MV2jWJsidW13D2qrHU/RUUONendL2Q/WlJg=",
"lastModified": 1728538411,
"narHash": "sha256-f0SBJz1eZ2yOuKUr5CA9BHULGXVSn6miBuUWdTyhUhU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "90f456026d284c22b3e3497be980b2e47d0b28ac",
"rev": "b69de56fac8c2b6f8fd27f2eca01dcda8e0a4221",
"type": "github"
},
"original": {
@@ -165,22 +128,21 @@
"root": {
"inputs": {
"android": "android",
"flake-utils": "flake-utils_3",
"flake-utils": "flake-utils_2",
"nixpkgs": "nixpkgs_2",
"rust-overlay": "rust-overlay"
}
},
"rust-overlay": {
"inputs": {
"flake-utils": "flake-utils_4",
"nixpkgs": "nixpkgs_3"
},
"locked": {
"lastModified": 1711073443,
"narHash": "sha256-PpNb4xq7U5Q/DdX40qe7CijUsqhVVM3VZrhN0+c6Lcw=",
"lastModified": 1733970833,
"narHash": "sha256-sPEKtSaZk2CtfF9cdhtbY93S6qGq+d2PKI1fcoDfDaI=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "eec55ba9fcde6be4c63942827247e42afef7fafe",
"rev": "f7f4c59ccdf1bec3f1547d27398e9589aa94e3e8",
"type": "github"
},
"original": {
@@ -218,36 +180,6 @@
"repo": "default",
"type": "github"
}
},
"systems_3": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_4": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
+3 -4
View File
@@ -15,12 +15,11 @@
pkgs = import nixpkgs { inherit system overlays; };
android-sdk = android.sdk.${system} (sdkPkgs:
with sdkPkgs; [
build-tools-33-0-1
build-tools-34-0-0
cmdline-tools-latest
ndk-bundle
platform-tools
platforms-android-34
ndk-23-2-8568313
ndk-27-0-11902837
]);
rust-version = pkgs.lib.removeSuffix "\n"
(builtins.readFile ./scripts/rust-toolchain);
@@ -28,7 +27,7 @@
devShells.default = pkgs.mkShell {
ANDROID_SDK_ROOT = "${android-sdk}/share/android-sdk";
ANDROID_NDK_ROOT =
"${android-sdk}/share/android-sdk/ndk/23.2.8568313";
"${android-sdk}/share/android-sdk/ndk/27.0.11902837";
buildInputs = [
android-sdk
pkgs.openjdk17
+4 -4
View File
@@ -28,7 +28,7 @@
"client_info": {
"mobilesdk_app_id": "1:922391085500:android:6f54e2c4e49405673e2bb9",
"android_client_info": {
"package_name": "chat.delta.lite.beta"
"package_name": "com.github.arcanechat.beta"
}
},
"oauth_client": [],
@@ -47,7 +47,7 @@
"client_info": {
"mobilesdk_app_id": "1:922391085500:android:aff82fbc40c8172e3e2bb9",
"android_client_info": {
"package_name": "chat.delta.lite"
"package_name": "com.github.arcanechat"
}
},
"oauth_client": [],
@@ -66,7 +66,7 @@
"client_info": {
"mobilesdk_app_id": "1:922391085500:android:92b4cf12669cc2083e2bb9",
"android_client_info": {
"package_name": "com.github.arcanechat"
"package_name": "chat.delta.lite"
}
},
"oauth_client": [],
@@ -85,7 +85,7 @@
"client_info": {
"mobilesdk_app_id": "1:922391085500:android:228a205b8aa2bacc3e2bb9",
"android_client_info": {
"package_name": "com.github.arcanechat.beta"
"package_name": "chat.delta.lite.beta"
}
},
"oauth_client": [],
+2 -2
View File
@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=ff7bf6a86f09b9b2c40bb8f48b25fc19cf2b2664fd1d220cd7ab833ec758d0d7
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip
distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
+36 -71
View File
@@ -7,57 +7,6 @@
#include "deltachat-core-rust/deltachat-ffi/deltachat.h"
#if __ANDROID_API__ == 16
unsigned long getauxval(unsigned long type) {
return 0;
}
#include <sys/socket.h>
#include <unistd.h>
int sendmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen,
int flags)
{
if (flags != 0) {
// Not supported by the fallback.
return -1;
}
if (vlen == 0) {
return 0;
}
ssize_t n = sendmsg(sockfd, &msgvec->msg_hdr, flags);
if (n == -1) {
return -1;
}
(*msgvec).msg_len = n;
return 1;
}
int recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen,
int flags, struct timespec *timeout)
{
if (flags != 0) {
// Not supported by the fallback.
return -1;
}
if (vlen == 0) {
return 0;
}
int n = recvmsg(sockfd, &msgvec->msg_hdr, flags);
if (n == -1) {
return -1;
}
(*msgvec).msg_len = n;
return 1;
}
#endif
static dc_msg_t* get_dc_msg(JNIEnv *env, jobject obj);
@@ -753,12 +702,6 @@ JNIEXPORT jboolean Java_com_b44t_messenger_DcContext_resendMsgs(JNIEnv *env, job
}
JNIEXPORT jint Java_com_b44t_messenger_DcContext_prepareMsg(JNIEnv *env, jobject obj, jint chat_id, jobject msg)
{
return dc_prepare_msg(get_dc_context(env, obj), chat_id, get_dc_msg(env, msg));
}
JNIEXPORT jint Java_com_b44t_messenger_DcContext_sendMsg(JNIEnv *env, jobject obj, jint chat_id, jobject msg)
{
return dc_send_msg(get_dc_context(env, obj), chat_id, get_dc_msg(env, msg));
@@ -780,12 +723,10 @@ JNIEXPORT jint Java_com_b44t_messenger_DcContext_sendVideochatInvitation(JNIEnv
}
JNIEXPORT jboolean Java_com_b44t_messenger_DcContext_sendWebxdcStatusUpdate(JNIEnv *env, jobject obj, jint msg_id, jstring payload, jstring descr)
JNIEXPORT jboolean Java_com_b44t_messenger_DcContext_sendWebxdcStatusUpdate(JNIEnv *env, jobject obj, jint msg_id, jstring payload)
{
CHAR_REF(payload);
CHAR_REF(descr);
jboolean ret = dc_send_webxdc_status_update(get_dc_context(env, obj), msg_id, payloadPtr, descrPtr) != 0;
CHAR_UNREF(descr);
jboolean ret = dc_send_webxdc_status_update(get_dc_context(env, obj), msg_id, payloadPtr, NULL) != 0;
CHAR_UNREF(payload);
return ret;
}
@@ -1423,12 +1364,6 @@ JNIEXPORT jint Java_com_b44t_messenger_DcMsg_getId(JNIEnv *env, jobject obj)
return dc_msg_get_id(get_dc_msg(env, obj));
}
JNIEXPORT jboolean Java_com_b44t_messenger_DcMsg_isOutgoing(JNIEnv *env, jobject obj)
{
return (jboolean)(dc_msg_is_outgoing(get_dc_msg(env, obj))!=0);
}
JNIEXPORT jint Java_com_b44t_messenger_DcMsg_getSenderColor(JNIEnv *env, jobject obj)
{
return dc_msg_get_sender_color(get_dc_msg(env, obj));
@@ -1626,15 +1561,18 @@ JNIEXPORT jstring Java_com_b44t_messenger_DcMsg_getWebxdcInfoJson(JNIEnv *env, j
}
JNIEXPORT jboolean Java_com_b44t_messenger_DcMsg_isForwarded(JNIEnv *env, jobject obj)
JNIEXPORT jstring Java_com_b44t_messenger_DcMsg_getWebxdcHref(JNIEnv *env, jobject obj)
{
return dc_msg_is_forwarded(get_dc_msg(env, obj))!=0;
char* temp = dc_msg_get_webxdc_href(get_dc_msg(env, obj));
jstring ret = JSTRING_NEW(temp);
dc_str_unref(temp);
return ret;
}
JNIEXPORT jboolean Java_com_b44t_messenger_DcMsg_isIncreation(JNIEnv *env, jobject obj)
JNIEXPORT jboolean Java_com_b44t_messenger_DcMsg_isForwarded(JNIEnv *env, jobject obj)
{
return dc_msg_is_increation(get_dc_msg(env, obj))!=0;
return dc_msg_is_forwarded(get_dc_msg(env, obj))!=0;
}
@@ -1714,6 +1652,33 @@ JNIEXPORT void Java_com_b44t_messenger_DcMsg_setFile(JNIEnv *env, jobject obj, j
}
JNIEXPORT void Java_com_b44t_messenger_DcMsg_forceSticker(JNIEnv *env, jobject obj)
{
dc_msg_force_sticker(get_dc_msg(env, obj));
}
JNIEXPORT jstring Java_com_b44t_messenger_DcMsg_getPOILocation(JNIEnv *env, jobject obj)
{
char* temp = dc_msg_get_poi_location(get_dc_msg(env, obj));
jstring ret = JSTRING_NEW(temp);
dc_str_unref(temp);
return ret;
}
JNIEXPORT void Java_com_b44t_messenger_DcMsg_setFileAndDeduplicate(JNIEnv *env, jobject obj, jstring file, jstring name, jstring filemime)
{
CHAR_REF(file);
CHAR_REF(name);
CHAR_REF(filemime);
dc_msg_set_file_and_deduplicate(get_dc_msg(env, obj), filePtr, namePtr, filemimePtr);
CHAR_UNREF(filemime);
CHAR_UNREF(name);
CHAR_UNREF(file);
}
JNIEXPORT void Java_com_b44t_messenger_DcMsg_setDimension(JNIEnv *env, jobject obj, int width, int height)
{
dc_msg_set_dimension(get_dc_msg(env, obj), width, height);
+1 -1
View File
@@ -1 +1 @@
../deltachat-pages/tools/create-local-help.py ../deltachat-pages/_site src/main/assets/help
../deltachat-pages/tools/create-local-help.py ../deltachat-pages/result src/main/assets/help
+11 -10
View File
@@ -38,8 +38,6 @@
#
# If anything doesn't work, please open an issue!!
"$(dirname "$0")/rebrand.sh"
set -e
echo "starting time: `date`"
@@ -77,9 +75,9 @@ if test -z "$NDK_HOST_TAG"; then
fi
TOOLCHAIN="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$NDK_HOST_TAG"
export CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER="$TOOLCHAIN/bin/armv7a-linux-androideabi16-clang"
export CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER="$TOOLCHAIN/bin/armv7a-linux-androideabi21-clang"
export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="$TOOLCHAIN/bin/aarch64-linux-android21-clang"
export CARGO_TARGET_I686_LINUX_ANDROID_LINKER="$TOOLCHAIN/bin/i686-linux-android16-clang"
export CARGO_TARGET_I686_LINUX_ANDROID_LINKER="$TOOLCHAIN/bin/i686-linux-android21-clang"
export CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER="$TOOLCHAIN/bin/x86_64-linux-android21-clang"
export RUSTUP_TOOLCHAIN=$(cat "$(dirname "$0")/rust-toolchain")
@@ -125,10 +123,10 @@ unset CPATH
if test -z $1 || test $1 = armeabi-v7a; then
echo "-- cross compiling to armv7-linux-androideabi (arm) --"
TARGET_CC="$TOOLCHAIN/bin/armv7a-linux-androideabi16-clang" \
TARGET_CC="$TOOLCHAIN/bin/armv7a-linux-androideabi21-clang" \
TARGET_AR="$TOOLCHAIN/bin/llvm-ar" \
TARGET_RANLIB="$TOOLCHAIN/bin/llvm-ranlib" \
cargo build $RELEASEFLAG --target armv7-linux-androideabi -p deltachat_ffi --features jsonrpc
cargo build $RELEASEFLAG --target armv7-linux-androideabi -p deltachat_ffi
cp $CARGO_TARGET_DIR/armv7-linux-androideabi/$RELEASE/libdeltachat.a $jnidir/armeabi-v7a
fi
@@ -137,16 +135,16 @@ if test -z $1 || test $1 = arm64-v8a; then
TARGET_CC="$TOOLCHAIN/bin/aarch64-linux-android21-clang" \
TARGET_AR="$TOOLCHAIN/bin/llvm-ar" \
TARGET_RANLIB="$TOOLCHAIN/bin/llvm-ranlib" \
cargo build $RELEASEFLAG --target aarch64-linux-android -p deltachat_ffi --features jsonrpc
cargo build $RELEASEFLAG --target aarch64-linux-android -p deltachat_ffi
cp $CARGO_TARGET_DIR/aarch64-linux-android/$RELEASE/libdeltachat.a $jnidir/arm64-v8a
fi
if test -z $1 || test $1 = x86; then
echo "-- cross compiling to i686-linux-android (x86) --"
TARGET_CC="$TOOLCHAIN/bin/i686-linux-android16-clang" \
TARGET_CC="$TOOLCHAIN/bin/i686-linux-android21-clang" \
TARGET_AR="$TOOLCHAIN/bin/llvm-ar" \
TARGET_RANLIB="$TOOLCHAIN/bin/llvm-ranlib" \
cargo build $RELEASEFLAG --target i686-linux-android -p deltachat_ffi --features jsonrpc
cargo build $RELEASEFLAG --target i686-linux-android -p deltachat_ffi
cp $CARGO_TARGET_DIR/i686-linux-android/$RELEASE/libdeltachat.a $jnidir/x86
fi
@@ -155,7 +153,7 @@ fi
TARGET_CC="$TOOLCHAIN/bin/x86_64-linux-android21-clang" \
TARGET_AR="$TOOLCHAIN/bin/llvm-ar" \
TARGET_RANLIB="$TOOLCHAIN/bin/llvm-ranlib" \
cargo build $RELEASEFLAG --target x86_64-linux-android -p deltachat_ffi --features jsonrpc
cargo build $RELEASEFLAG --target x86_64-linux-android -p deltachat_ffi
cp $CARGO_TARGET_DIR/x86_64-linux-android/$RELEASE/libdeltachat.a $jnidir/x86_64
fi
@@ -176,4 +174,7 @@ else
rm -f ndkArch # Remove ndkArch, ignore if it doesn't exist
fi
"$(dirname "$0")/rebrand.sh"
echo "ending time: `date`"
+1 -1
View File
@@ -1 +1 @@
1.77.0
1.83.0
+1
View File
@@ -4,3 +4,4 @@ find ./src/main/assets/help/ -type f -name '*.html' | xargs sed -i 's/github.com
find ./src/main/assets/help/ -type f -name '*.html' | xargs sed -i 's/ArcaneChat/Delta Chat/g'
find ./src/ -type f -name 'strings.xml' | xargs sed -i 's/github.com\/ArcaneChat/get.delta.chat/g'
find ./src/ -type f -name 'strings.xml' | xargs sed -i 's/ArcaneChat/Delta Chat/g'
sed -i 's/>Delta Chat</>ArcaneChat</g' ./src/main/res/values/strings.xml
+2
View File
@@ -1,3 +1,5 @@
#!/usr/bin/env bash
set -e # stop on all errors
git submodule update --init --recursive
+1 -1
View File
@@ -1,3 +1,4 @@
#!/usr/bin/env bash
VERSION=$1
@@ -29,7 +30,6 @@ echo ""
echo "and now: here is Delta Chat $VERSION - choose your flavour and mind your backups:"
echo "- 🍋 https://download.delta.chat/android/beta/deltachat-gplay-release-$VERSION.apk (google play candidate, overwrites existing installs, should keep data)"
echo "- 🍉 https://download.delta.chat/android/beta/deltachat-foss-debug-$VERSION.apk (f-droid candidate, can be installed beside google play)"
echo "- 🍏 https://testflight.apple.com/join/uEMc1NxS (ios, update to $VERSION may take a day or so)"
echo ""
echo "what to test: PLEASE_FILL_OUT"
+1
View File
@@ -1,3 +1,4 @@
#!/usr/bin/env bash
VERSION=$1
@@ -93,7 +93,7 @@ public class SharingTest {
}
}
Uri uri = Uri.parse("content://" + BuildConfig.APPLICATION_ID + ".attachments/" + Uri.encode(pngImage));
DcHelper.sharedFiles.put("/" + pngImage, 1);
DcHelper.sharedFiles.put(pngImage, 1);
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("image/png");
@@ -28,11 +28,6 @@ public class FcmReceiveService extends FirebaseMessagingService {
private static volatile String prefixedToken;
public static void register(Context context) {
if (Build.VERSION.SDK_INT < 19) {
Log.w(TAG, "FCM not available on SDK < 19");
triedRegistering = true;
return;
}
if (FcmReceiveService.prefixedToken != null) {
Log.i(TAG, "FCM already registered");
+9 -3
View File
@@ -20,7 +20,6 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
@@ -66,6 +65,10 @@
android:resource="@xml/automotive_app_desc" />
-->
<!-- Opt out of metrics collection: https://developer.android.com/develop/ui/views/layout/webapps/managing-webview#metrics -->
<meta-data android:name="android.webkit.WebView.MetricsOptOut"
android:value="true" />
<activity android:name=".ShareActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:excludeFromRecents="true"
@@ -325,8 +328,6 @@
android:theme="@style/TextSecure.ScribbleTheme"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name="com.soundcloud.android.crop.CropImageActivity" />
<activity android:name=".InstantOnboardingActivity"
android:theme="@style/TextSecure.LightTheme"
android:windowSoftInputMode="stateHidden|adjustResize"
@@ -385,6 +386,11 @@
android:exported="true">
</activity>
<activity android:name=".WebxdcStoreActivity"
android:theme="@style/TextSecure.LightTheme"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize|uiMode">
</activity>
<activity android:name=".FullMsgActivity"
android:theme="@style/TextSecure.LightTheme"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize">
+47 -10
View File
@@ -99,6 +99,7 @@
<li><a href="#lze-delta-chat-používat-s-protonmail--tutanota--criptext">Lze Delta Chat používat s Protonmail / Tutanota / Criptext?</a></li>
<li><a href="#remove-account">How can I delete my account?</a></li>
<li><a href="#mám-zájem-o-technické-podrobnosti-kde-najdu-víc">Mám zájem o technické podrobnosti. Kde najdu víc?</a></li>
<li><a href="#where-can-my-friends-find-delta-chat">Where can my friends find Delta Chat?</a></li>
<li><a href="#jak-je-financován-vývoj-delta-chatu">Jak je financován vývoj Delta Chatu?</a></li>
</ul>
</li>
@@ -297,8 +298,7 @@ Archived chats remain accessible above the chat list or via search.</p>
</li>
</ul>
<p>To archive or pin a chat, long tap (Android), use the chats menu (Android/Desktop) or swipe to the left (iOS);
to mute a chat, use the chats menu (Android/Desktop) or the chats profile (iOS).</p>
<p>To use the functions, long tap or right click a chat in the chat list.</p>
<h3 id="what-does-the-green-dot-mean">
@@ -599,16 +599,16 @@ to any system involved in the delivery of Push Notifications.</p>
<ul>
<li>
<p>A Delta Chat app obtains a “device token” locally and stores it
<p>A Delta Chat app obtains a “device token” locally, encrypts it and stores it
on the <a href="https://delta.chat/chatmail">chatmail</a> server.</p>
</li>
<li>
<p>When a <a href="https://delta.chat/chatmail">chatmail</a> server receives an e-mail for a Delta Chat user
it forwards the device token to the central Delta Chat notification proxy.</p>
it forwards the encrypted device token to the central Delta Chat notification proxy.</p>
</li>
<li>
<p>The central Delta Chat notification proxy forwards
the “device token” to the respective Push service (Apple, Google, etc.),
<p>The central Delta Chat notification proxy decrypts the device token
and forwards it to the respective Push service (Apple, Google, etc.),
without ever knowing the IP or e-mail address of Delta Chat users.</p>
</li>
<li>
@@ -621,14 +621,15 @@ and also never see any message content (also not in encrypted forms).</p>
</li>
</ul>
<p>As of May 2024, chatmail servers know about “device tokens”
but we plan to encrypt this information to the notification proxy
such that the chatmail server never learns the device token.</p>
<p>The central Delta Chat notification proxy <a href="https://github.com/deltachat/notifiers">is small and fully implemented in Rust</a>
and forgets about device-tokens as soon as Apple/Google/etc processed them,
usually in a matter of milliseconds.</p>
<p>Note that the device token is encrypted between apps and notification proxy
but it is not signed.
The notification proxy thus never sees e-mail addresses, IP-addresses or
any cryptographic identity information associated with a users device (token).</p>
<p>Resulting from this overall privacy design, even the seizure of a chatmail server,
or the full seizure of the central Delta Chat notification proxy
would not reveal private information that Push services do not already have.</p>
@@ -1309,6 +1310,12 @@ One device is not needed for the other to work.</p>
and make sure, <strong>Private Network</strong> is selected as “Network profile type”
(after transfer, you can change back to the original value)</p>
</li>
<li>
<p>On <strong>iOS</strong>, make sure “System Settings / Apps / Delta Chat / <strong>Local Network</strong>” access is granted</p>
</li>
<li>
<p>On <strong>macOS</strong>, enable “System Settings / Privacy &amp; Security / <strong>Local Network</strong> / Delta Chat”</p>
</li>
<li>
<p>Your system might have a “personal firewall”,
which is known to cause problems (especially on Windows).
@@ -1425,6 +1432,7 @@ you only open attachments from senders you trust, and not from spammers.</li>
<ul>
<li>In general, anyone can share webxdc apps with each
other without restrictions.</li>
<li>From <a href="https://webxdc.org/apps/">webxdc.org/apps</a>.</li>
<li>You can <a href="https://delta.chat/en/2023-08-11-xstore">send hi to xstore@testrun.org</a>
to see an experimental webxdc appstore.
All of the apps are open source and for free.</li>
@@ -1874,6 +1882,35 @@ Otherwise you might receive undecryptable messages from those group chats.</p>
<li>Dobrý začátek je <a href="https://github.com/deltachat/deltachat-core-rust/blob/master/standards.md#standards-used-in-delta-chat">Standards used in Delta Chat</a>.</li>
</ul>
<h3 id="where-can-my-friends-find-delta-chat">
Where can my friends find Delta Chat? <a href="#where-can-my-friends-find-delta-chat" class="anchor"></a>
</h3>
<p>Delta Chat is available for all major and some minor platforms:</p>
<ul>
<li>
<p>The <strong>official website</strong>, <a href="https://delta.chat/download">https://delta.chat/download</a> shows all options in detail</p>
</li>
<li>
<p>If unavailable, use the <strong>mirror</strong> at <a href="https://deltachat.github.io/deltachat-pages">https://deltachat.github.io/deltachat-pages</a></p>
</li>
<li>
<p>Open one of the following <strong>app stores and search for “Delta Chat”:</strong>
Google Play Store, F-Droid, Huawei App Gallery, Amazon App Store, iOS and macOS App Store, Microsoft Store</p>
</li>
<li>
<p>Check the <strong>package manager</strong> of your Linux distributions</p>
</li>
<li>
<p><strong>Android APKs</strong> are also available on <a href="https://github.com/deltachat/deltachat-android/releases">https://github.com/deltachat/deltachat-android/releases</a></p>
</li>
</ul>
<h3 id="jak-je-financován-vývoj-delta-chatu">
+85 -49
View File
@@ -30,14 +30,14 @@
<li><a href="#was-sind-push-benachrichtigungen-wie-kann-ich-nachrichten-sofort-erhalten">Was sind Push-Benachrichtigungen? Wie kann ich Nachrichten sofort erhalten?</a></li>
<li><a href="#sind-push-benachrichtigungen-auf-ios-geräten-aktiviert-gibt-es-alternativen">Sind Push-Benachrichtigungen auf iOS-Geräten aktiviert? Gibt es Alternativen?</a></li>
<li><a href="#android-push">Sind Push-Benachrichtigungen auf Android-Geräten aktiviert/erforderlich?</a></li>
<li><a href="#privacy-notifications">Wie privat sind Delta Chat Push-Benachrichtigungen?</a></li>
<li><a href="#privacy-notifications">Wie privat sind Delta-Chat-Push-Benachrichtigungen?</a></li>
<li><a href="#warum-integriert-sich-delta-chat-in-zentralisierte-proprietäre-applegoogle-push-dienste">Warum integriert sich Delta Chat in zentralisierte, proprietäre Apple/Google-Push-Dienste?</a></li>
</ul>
</li>
<li><a href="#verschlüsselung-und-sicherheit">Verschlüsselung und Sicherheit</a>
<ul>
<li><a href="#welche-standards-werden-für-die-ende-zu-ende-verschlüsselung-verwendet">Welche Standards werden für die Ende-zu-Ende-Verschlüsselung verwendet?</a></li>
<li><a href="#whene2e">Wie kann ich wissen, ob Nachrichten Ende-zu-Ende verschlüsselt sind?</a></li>
<li><a href="#whene2e">Wie kann ich wissen, ob Nachrichten Ende-zu-Ende-verschlüsselt sind?</a></li>
<li><a href="#howtoe2ee">Wie kann ich garantierte Ende-zu-Ende-Verschlüsselung und grüne Häkchen erhalten?</a></li>
<li><a href="#e2eeguarantee">Was bedeuten das “Grüne Häkchen” und die “garantierte Ende-zu-Ende-Verschlüsselung”?</a></li>
<li><a href="#nocryptanymore">Ein Kontakt hat eine Nachricht von einem anderen Gerät gesendet”, was kann ich tun?</a></li>
@@ -65,10 +65,10 @@
<li><a href="#kann-ich-delta-chat-auf-mehreren-geräten-zur-selben-zeit-verwenden">Kann ich Delta Chat auf mehreren Geräten zur selben Zeit verwenden?</a></li>
<li><a href="#fehlersuche">Fehlersuche</a></li>
<li><a href="#backup">Manueller Transfer</a></li>
<li><a href="#gibt-es-pläne-für-eine-delta-chat-web-anwendung">Gibt es Pläne für eine Delta Chat Web-Anwendung?</a></li>
<li><a href="#gibt-es-pläne-für-eine-delta-chat-web-anwendung">Gibt es Pläne für eine Delta-Chat-Web-Anwendung?</a></li>
</ul>
</li>
<li><a href="#webxdc">Webxdc Apps</a>
<li><a href="#webxdc">Webxdc-Apps</a>
<ul>
<li><a href="#wie-privat-sind-webxdc-apps">Wie privat sind Webxdc Apps?</a></li>
<li><a href="#wo-bekomme-ich-webxdc-apps">Wo bekomme ich Webxdc Apps?</a></li>
@@ -99,6 +99,7 @@
<li><a href="#ist-delta-chat-kompatibel-mit-protonmail--tutanota--criptext">Ist Delta Chat kompatibel mit Protonmail / Tutanota / Criptext?</a></li>
<li><a href="#remove-account">Wie kann ich mein Konto löschen?</a></li>
<li><a href="#ich-bin-an-technischen-details-interessiert-gibt-es-hierzu-weitere-infos">Ich bin an technischen Details interessiert. Gibt es hierzu weitere Infos?</a></li>
<li><a href="#wo-können-meine-freunde-delta-chat-finden">Wo können meine Freunde Delta Chat finden?</a></li>
<li><a href="#wie-wird-delta-chat-finanziert">Wie wird Delta Chat finanziert?</a></li>
</ul>
</li>
@@ -152,7 +153,7 @@ auch wenn der Empfänger Delta Chat nicht benutzt.</p>
die sofortige Push-Benachrichtigungen für iOS- und Android-Geräte bieten.</p>
</li>
<li>
<p>Durchgängige <a href="#multiple-accounts">Multi-Profil</a> und Multi-Geräte-Unterstützung auf allen Plattformen.</p>
<p>Durchgängige <a href="#multiple-accounts">Multi-Profil-</a> und Multi-Geräte-Unterstützung auf allen Plattformen.</p>
</li>
<li>
<p>Interaktive <a href="https://webxdc.org/apps">Webanwendungen in Chats</a> für Spiele und für die Zusammenarbeit</p>
@@ -286,7 +287,7 @@ unter dem Text Ihrer Nachrichten.</p>
</li>
</ul>
<p>Zum Archivieren oder Anheften, tippen Sie lange auf den Chat (Android), verwenden Sie das Chatmenü (Android/Desktop) oder wischen Sie nach links (iOS); zum Stummschalten, verwenden Sie das Chatmenü (Android/Desktop) oder das Chatprofil (iOS).</p>
<p>Um die Funktionen zu nutzen, lang auf einen Chat in der Chatliste tippen oder den Chat mit der rechten Maustaste anklicken.</p>
<h3 id="was-bedeutet-der-grüne-punkt">
@@ -303,7 +304,7 @@ unter dem Text Ihrer Nachrichten.</p>
<li>entweder weil der Kontakt Ihnen direkt eine Nachricht gesendet hat,</li>
<li>weil der Kontakt etwas an eine Gruppe geschrieben hat, in der sie beide Mitglied sind,</li>
<li>weil der Kontakt Ihnen eine Lesebestätigung für eine von Ihnen geschriebene Nachricht gesendet hat</li>
<li>oder weil der Kontakt Daten mithilfe einer <a href="#webxdc">Webxdc App</a> an Ihre Delta Chat-App gesendet hat.</li>
<li>oder weil der Kontakt Daten mithilfe einer <a href="#webxdc">Webxdc-App</a> an Ihre Delta-Chat-App gesendet hat.</li>
</ul>
</li>
<li>Dies ist also kein Echtzeit-Online-Status - und wenn jemand nicht sofort antwortet, obwohl er online zu sein scheint, machen Sie sich keine Sorgen und geben Sie ihm etwas Raum. ;-)</li>
@@ -486,7 +487,7 @@ und Benachrichtigungen auf dem Telefon des Nutzers anzeigen kann.</p>
<p>iOS-Geräten, durch die Integration mit den Apple-Push-Diensten.</p>
</li>
<li>
<p>Android-Geräten, durch die Integration des Google FCM Push-Dienste,
<p>Android-Geräten, durch die Integration des Google-FCM-Push-Dienstes,
auch auf Geräten, die <a href="https://microg.org">microG</a>
anstelle von proprietärem Google-Code auf dem Telefon.</p>
</li>
@@ -517,7 +518,7 @@ keine Daten an Apple weitergibt, die Apple nicht bereits hat.</p>
</h3>
<p>Wenn ein „Push-Service“ verfügbar ist, aktiviert Delta Chat Push-Benachrichtigungen
<p>Wenn ein „Push-Service“ verfügbar ist, aktiviert Delta Chat Push-Benachrichtigungen,
um eine sofortige Nachrichtenzustellung für alle Chatmail-Benutzer zu erreichen.
Wenn Sie einen klassischen E-Mail-Anbieter anstelle von <a href="https://delta.chat/chatmail">chatmail</a> Servern verwenden,
sind Push-Benachrichtigungen nicht verfügbar.</p>
@@ -543,7 +544,7 @@ können sicher ausprobiert werden, wenn Sie feststellen, dass Nachrichten nur mi
<h3 id="privacy-notifications">
Wie privat sind Delta Chat Push-Benachrichtigungen? <a href="#privacy-notifications" class="anchor"></a>
Wie privat sind Delta-Chat-Push-Benachrichtigungen? <a href="#privacy-notifications" class="anchor"></a>
</h3>
@@ -556,16 +557,15 @@ an irgendein System, das an der Zustellung von Push-Benachrichtigungen beteiligt
<ul>
<li>
<p>Eine Delta-Chat-Anwendung erhält lokal ein „Geräte-Token“ (eine zufällige Zahl) und speichert es
<p>Eine Delta-Chat-Anwendung erhält lokal ein „Geräte-Token“, verschlüsselt und speichert es
auf dem <a href="https://delta.chat/chatmail">Chatmail</a>-Server.</p>
</li>
<li>
<p>Wenn ein <a href="https://delta.chat/chatmail">Chatmail</a>-Server eine E-Mail für einen Delta Chat-Benutzer erhält
erhält, leitet er den „Geräte-Token an den zentralen Delta-Chat-Benachrichtigungs-Proxy weiter.</p>
<p>Wenn ein <a href="https://delta.chat/chatmail">Chatmail</a>-Server eine E-Mail für einen Delta-Chat-Benutzer erhält
erhält, leitet er das verschlüsselte Geräte-Token an den zentralen Delta-Chat-Benachrichtigungs-Proxy weiter.</p>
</li>
<li>
<p>Der zentrale Delta-Chat-Benachrichtigungs-Proxy leitet
das „Geräte-Token“ an den jeweiligen Push-Dienst (Apple, Google, etc.) weiter,
<p>Der zentrale Delta-Chat-Benachrichtigungs-Proxy entschlüsselt das Geräte-Token und leitet es an den jeweiligen Push-Dienst (Apple, Google, etc.) weiter,
ohne jemals die IP- oder E-Mail-Adresse des Delta-Chat-Benutzers zu kennen.</p>
</li>
<li>
@@ -577,14 +577,15 @@ und auch nie den Inhalt einer Nachricht (auch nicht in verschlüsselter Form).</
</li>
</ul>
<p>Stand Mai 2024 kennen die Chatmail-Server die Geräte-Token,
aber wir planen, diese Informationen an den Benachrichtigungs-Proxy zu verschlüsseln
zu verschlüsseln, so dass der Chatmail-Server niemals das „Geräte-Token“ erfährt.</p>
<p>Der zentrale Delta-Chat-Benachrichtigungs-Proxy <a href="https://github.com/deltachat/notifiers">ist klein und vollständig in Rust implementiert</a>
und vergisst die Geräte-Token, sobald Apple/Google/etc. sie verarbeitet hat,
normalerweise innerhalb weniger Millisekunden.</p>
<p>Beachten Sie, dass das Geräte-Token zwischen Anwendungen und dem Benachrichtigungs-Proxy verschlüsselt,
aber nicht signiert ist.
Der Benachrichtigungs-Proxy sieht also niemals E-Mail-Adressen, IP-Adressen oder
irgendwelche kryptografischen Identitätsinformationen, die mit dem Gerät oder dem Geräte-Token eines Nutzers verbunden sind.</p>
<p>Aufgrund dieses umfassenden Datenschutzkonzepts würde sogar die Beschlagnahmung eines Chatmail-Servers,
oder die vollständige Beschlagnahmung des zentralen Delta-Chat-Benachrichtigungsproxys
keine privaten Informationen preisgeben, die den zentralen Push-Diensten nicht bereits vorliegen.</p>
@@ -626,7 +627,7 @@ Willkommen bei der Macht des interoperablen und massiven Chatmail- und E-Mail-Sy
<p><a href="https://autocrypt.org">Autocrypt</a> wird verwendet, um automatisch
eine Ende-zu-Ende-Verschlüsselung mit Kontakten und Gruppenchats herzustellen.
Autocrypt verwendet eine begrenzte und <a href="#openpgp-secure">sichere Untermenge des OpenPGP-Standards</a>.
Ende-zu-Ende verschlüsselte Nachrichten sind mit einem Vorhängeschloss gekennzeichnet <img style="vertical-align:middle; width:1.2em; margin:1px" src="../lock-icon.png" alt="padlock" /></p>
Ende-zu-Ende-verschlüsselte Nachrichten sind mit einem Vorhängeschloss gekennzeichnet <img style="vertical-align:middle; width:1.2em; margin:1px" src="../lock-icon.png" alt="padlock" /></p>
<p><a href="https://securejoin.delta.chat/en/latest/new.html">Secure-Join-Protokolle</a>
werden für Chats mit garantierter Ende-zu-Ende-Verschlüsselung verwendet,
@@ -638,7 +639,7 @@ garantieren Ende-zu-Ende-verschlüsselte Nachrichten.</p>
<h3 id="whene2e">
Wie kann ich wissen, ob Nachrichten Ende-zu-Ende verschlüsselt sind? <a href="#whene2e" class="anchor"></a>
Wie kann ich wissen, ob Nachrichten Ende-zu-Ende-verschlüsselt sind? <a href="#whene2e" class="anchor"></a>
</h3>
@@ -729,7 +730,7 @@ Das Einführen geschieht automatisch, wenn Sie Mitglieder zu Gruppen hinzufügen
Wer einen Kontakt zu einer Gruppe mit grünem Häkchen hinzufügt, wird zum Einführenden
für die Mitglieder, die noch nichts von dem hinzugefügten Kontakt wussten.
In einem Kontaktprofil können Sie wiederholt auf den Text “Eingeführt von …” tippen
bis du zu demjenigen gelangst, mit dem Sie einen direkten <a href="#howtoe2ee">QR-Scan</a> gemacht haben.</p>
bis Sie zu demjenigen gelangen, mit dem Sie einen direkten <a href="#howtoe2ee">QR-Scan</a> gemacht haben.</p>
<p>Beachten Sie, dass Sie in einem Kontaktprofil unter Umständen Einführende sehen und antippen können, aber kein grünes Häkchen im Profiltitel vorhanden ist.
Dies bedeutet normalerweise, dass der Kontakt <a href="#nocryptanymore">“eine Nachricht von einem anderen Gerät gesendet hat”</a>.</p>
@@ -760,7 +761,7 @@ auch wenn der Kontakt dort Mitglied ist.</p>
<p><strong>Ihr Kontakt verwendet Delta Chat auf einem zweiten Gerät (Smartphone oder Laptop)</strong></p>
<p>Wenn Ihr Kontakt ein weiteres Gerät mit Delta Chat eingerichtet hat,
sollte das Konto von dem neuen Gerät entfernen werden und <a href="#multiclient">als zweites Gerät, wie hier beschrieben</a> erneut hinzugefügt werden.
sollte das Konto von dem neuen Gerät entfernen werden und <a href="#multiclient">als zweites Gerät, wie hier beschrieben</a>, erneut hinzugefügt werden.
Sobald sie sich danach schreiben, wird die Warnung verschwinden
und die Verschlüsselung ist mit beiden Geräten Ihres Kontakts garantiert.</p>
@@ -882,7 +883,7 @@ wenn dieser falsch ist.</p>
<p>Delta Chat war auch nie anfällig für den EFAIL-Angriff “Direct Exfiltration”,
da nur <code class="language-plaintext highlighter-rouge">multipart/encrypted</code> Nachrichten entschlüsselt werden,
die genau einen verschlüsselten und signierten Teil enthalten;
so wie in der Autocrypt Level 1 Spezifikation definiert.</p>
so wie in der Autocrypt-Level-1-Spezifikation definiert.</p>
<h3 id="tls">
@@ -948,7 +949,7 @@ Nachrichten an die Geräte der Empfänger weiterzuleiten und zuzustellen.</p>
</h3>
<p>Sowohl zum Schutz vor E-Mail-Servern, die Metadaten sammeln
<p>Sowohl zum Schutz vor E-Mail-Servern, die Metadaten sammeln,
als auch gegen die Gefahr der Beschlagnahmung von Geräten
empfehlen wir die Verwendung einer für Delta Chat optimierten <a href="https://delta.chat/serverguide">E-Mail-Server-Instanz</a>, um pseudonym-temporäre Konten durch Scannen von QR-Codes zu erstellen.
Beachten Sie, dass Delta-Chat-Apps auf allen Plattformen mehrere Konten unterstützen.
@@ -995,7 +996,7 @@ ohne Ende-zu-Ende-Unterstützung verwendet.</p>
</h3>
<p>Wenn ein Kontakt keine Autocrypt-fähige App verwendet,
werden alle Nachrichten, die diesen Kontakt betreffen (in Gruppen- oder Direkt-Chats)
werden alle Nachrichten, die diesen Kontakt betreffen (in Gruppen- oder Direkt-Chats),
nicht Ende-zu-Ende-verschlüsselt und zeigen daher kein “Vorhängeschloss”.
Beachten Sie, auch Kontakte, die primär Delta Chat verwenden,
können gleichzeitig auch nicht-Autocrypt-fähige Apps verwenden.
@@ -1011,7 +1012,7 @@ um zu verhindern, dass unlesbare Nachrichten auf der Seite Ihrer Kontakte ankomm
</h3>
<p>Wenn Sie einen sicheren Ende-zu-Ende-verschlüsselten Chat mit einem Kontakt benötigen,
der sowohl Delta Chat als auch nicht-Autocrypt-Anwendungen nutzt,
der sowohl Delta Chat als auch Nicht-Autocrypt-Anwendungen nutzt,
können Sie eine <a href="#howtoe2ee">garantierte Ende-zu-Ende-Verschlüsselung</a> einrichten, mit einer Gruppe mit Ihnen beiden als Mitgliedern.
In diesem Gruppenchat werden alle Nachrichten Ende-zu-Ende verschlüsselt werdejn,
auch wenn im Direkt-Chat eine
@@ -1025,10 +1026,10 @@ auch wenn im Direkt-Chat eine
</h3>
<p>Der beste Weg, um sicherzustellen, dass alle Nachrichten Ende-zu-Ende verschlüsselt sind
<p>Der beste Weg, um sicherzustellen, dass alle Nachrichten Ende-zu-Ende-verschlüsselt sind
und Metadaten so schnell wie möglich gelöscht werden,
ist <a href="#howtoe2ee">die Verwendung von Chats mit garantierter Ende-zu-Ende-Verschlüsselung</a>
und die Aktivierung von <a href="#ephemeralmsgs">Verschwindende Nachrichten</a>.</p>
und die Aktivierung von <a href="#ephemeralmsgs">verschwindenden Nachrichten</a>.</p>
<p>Garantierte Ende-zu-Ende-Verschlüsselung schützt vor <a href="https://en.wikipedia.org/wiki/Man-in-the-middle_attack">MITM-Angriffen</a>
und das Aktivieren von “Verschwindende Nachrichten” löscht die Nachrichten
@@ -1045,7 +1046,7 @@ auf dem Server und Lokal nach einer vom Benutzer eingestellten Zeit.</p>
</h3>
<p>Nein, Delta Chat unterstützt kein “Perfect Forward Secrecy” (PFS).
Das bedeutet, dass wenn Ihr privater Delta-Chat-Schlüssel durchgesickert ist,
Das bedeutet, wenn Ihr privater Delta-Chat-Schlüssel durchgesickert ist
und jemand Ihre vorherigen In-Transit-Nachrichten gesammelt hat,
können diese mit dem veröffentlichtem Schlüssel entschlüsselt werden.</p>
@@ -1056,7 +1057,7 @@ Die typische, reale Situation für durchgesickerte private Schlüssel, ist die <
OpenPGP ist nur ein Container für verschlüsselte Nachrichten mit dem
die Verwaltung der Schlüssel (und damit die Schlüsselrotation oder das Schlüssel-“Ratcheting”)
auf flexible Weise organisiert werden kann.
Siehe <a href="https://gitlab.com/sequoia-pgp/openpgp-dr">Seqouias PFS-Prototyp</a>
Siehe <a href="https://gitlab.com/sequoia-pgp/openpgp-dr">Seqouias PFS-Prototyp</a>
für bestehende Experimente in der OpenPGP-Community.</p>
<h3 id="ist-die-ende-zu-ende-verschlüsselung-von-delta-chat-genauso-sicher-wie-die-von-signal">
@@ -1145,7 +1146,7 @@ Für andere Programme können Sie online eine Lösung finden.</p>
Weitere Informationen finden Sie in unserem Blogbeitrag über <a href="https://delta.chat/en/2024-03-25-crypto-analysis-securejoin">Hardening Guaranteed End-to-End encryption</a> und in der hinterher publizierten <a href="https://eprint.iacr.org/2024/918.pdf">Kryptografischen Analyse von Delta Chat</a></p>
</li>
<li>
<p>Im April 2023 haben wir Sicherheits- und Datenschutzprobleme mit den “In Chats geteilten Apps”-Feature behoben, die mit Fehlern beim Sandboxing, insbesondere mit Chromium zusammenhängen. Wir haben daraufhin eine unabhängige Sicherheitsprüfung von Cure53 durchführen lassen, und alle gefundenen Probleme wurden mit den im April 2023 veröffentlichten 1.36 Releases behoben. Siehe <a href="https://delta.chat/en/2023-05-22-webxdc-security">hier für die vollständige Hintergrundgeschichte</a>.</p>
<p>Im April 2023 haben wir Sicherheits- und Datenschutzprobleme mit dem “In Chats geteilten Apps”-Feature behoben, die mit Fehlern beim Sandboxing, insbesondere mit Chromium zusammenhängen. Wir haben daraufhin eine unabhängige Sicherheitsprüfung von Cure53 durchführen lassen, und alle gefundenen Probleme wurden mit den im April 2023 veröffentlichten 1.36 Releases behoben. Siehe <a href="https://delta.chat/en/2023-05-22-webxdc-security">hier für die vollständige Hintergrundgeschichte</a>.</p>
</li>
<li>
<p>Im März 2023 analysierte <a href="https://cure53.de">Cure53</a> sowohl die Transportverschlüsselung von Delta Chats Netzwerkverbindungen als auch das reproduzierbare Mailserver-Setup wie <a href="https://delta.chat/de/serverguide">auf dieser Seite empfohlen</a>. Sie können mehr über das Audit <a href="https://delta.chat/en/2023-03-27-third-independent-security-audit">in unserem Blog</a> lesen oder Sie lesen den <a href="https://delta.chat/assets/blog/MER-01-report.pdf">vollständigen Bericht hier</a>.</p>
@@ -1155,7 +1156,7 @@ Weitere Informationen finden Sie in unserem Blogbeitrag über <a href="https://d
Es wurden keine kritischen oder hochgradig gefährlichen Probleme gefunden. Der Bericht wies auf einige Schwachstellen mittlerer Schwere hin - sie stellen für sich genommen keine Bedrohung für Delta-Chat-Benutzer dar, da sie von der Umgebung abhängen, in der Delta Chat verwendet wird. Aus Gründen der Benutzerfreundlichkeit und der Kompatibilität können wir nicht alle Schwachstellen beseitigen und haben beschlossen, Sicherheitsempfehlungen für bedrohte Benutzer zu geben. Sie können den <a href="https://delta.chat/assets/blog/2020-second-security-review.pdf">vollständigen Bericht hier</a> lesen.</p>
</li>
<li>
<p>Im Jahr 2019 analysierte <a href="https://includesecurity.com">Include Security</a> die von Delta Chat verwendeten <a href="https://github.com/rpgp/rpgp">PGP</a> und <a href="https://github.com/RustCrypto/RSA">RSA</a> Bibliotheken.
<p>Im Jahr 2019 analysierte <a href="https://includesecurity.com">Include Security</a> die von Delta Chat verwendeten <a href="https://github.com/rpgp/rpgp">PGP-</a> und <a href="https://github.com/RustCrypto/RSA">RSA-</a> Bibliotheken.
Es wurden keine kritischen Probleme gefunden, aber zwei Probleme mit hohem Schweregrad, die wir anschließend behoben haben. Außerdem wurden ein mittelschweres und einige weniger schwerwiegende Probleme gefunden, aber es gab keine Möglichkeit, diese Schwachstellen in der Delta-Chat-Implementierung auszunutzen. Einige dieser Schwachstellen haben wir dennoch nach Abschluss des Audits behoben. Sie können den [vollständigen Bericht hier] lesen (../assets/blog/2019-first-security-review.pdf).</p>
</li>
</ul>
@@ -1215,6 +1216,12 @@ Es wurden keine kritischen Probleme gefunden, aber zwei Probleme mit hohem Schwe
und sicherstellen, dass <strong>Privates Netzwerk</strong> als “Netzwerkprofiltyp” ausgewählt ist.
(nach der Übertragung kann wieder der ursprüngliche Wert verwendet werden)</p>
</li>
<li>
<p>Auf <strong>iOS</strong>, sicherstellen, dass „Systemeinstellungen / Apps / Delta Chat / <strong>Lokales Netzwerk</strong>“ eingeschaltet ist</p>
</li>
<li>
<p>Auf <strong>macOS,</strong> „Systemeinstellungen / Datenschutz &amp; Sicherheit / <strong>Lokales Netzwerk</strong> / Delta Chat“ aktivieren</p>
</li>
<li>
<p>Ihr System verfügt möglicherweise über eine “Personal Firewall”, diese sind dafür bekannt, Probleme zu verursachen (insbesondere bei Windows). <strong>Deaktivieren Sie die Personal Firewall</strong> für Delta Chat auf beiden Seiten und versuchen Sie es erneut</p>
</li>
@@ -1253,32 +1260,32 @@ Verwenden Sie nach Möglichkeit ein Nicht-Gast-Netzwerk. Wenn Sie Zugriff auf de
<li><strong>Wenn Sie iOS verwenden</strong> und auf Schwierigkeiten stoßen, hilft Ihnen vielleicht <a href="https://support.delta.chat/t/import-backup-to-ios/1628">diese Anleitung</a>.</li>
</ul>
</li>
<li>Sie sind nun synchronisiert und können beide Geräte zum Senden und Empfangen von Ende-zu-Ende verschlüsselten Nachrichten mit Ihren Kommunikationspartnern verwenden.</li>
<li>Sie sind nun synchronisiert und können beide Geräte zum Senden und Empfangen von Ende-zu-Ende-verschlüsselten-Nachrichten mit Ihren Kommunikationspartnern verwenden.</li>
</ul>
<h3 id="gibt-es-pläne-für-eine-delta-chat-web-anwendung">
Gibt es Pläne für eine Delta Chat Web-Anwendung? <a href="#gibt-es-pläne-für-eine-delta-chat-web-anwendung" class="anchor"></a>
Gibt es Pläne für eine Delta-Chat-Web-Anwendung? <a href="#gibt-es-pläne-für-eine-delta-chat-web-anwendung" class="anchor"></a>
</h3>
<ul>
<li>Es gibt keine direkten Pläne, aber einige vorläufige Gedanken.</li>
<li>Es gibt 2-3 Möglichkeiten, einen Delta Chat Web-Client einzuführen, aber sie bedeuten alle immense Arbeit. Im Moment fokussieren wir uns darauf, stabile native Apps in den Appstores (Google Play/iOS/Windows/macOS/Linux repositories) anzubieten.</li>
<li>Sollten Sie einen Web-Client benötigen, weil Sie auf Ihrem Arbeitsrechner keine Software installieren dürfen, können Sie den Windows Desktop-Client bzw. Applmage für Linux nutzen. Sie finden diese unter <a href="https://get.delta.chat">get.delta.chat</a>.</li>
<li>Es gibt 2-3 Möglichkeiten, einen Delta-Chat-Web-Client einzuführen, aber sie bedeuten alle immense Arbeit. Im Moment fokussieren wir uns darauf, stabile native Apps in den Appstores (Google Play/iOS/Windows/macOS/Linux repositories) anzubieten.</li>
<li>Sollten Sie einen Web-Client benötigen, weil Sie auf Ihrem Arbeitsrechner keine Software installieren dürfen, können Sie den Windows-Desktop-Client bzw. Applmage für Linux nutzen. Sie finden diese unter <a href="https://get.delta.chat">get.delta.chat</a>.</li>
</ul>
<h2 id="webxdc">
Webxdc Apps <a href="#webxdc" class="anchor"></a>
Webxdc-Apps <a href="#webxdc" class="anchor"></a>
</h2>
<p>In Delta Chat können Sie <a href="https://webxdc.org">Webxdc Apps</a>, Anhänge mit der Dateierweiterung “.xdc” teilen. Sie können sehr unterschiedliche Dinge tun und machen Delta Chat zu einem wirklich erweiterbaren Messenger.</p>
<p>In Delta Chat können Sie <a href="https://webxdc.org">Webxdc-Apps</a>, Anhänge mit der Dateierweiterung “.xdc” teilen. Sie können sehr unterschiedliche Dinge tun und machen Delta Chat zu einem wirklich erweiterbaren Messenger.</p>
<h3 id="wie-privat-sind-webxdc-apps">
@@ -1304,7 +1311,8 @@ Verwenden Sie nach Möglichkeit ein Nicht-Gast-Netzwerk. Wenn Sie Zugriff auf de
</h3>
<ul>
<li>Grundsätzlich kann jeder Webxdc Apps mit anderen ohne Einschränkungen teilen.</li>
<li>Grundsätzlich kann jeder Webxdc-Apps mit anderen ohne Einschränkungen teilen.</li>
<li>Von <a href="https://webxdc.org/apps/">webxdc.org/apps</a>.</li>
<li>Sie können <a href="https://delta.chat/en/2023-08-11-xstore">hallo an xstore@testrun.org senden</a>
um einen experimentellen Webxdc Appstore zu sehen.
Alle Apps dort sind Open Source und umsonst.</li>
@@ -1322,7 +1330,7 @@ forum</a> veröffentlicht und diskutiert.</li>
<ul>
<li>Webxdc Apps sind nur ZIP-Dateien, die HTML-, CSS- und JavaScript-Code enthalten.</li>
<li>Sie können die <a href="https://github.com/webxdc/hello">Hello World-Beispiel-App</a> erweitern, um loszulegen.</li>
<li>Sie können die <a href="https://github.com/webxdc/hello">Hello-World-Beispiel-App</a> erweitern, um loszulegen.</li>
<li>Alles andere, was Sie wissen müssen, steht in der <a href="https://docs.webxdc.org/">Dokumentation</a>.</li>
<li>Wenn Sie Fragen haben, können Sie andere mit Erfahrung im <a href="https://support.delta.chat/c/webxdc/20">Delta-Chat-Forum</a> fragen.</li>
</ul>
@@ -1635,7 +1643,7 @@ wenn Sie eine <a href="#signature">Signaturtext</a> einfügen.</p>
<ul>
<li>Ja und Nein.</li>
<li>Nein, Sie können sich nicht mit Delta Chat in ein Protonmail-, Tutanota- oder Criptext-Konto einloggen, da diese keinen Standard-E-Mail-Empfang über IMAP anbieten.</li>
<li>Ja, Sie können Delta Chat verwenden, um Nachrichten an Personen zu senden, die Protonmail, Tutanota oder Criptext verwenden. Diese Nachrichten werden jedoch nicht ende-zu-ende-verschlüsselt, da diese Anbieter keine mit dem <a href="https://autocrypt.org/">Autocrypt</a>-Standard kompatible Verschlüsselung verwenden.</li>
<li>Ja, Sie können Delta Chat verwenden, um Nachrichten an Personen zu senden, die Protonmail, Tutanota oder Criptext verwenden. Diese Nachrichten werden jedoch nicht Ende-zu-Ende-verschlüsselt, da diese Anbieter keine mit dem <a href="https://autocrypt.org/">Autocrypt</a>-Standard kompatible Verschlüsselung verwenden.</li>
<li>Delta Chat kann Ende-zu-Ende-Verschlüsselung über jeden E-Mail-Anbieter mit jeder
<a href="https://autocrypt.org/dev-status.html">Autocrypt-fähige E-Mail-Anwendung</a> herstellen</li>
</ul>
@@ -1680,6 +1688,34 @@ Andernfalls könnten Sie unverschlüsselte Nachrichten aus diesen Gruppenchats e
<li>Siehe hierzu <a href="https://github.com/deltachat/deltachat-core-rust/blob/master/standards.md#standards-used-in-delta-chat">in Delta Chat genutzte Standards</a>.</li>
</ul>
<h3 id="wo-können-meine-freunde-delta-chat-finden">
Wo können meine Freunde Delta Chat finden? <a href="#wo-können-meine-freunde-delta-chat-finden" class="anchor"></a>
</h3>
<p>Delta Chat ist für alle großen und einige kleinere Plattformen verfügbar:</p>
<ul>
<li>
<p>Die <strong>offizielle Website</strong>, <a href="https://delta.chat/download">https://delta.chat/download</a> zeigt alle Optionen im Detail</p>
</li>
<li>
<p>Falls nicht verfügbar, verwenden Sie den <strong>Mirror</strong> auf <a href="https://deltachat.github.io/deltachat-pages">https://deltachat.github.io/deltachat-pages</a></p>
</li>
<li>
<p>Öffnen Sie einen der folgenden <strong>App-Stores und suchen Sie nach „Delta Chat“:</strong> Google Play Store, F-Droid, Huawei App Gallery, Amazon App Store, iOS und macOS App Store, Microsoft Store</p>
</li>
<li>
<p>Im <strong>Paketmanager</strong> Ihrer Linux-Distribution nachschauen</p>
</li>
<li>
<p><strong>Android-APKs</strong> sind auch auf <a href="https://github.com/deltachat/deltachat-android/releases">https://github.com/deltachat/deltachat-android/releases</a> verfügbar.</p>
</li>
</ul>
<h3 id="wie-wird-delta-chat-finanziert">
@@ -1705,10 +1741,10 @@ Die zweite Förderung 2019/2020 (~$300K) half uns bei der Erstellung der iOS-Ve
<p>Die <a href="https://nlnet.nl/">NLnet-Stiftung</a> bewilligte 2019/2020 46K EUR für die Fertigstellung von Rust-/Python-Bindungs und die Einrichtung eines Chat-Bot-Ökosystems.</p>
</li>
<li>
<p>Im Jahr 2021 erhielten wir weitere EU-Mittel für zwei “Next-Generation-Internet” Anträge, nämlich für <a href="https://dapsi.ngi.eu/hall-of-fame/eppd/">EPPD - E-Mail-Provider-Portabilitätsverzeichnis</a> (~97K EUR) und <a href="https://nlnet.nl/project/EmailPorting/">AEAP - E-Mail-Adressportierung</a> (~90K EUR). Ziel sind bessere Unterstützung von Mehrfachkonten, verbesserten QR-Code-Kontakt- und -Gruppen-Setups sowie Netzwerkverbesserungen auf allen Plattformen.</p>
<p>Im Jahr 2021 erhielten wir weitere EU-Mittel für zwei “Next-Generation-Internet”-Anträge, nämlich für <a href="https://dapsi.ngi.eu/hall-of-fame/eppd/">EPPD - E-Mail-Provider-Portabilitätsverzeichnis</a> (~97K EUR) und <a href="https://nlnet.nl/project/EmailPorting/">AEAP - E-Mail-Adressportierung</a> (~90K EUR). Ziel sind bessere Unterstützung von Mehrfachkonten, verbesserten QR-Code-Kontakt- und -Gruppen-Setups sowie Netzwerkverbesserungen auf allen Plattformen.</p>
</li>
<li>
<p>Von Ende 2021 bis März 2023 erhielten wir eine <em>Internet Freedom</em> Finanzierung (500K USD) vom U.S. Bureau of Democracy, Human Rights and Labor (DRL). Diese Finanzierung unterstützte unsere langjährigen Ziele, Delta Chat benutzerfreundlicher und kompatibel mit einer breiten Palette von E-Mail-Servern weltweit zu machen, sowie widerstandsfähiger und sicherer an Orten, die häufig von Internetzensur und Abschaltungen betroffen sind.</p>
<p>Von Ende 2021 bis März 2023 erhielten wir eine <em>Internet-Freedom</em>-Finanzierung (500K USD) vom U.S. Bureau of Democracy, Human Rights and Labor (DRL). Diese Finanzierung unterstützte unsere langjährigen Ziele, Delta Chat benutzerfreundlicher und kompatibel mit einer breiten Palette von E-Mail-Servern weltweit zu machen, sowie widerstandsfähiger und sicherer an Orten, die häufig von Internetzensur und Abschaltungen betroffen sind.</p>
</li>
<li>
<p>2023-2024 schlossen wir erfolgreich das vom OTF finanzierte
@@ -1718,11 +1754,11 @@ das <a href="https://delta.chat/chatmail">Chatmail-Server-Netzwerk</a>
und „Instant Onboarding“ allen ab April 2024 veröffentlichten Anwendungen hinzu.</p>
</li>
<li>
<p>2023 und 2024 wurden wir in das Next Generation Internet (NGI)
Programm für unsere Arbeit an <a href="https://nlnet.nl/project/WebXDC-Push/">webxdc PUSH</a> aufgenommen,
<p>2023 und 2024 wurden wir in das Next-Generation-Internet-Programm (NGI)
für unsere Arbeit an <a href="https://nlnet.nl/project/WebXDC-Push/">Webxdc-PUSH</a> aufgenommen,
zusammen mit Kooperationspartnern, die an
<a href="https://nlnet.nl/project/Webxdc-Evolve/">webxdc evolve</a>,
<a href="https://nlnet.nl/project/WebXDC-XMPP/">webxdc XMPP</a>,
<a href="https://nlnet.nl/project/Webxdc-Evolve/">Webxdc-Evolve</a>,
<a href="https://nlnet.nl/project/WebXDC-XMPP/">Webxdc-XMPP</a>,
<a href="https://nlnet.nl/project/DeltaTouch/">DeltaTouch</a> und
<a href="https://nlnet.nl/project/DeltaTauri/">DeltaTauri</a>.
Alle diese Projekte sind teilweise abgeschlossen oder sollen Anfang 2025 abgeschlossen werden.</p>
@@ -1740,7 +1776,7 @@ Der Erhalt von Spenden hilft uns auch, unabhängiger und langfristig lebensfähi
<p>Die oben aufgeführte finanzielle Förderung wird hauptsächlich von der merlinux GmbH in Freiburg (Deutschland) organisiert und an mehr als ein Dutzend Mitwirkende weltweit verteilt.</p>
<p>Möglichkeiten mitzuwirken finden Sie Auf der <a href="https://delta.chat/de/contribute">Delta Chat Seite “Mitwirken”</a>.</p>
<p>Möglichkeiten mitzuwirken finden Sie Auf der <a href="https://delta.chat/de/contribute">Delta-Chat-Seite “Mitwirken”</a>.</p>
+47 -10
View File
@@ -99,6 +99,7 @@
<li><a href="#is-delta-chat-compatible-with-protonmail--tutanota--criptext">Is Delta Chat compatible with Protonmail / Tutanota / Criptext?</a></li>
<li><a href="#remove-account">How can I delete my account?</a></li>
<li><a href="#im-interested-in-the-technical-details-can-you-tell-me-more">Im interested in the technical details. Can you tell me more?</a></li>
<li><a href="#where-can-my-friends-find-delta-chat">Where can my friends find Delta Chat?</a></li>
<li><a href="#how-are-delta-chat-developments-funded">How are Delta Chat developments funded?</a></li>
</ul>
</li>
@@ -301,8 +302,7 @@ Archived chats remain accessible above the chat list or via search.</p>
</li>
</ul>
<p>To archive or pin a chat, long tap (Android), use the chats menu (Android/Desktop) or swipe to the left (iOS);
to mute a chat, use the chats menu (Android/Desktop) or the chats profile (iOS).</p>
<p>To use the functions, long tap or right click a chat in the chat list.</p>
<h3 id="what-does-the-green-dot-mean">
@@ -603,16 +603,16 @@ to any system involved in the delivery of Push Notifications.</p>
<ul>
<li>
<p>A Delta Chat app obtains a “device token” locally and stores it
<p>A Delta Chat app obtains a “device token” locally, encrypts it and stores it
on the <a href="https://delta.chat/chatmail">chatmail</a> server.</p>
</li>
<li>
<p>When a <a href="https://delta.chat/chatmail">chatmail</a> server receives an e-mail for a Delta Chat user
it forwards the device token to the central Delta Chat notification proxy.</p>
it forwards the encrypted device token to the central Delta Chat notification proxy.</p>
</li>
<li>
<p>The central Delta Chat notification proxy forwards
the “device token” to the respective Push service (Apple, Google, etc.),
<p>The central Delta Chat notification proxy decrypts the device token
and forwards it to the respective Push service (Apple, Google, etc.),
without ever knowing the IP or e-mail address of Delta Chat users.</p>
</li>
<li>
@@ -625,14 +625,15 @@ and also never see any message content (also not in encrypted forms).</p>
</li>
</ul>
<p>As of May 2024, chatmail servers know about “device tokens”
but we plan to encrypt this information to the notification proxy
such that the chatmail server never learns the device token.</p>
<p>The central Delta Chat notification proxy <a href="https://github.com/deltachat/notifiers">is small and fully implemented in Rust</a>
and forgets about device-tokens as soon as Apple/Google/etc processed them,
usually in a matter of milliseconds.</p>
<p>Note that the device token is encrypted between apps and notification proxy
but it is not signed.
The notification proxy thus never sees e-mail addresses, IP-addresses or
any cryptographic identity information associated with a users device (token).</p>
<p>Resulting from this overall privacy design, even the seizure of a chatmail server,
or the full seizure of the central Delta Chat notification proxy
would not reveal private information that Push services do not already have.</p>
@@ -1315,6 +1316,12 @@ One device is not needed for the other to work.</p>
and make sure, <strong>Private Network</strong> is selected as “Network profile type”
(after transfer, you can change back to the original value)</p>
</li>
<li>
<p>On <strong>iOS</strong>, make sure “System Settings / Apps / Delta Chat / <strong>Local Network</strong>” access is granted</p>
</li>
<li>
<p>On <strong>macOS</strong>, enable “System Settings / Privacy &amp; Security / <strong>Local Network</strong> / Delta Chat”</p>
</li>
<li>
<p>Your system might have a “personal firewall”,
which is known to cause problems (especially on Windows).
@@ -1432,6 +1439,7 @@ you only open attachments from senders you trust, and not from spammers.</li>
<ul>
<li>In general, anyone can share webxdc apps with each
other without restrictions.</li>
<li>From <a href="https://webxdc.org/apps/">webxdc.org/apps</a>.</li>
<li>You can <a href="https://delta.chat/en/2023-08-11-xstore">send hi to xstore@testrun.org</a>
to see an experimental webxdc appstore.
All of the apps are open source and for free.</li>
@@ -1883,6 +1891,35 @@ Otherwise you might receive undecryptable messages from those group chats.</p>
<li>See <a href="https://github.com/deltachat/deltachat-core-rust/blob/master/standards.md#standards-used-in-delta-chat">Standards used in Delta Chat</a>.</li>
</ul>
<h3 id="where-can-my-friends-find-delta-chat">
Where can my friends find Delta Chat? <a href="#where-can-my-friends-find-delta-chat" class="anchor"></a>
</h3>
<p>Delta Chat is available for all major and some minor platforms:</p>
<ul>
<li>
<p>The <strong>official website</strong>, <a href="https://delta.chat/download">https://delta.chat/download</a> shows all options in detail</p>
</li>
<li>
<p>If unavailable, use the <strong>mirror</strong> at <a href="https://deltachat.github.io/deltachat-pages">https://deltachat.github.io/deltachat-pages</a></p>
</li>
<li>
<p>Open one of the following <strong>app stores and search for “Delta Chat”:</strong>
Google Play Store, F-Droid, Huawei App Gallery, Amazon App Store, iOS and macOS App Store, Microsoft Store</p>
</li>
<li>
<p>Check the <strong>package manager</strong> of your Linux distributions</p>
</li>
<li>
<p><strong>Android APKs</strong> are also available on <a href="https://github.com/deltachat/deltachat-android/releases">https://github.com/deltachat/deltachat-android/releases</a></p>
</li>
</ul>
<h3 id="how-are-delta-chat-developments-funded">
+46 -8
View File
@@ -99,6 +99,7 @@
<li><a href="#delta-chat-es-compatible-con-protonmail--tutanota--criptext">¿Delta Chat es compatible con Protonmail / Tutanota / Criptext?</a></li>
<li><a href="#remove-account">¿Cómo puedo eliminar mi cuenta?</a></li>
<li><a href="#estoy-interesado-en-los-detalles-técnicos-pueden-decirme-más">Estoy interesado en los detalles técnicos. ¿Pueden decirme más?</a></li>
<li><a href="#where-can-my-friends-find-delta-chat">Where can my friends find Delta Chat?</a></li>
<li><a href="#cómo-se-financia-el-desarrollo-de-delta-chat">¿Cómo se financia el desarrollo de Delta Chat?</a></li>
</ul>
</li>
@@ -596,16 +597,16 @@ to any system involved in the delivery of Push Notifications.</p>
<ul>
<li>
<p>A Delta Chat app obtains a “device token” locally and stores it
<p>A Delta Chat app obtains a “device token” locally, encrypts it and stores it
on the <a href="https://delta.chat/chatmail">chatmail</a> server.</p>
</li>
<li>
<p>When a <a href="https://delta.chat/chatmail">chatmail</a> server receives an e-mail for a Delta Chat user
it forwards the device token to the central Delta Chat notification proxy.</p>
it forwards the encrypted device token to the central Delta Chat notification proxy.</p>
</li>
<li>
<p>The central Delta Chat notification proxy forwards
the “device token” to the respective Push service (Apple, Google, etc.),
<p>The central Delta Chat notification proxy decrypts the device token
and forwards it to the respective Push service (Apple, Google, etc.),
without ever knowing the IP or e-mail address of Delta Chat users.</p>
</li>
<li>
@@ -618,14 +619,15 @@ and also never see any message content (also not in encrypted forms).</p>
</li>
</ul>
<p>As of May 2024, chatmail servers know about “device tokens”
but we plan to encrypt this information to the notification proxy
such that the chatmail server never learns the device token.</p>
<p>The central Delta Chat notification proxy <a href="https://github.com/deltachat/notifiers">is small and fully implemented in Rust</a>
and forgets about device-tokens as soon as Apple/Google/etc processed them,
usually in a matter of milliseconds.</p>
<p>Note that the device token is encrypted between apps and notification proxy
but it is not signed.
The notification proxy thus never sees e-mail addresses, IP-addresses or
any cryptographic identity information associated with a users device (token).</p>
<p>Resulting from this overall privacy design, even the seizure of a chatmail server,
or the full seizure of the central Delta Chat notification proxy
would not reveal private information that Push services do not already have.</p>
@@ -1277,6 +1279,12 @@ No es necesario un dispositivo para que el otro funcione.</p>
and make sure, <strong>Private Network</strong> is selected as “Network profile type”
(after transfer, you can change back to the original value)</p>
</li>
<li>
<p>On <strong>iOS</strong>, make sure “System Settings / Apps / Delta Chat / <strong>Local Network</strong>” access is granted</p>
</li>
<li>
<p>On <strong>macOS</strong>, enable “System Settings / Privacy &amp; Security / <strong>Local Network</strong> / Delta Chat”</p>
</li>
<li>
<p>Your system might have a “personal firewall”,
which is known to cause problems (especially on Windows).
@@ -1394,6 +1402,7 @@ solo abre archivos adjuntos de remitentes en los que confía y no de spammers.</
<ul>
<li>In general, anyone can share webxdc apps with each
other without restrictions.</li>
<li>From <a href="https://webxdc.org/apps/">webxdc.org/apps</a>.</li>
<li>You can <a href="https://delta.chat/en/2023-08-11-xstore">send hi to xstore@testrun.org</a>
to see an experimental webxdc appstore.
All of the apps are open source and for free.</li>
@@ -1827,6 +1836,35 @@ Otherwise you might receive undecryptable messages from those group chats.</p>
<li>Visita la página <a href="https://github.com/deltachat/deltachat-core-rust/blob/master/standards.md#standards-used-in-delta-chat">Estándares usados en Delta Chat</a>.</li>
</ul>
<h3 id="where-can-my-friends-find-delta-chat">
Where can my friends find Delta Chat? <a href="#where-can-my-friends-find-delta-chat" class="anchor"></a>
</h3>
<p>Delta Chat is available for all major and some minor platforms:</p>
<ul>
<li>
<p>The <strong>official website</strong>, <a href="https://delta.chat/download">https://delta.chat/download</a> shows all options in detail</p>
</li>
<li>
<p>If unavailable, use the <strong>mirror</strong> at <a href="https://deltachat.github.io/deltachat-pages">https://deltachat.github.io/deltachat-pages</a></p>
</li>
<li>
<p>Open one of the following <strong>app stores and search for “Delta Chat”:</strong>
Google Play Store, F-Droid, Huawei App Gallery, Amazon App Store, iOS and macOS App Store, Microsoft Store</p>
</li>
<li>
<p>Check the <strong>package manager</strong> of your Linux distributions</p>
</li>
<li>
<p><strong>Android APKs</strong> are also available on <a href="https://github.com/deltachat/deltachat-android/releases">https://github.com/deltachat/deltachat-android/releases</a></p>
</li>
</ul>
<h3 id="cómo-se-financia-el-desarrollo-de-delta-chat">
+77 -39
View File
@@ -8,7 +8,7 @@
<li><a href="#delta-chat-prend-il-en-charge-les-images-vidéos-et-autres-pièces-jointes-">Delta Chat prend-il en charge les images, vidéos et autres pièces jointes ?</a></li>
<li><a href="#multiple-accounts">What are profiles? How can I switch between them?</a></li>
<li><a href="#qui-peut-voir-ma-photo-de-profil-">Qui peut voir ma photo de profil ?</a></li>
<li><a href="#signature">Can I set a Bio/Signature/Status/Motto with Delta Chat?</a></li>
<li><a href="#signature">Puis-je afficher une Bio/Signature ou un Status/Motto avec Delta Chat?</a></li>
<li><a href="#que-signifient-épingler-sourdine-et-archiver-">Que signifient “épingler”, “sourdine” et “archiver” ?</a></li>
<li><a href="#que-signifie-le-point-vert-">Que signifie le point vert ?</a></li>
<li><a href="#ephemeralmsgs">How do disappearing messages work?</a></li>
@@ -99,6 +99,7 @@
<li><a href="#delta-chat-est-il-compatible-avec-protonmail--tutanota--criptext-">Delta Chat est-il compatible avec Protonmail / Tutanota / Criptext ?</a></li>
<li><a href="#remove-account">Comment supprimer mon compte ?</a></li>
<li><a href="#les-détails-techniques-mintéressent-pouvez-vous-men-dire-plus-">Les détails techniques mintéressent. Pouvez-vous men dire plus ?</a></li>
<li><a href="#where-can-my-friends-find-delta-chat">Where can my friends find Delta Chat?</a></li>
<li><a href="#comment-est-financé-le-développement-de-delta-chat-">Comment est financé le développement de Delta Chat ?</a></li>
</ul>
</li>
@@ -114,14 +115,14 @@
</h2>
<p>Delta Chat is a reliable, decentralized and secure messaging app,
available for mobile and desktop platforms.</p>
<p>Delta Chat est une application de messagerie fiable, décentralisée et sécurisée,
Disponible pour les plateformes smartphone et ordinateurs de bureau.</p>
<p>Delta Chat feels like Whatsapp or Telegram but you can also use and regard it as an e-mail app.
You can signup anonymously to a variety of <a href="https://delta.chat/chatmail">interoperable chatmail servers</a>
which are minimal e-mail servers optimized for fast and secure operations.
Or you may use classic e-mail servers and an existing e-mail account
in which case Delta Chat acts as an e-mail app.</p>
<p>Delta Chat ressemble à Whatsapp ou Telegram mais vous pouvez aussi lutiliser et la considérer comme une application e-mail.
Vous pouvez vous inscrire anonymement à une variété <a href="https://delta.chat/chatmail">de serveurs chatmail interéopérables</a>
Qui sont des serveurs e-mails minimalistes optimisés pour des opérations rapides et sécurisées.
Ou vous pouvez utiliser des serveurs e-mail classiques et utiliser votre compte e-mail
dans ce cas Delta Chat agit comme une application de courriel.</p>
<p><img style="float:right; width:50%; max-width:360%; margin:1em;" src="../delta-what-optim.png" /></p>
@@ -133,15 +134,15 @@ in which case Delta Chat acts as an e-mail app.</p>
</h3>
<p>To securely setup contact with others <a href="#howtoe2ee">scan an invite QR code
or share an invite link</a>.
This is required when using a (default) chatmail-based chat profile
because chatmail servers reject un-encrypted outgoing messages.</p>
<p>Pour établir un contact en toute sécurité avec dautres personnes <a href="#howtoe2ee">scanner un code QR dinvitation
ou partager un lien dinvitation</a>.
Cette opération est nécessaire lors de lutilisation dun profil de discussion basé sur le chatmail (par défaut).
car les serveurs de chatmail rejettent les messages sortants non chiffrés.</p>
<p>If you create a chat profile with a classic e-mail address
you may manually create a contact if you know their e-mail address
and then write a message to them
even if the recipient is not using Delta Chat.</p>
<p>Si vous créez un profil discussion avec une adresse courriel classique
vous pouvez créer manuellement un contact si vous connaissez son adresse courriel
et lui écrire un message
même si le destinataire nutilise pas Delta Chat.</p>
<h3 id="quels-sont-les-avantages-de-delta-chat-par-rapport-aux-autres-messageries-">
@@ -153,23 +154,23 @@ even if the recipient is not using Delta Chat.</p>
<ul>
<li>
<p>Anonymous chat profiles with fast, secure and interoperable <a href="https://delta.chat/chatmail">chatmail servers</a>
which offer instant Push Notifications for iOS and Android devices.</p>
<p>Profils anonymes de discussion avec des <a href="https://delta.chat/chatmail">serveurs de chatmail</a> rapides, sécurisés et interopérables
qui offrent des notifications push instantanées pour les appareils iOS et Android.</p>
</li>
<li>
<p>Pervasive <a href="#multiple-accounts">multi-profile</a> and multi-device support on all platforms.</p>
<p>Fonctionnalités de <a href="#multiple-accounts">multi-profil</a> et de multi-appareil supportées sur toutes les plateformes.</p>
</li>
<li>
<p>Interactive <a href="https://webxdc.org/apps">web apps in chats</a> for gaming and collaboration</p>
<p><a href="https://webxdc.org/apps">web apps dans les chats</a> interactifs pour le gaming et la collaboration</p>
</li>
<li>
<p><a href="#security-audits">Audited end-to-end encryption</a>
safe against network and server attacks.</p>
<p><a href="#security-audits">Chiffrement de bout en bout audité</a>
contre les attaques ciblées sur le réseau et les serveurs.</p>
</li>
<li>
<p>Free and Open Source software, both app and server side.
Built on <a href="https://github.com/deltachat/deltachat-core-rust/blob/master/standards.md">E-mail and Web Internet Standards</a>,
<a href="https://xkcd.com/927/">to avoid “yet another standard syndrome (xkcd 927)</a></p>
<p>Logiciel libre et open source, à la fois appli et côté serveur.
Construit sur des <a href="https://github.com/deltachat/deltachat-core-rust/blob/master/standards.md">Standards dInternet et de-mail</a>,
<a href="https://xkcd.com/927/">pour éviter le syndrome du “standard de plus” (xkcd 927)</a></p>
</li>
</ul>
@@ -255,16 +256,16 @@ that tend to cause unsolicited messages (“spam”) sooner or later.</p>
<h3 id="signature">
Can I set a Bio/Signature/Status/Motto with Delta Chat? <a href="#signature" class="anchor"></a>
Puis-je afficher une Bio/Signature ou un Status/Motto avec Delta Chat? <a href="#signature" class="anchor"></a>
</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>Oui,
vous pouvez le faire sous <strong>Paramètres → Profil → Bio</strong>.
Vos contacts qui utilisent Delta Chat le verront
lorsquils consulteront vos coordonnées.
De plus, elle apparaîtra sous la forme dune signature classique sur vos courriels.</p>
<h3 id="que-signifient-épingler-sourdine-et-archiver-">
@@ -577,16 +578,16 @@ to any system involved in the delivery of Push Notifications.</p>
<ul>
<li>
<p>A Delta Chat app obtains a “device token” locally and stores it
<p>A Delta Chat app obtains a “device token” locally, encrypts it and stores it
on the <a href="https://delta.chat/chatmail">chatmail</a> server.</p>
</li>
<li>
<p>When a <a href="https://delta.chat/chatmail">chatmail</a> server receives an e-mail for a Delta Chat user
it forwards the device token to the central Delta Chat notification proxy.</p>
it forwards the encrypted device token to the central Delta Chat notification proxy.</p>
</li>
<li>
<p>The central Delta Chat notification proxy forwards
the “device token” to the respective Push service (Apple, Google, etc.),
<p>The central Delta Chat notification proxy decrypts the device token
and forwards it to the respective Push service (Apple, Google, etc.),
without ever knowing the IP or e-mail address of Delta Chat users.</p>
</li>
<li>
@@ -599,14 +600,15 @@ and also never see any message content (also not in encrypted forms).</p>
</li>
</ul>
<p>As of May 2024, chatmail servers know about “device tokens”
but we plan to encrypt this information to the notification proxy
such that the chatmail server never learns the device token.</p>
<p>The central Delta Chat notification proxy <a href="https://github.com/deltachat/notifiers">is small and fully implemented in Rust</a>
and forgets about device-tokens as soon as Apple/Google/etc processed them,
usually in a matter of milliseconds.</p>
<p>Note that the device token is encrypted between apps and notification proxy
but it is not signed.
The notification proxy thus never sees e-mail addresses, IP-addresses or
any cryptographic identity information associated with a users device (token).</p>
<p>Resulting from this overall privacy design, even the seizure of a chatmail server,
or the full seizure of the central Delta Chat notification proxy
would not reveal private information that Push services do not already have.</p>
@@ -1262,6 +1264,12 @@ Lun na pas besoin de lautre pour pouvoir fonctionner.</p>
and make sure, <strong>Private Network</strong> is selected as “Network profile type”
(after transfer, you can change back to the original value)</p>
</li>
<li>
<p>On <strong>iOS</strong>, make sure “System Settings / Apps / Delta Chat / <strong>Local Network</strong>” access is granted</p>
</li>
<li>
<p>On <strong>macOS</strong>, enable “System Settings / Privacy &amp; Security / <strong>Local Network</strong> / Delta Chat”</p>
</li>
<li>
<p>Il se peut que votre système dispose dun “pare-feu personnalisé”,
source bien connue de dysfonctionnements (en particulier sur Windows).
@@ -1375,6 +1383,7 @@ you only open attachments from senders you trust, and not from spammers.</li>
<ul>
<li>In general, anyone can share webxdc apps with each
other without restrictions.</li>
<li>From <a href="https://webxdc.org/apps/">webxdc.org/apps</a>.</li>
<li>You can <a href="https://delta.chat/en/2023-08-11-xstore">send hi to xstore@testrun.org</a>
to see an experimental webxdc appstore.
All of the apps are open source and for free.</li>
@@ -1789,6 +1798,35 @@ Otherwise you might receive undecryptable messages from those group chats.</p>
<li>Consultez les <a href="https://github.com/deltachat/deltachat-core-rust/blob/master/standards.md#standards-used-in-delta-chat">standards utilisés dans Delta Chat</a>.</li>
</ul>
<h3 id="where-can-my-friends-find-delta-chat">
Where can my friends find Delta Chat? <a href="#where-can-my-friends-find-delta-chat" class="anchor"></a>
</h3>
<p>Delta Chat is available for all major and some minor platforms:</p>
<ul>
<li>
<p>The <strong>official website</strong>, <a href="https://delta.chat/download">https://delta.chat/download</a> shows all options in detail</p>
</li>
<li>
<p>If unavailable, use the <strong>mirror</strong> at <a href="https://deltachat.github.io/deltachat-pages">https://deltachat.github.io/deltachat-pages</a></p>
</li>
<li>
<p>Open one of the following <strong>app stores and search for “Delta Chat”:</strong>
Google Play Store, F-Droid, Huawei App Gallery, Amazon App Store, iOS and macOS App Store, Microsoft Store</p>
</li>
<li>
<p>Check the <strong>package manager</strong> of your Linux distributions</p>
</li>
<li>
<p><strong>Android APKs</strong> are also available on <a href="https://github.com/deltachat/deltachat-android/releases">https://github.com/deltachat/deltachat-android/releases</a></p>
</li>
</ul>
<h3 id="comment-est-financé-le-développement-de-delta-chat-">
+47 -10
View File
@@ -99,6 +99,7 @@
<li><a href="#is-delta-chat-compatible-with-protonmail--tutanota--criptext">Is Delta Chat compatible with Protonmail / Tutanota / Criptext?</a></li>
<li><a href="#remove-account">How can I delete my account?</a></li>
<li><a href="#im-interested-in-the-technical-details-can-you-tell-me-more">Im interested in the technical details. Can you tell me more?</a></li>
<li><a href="#where-can-my-friends-find-delta-chat">Where can my friends find Delta Chat?</a></li>
<li><a href="#how-are-delta-chat-developments-funded">How are Delta Chat developments funded?</a></li>
</ul>
</li>
@@ -301,8 +302,7 @@ Archived chats remain accessible above the chat list or via search.</p>
</li>
</ul>
<p>To archive or pin a chat, long tap (Android), use the chats menu (Android/Desktop) or swipe to the left (iOS);
to mute a chat, use the chats menu (Android/Desktop) or the chats profile (iOS).</p>
<p>To use the functions, long tap or right click a chat in the chat list.</p>
<h3 id="what-does-the-green-dot-mean">
@@ -603,16 +603,16 @@ to any system involved in the delivery of Push Notifications.</p>
<ul>
<li>
<p>A Delta Chat app obtains a “device token” locally and stores it
<p>A Delta Chat app obtains a “device token” locally, encrypts it and stores it
on the <a href="https://delta.chat/chatmail">chatmail</a> server.</p>
</li>
<li>
<p>When a <a href="https://delta.chat/chatmail">chatmail</a> server receives an e-mail for a Delta Chat user
it forwards the device token to the central Delta Chat notification proxy.</p>
it forwards the encrypted device token to the central Delta Chat notification proxy.</p>
</li>
<li>
<p>The central Delta Chat notification proxy forwards
the “device token” to the respective Push service (Apple, Google, etc.),
<p>The central Delta Chat notification proxy decrypts the device token
and forwards it to the respective Push service (Apple, Google, etc.),
without ever knowing the IP or e-mail address of Delta Chat users.</p>
</li>
<li>
@@ -625,14 +625,15 @@ and also never see any message content (also not in encrypted forms).</p>
</li>
</ul>
<p>As of May 2024, chatmail servers know about “device tokens”
but we plan to encrypt this information to the notification proxy
such that the chatmail server never learns the device token.</p>
<p>The central Delta Chat notification proxy <a href="https://github.com/deltachat/notifiers">is small and fully implemented in Rust</a>
and forgets about device-tokens as soon as Apple/Google/etc processed them,
usually in a matter of milliseconds.</p>
<p>Note that the device token is encrypted between apps and notification proxy
but it is not signed.
The notification proxy thus never sees e-mail addresses, IP-addresses or
any cryptographic identity information associated with a users device (token).</p>
<p>Resulting from this overall privacy design, even the seizure of a chatmail server,
or the full seizure of the central Delta Chat notification proxy
would not reveal private information that Push services do not already have.</p>
@@ -1315,6 +1316,12 @@ One device is not needed for the other to work.</p>
and make sure, <strong>Private Network</strong> is selected as “Network profile type”
(after transfer, you can change back to the original value)</p>
</li>
<li>
<p>On <strong>iOS</strong>, make sure “System Settings / Apps / Delta Chat / <strong>Local Network</strong>” access is granted</p>
</li>
<li>
<p>On <strong>macOS</strong>, enable “System Settings / Privacy &amp; Security / <strong>Local Network</strong> / Delta Chat”</p>
</li>
<li>
<p>Your system might have a “personal firewall”,
which is known to cause problems (especially on Windows).
@@ -1432,6 +1439,7 @@ you only open attachments from senders you trust, and not from spammers.</li>
<ul>
<li>In general, anyone can share webxdc apps with each
other without restrictions.</li>
<li>From <a href="https://webxdc.org/apps/">webxdc.org/apps</a>.</li>
<li>You can <a href="https://delta.chat/en/2023-08-11-xstore">send hi to xstore@testrun.org</a>
to see an experimental webxdc appstore.
All of the apps are open source and for free.</li>
@@ -1883,6 +1891,35 @@ Otherwise you might receive undecryptable messages from those group chats.</p>
<li>See <a href="https://github.com/deltachat/deltachat-core-rust/blob/master/standards.md#standards-used-in-delta-chat">Standards used in Delta Chat</a>.</li>
</ul>
<h3 id="where-can-my-friends-find-delta-chat">
Where can my friends find Delta Chat? <a href="#where-can-my-friends-find-delta-chat" class="anchor"></a>
</h3>
<p>Delta Chat is available for all major and some minor platforms:</p>
<ul>
<li>
<p>The <strong>official website</strong>, <a href="https://delta.chat/download">https://delta.chat/download</a> shows all options in detail</p>
</li>
<li>
<p>If unavailable, use the <strong>mirror</strong> at <a href="https://deltachat.github.io/deltachat-pages">https://deltachat.github.io/deltachat-pages</a></p>
</li>
<li>
<p>Open one of the following <strong>app stores and search for “Delta Chat”:</strong>
Google Play Store, F-Droid, Huawei App Gallery, Amazon App Store, iOS and macOS App Store, Microsoft Store</p>
</li>
<li>
<p>Check the <strong>package manager</strong> of your Linux distributions</p>
</li>
<li>
<p><strong>Android APKs</strong> are also available on <a href="https://github.com/deltachat/deltachat-android/releases">https://github.com/deltachat/deltachat-android/releases</a></p>
</li>
</ul>
<h3 id="how-are-delta-chat-developments-funded">
+48 -11
View File
@@ -99,6 +99,7 @@
<li><a href="#delta-chat-è-compatibile-con-protonmail--tutanota--criptext">Delta Chat è compatibile con Protonmail / Tutanota / Criptext?</a></li>
<li><a href="#remove-account">Come posso eliminare il mio profilo?</a></li>
<li><a href="#sono-interessato-ai-dettagli-tecnici-mi-puoi-dire-di-più">Sono interessato ai dettagli tecnici. Mi puoi dire di più?</a></li>
<li><a href="#dove-possono-trovare-delta-chat-i-miei-amici">Dove possono trovare Delta Chat i miei amici?</a></li>
<li><a href="#come-viene-finanziato-lo-sviluppo-di-delta-chat">Come viene finanziato lo sviluppo di Delta Chat?</a></li>
</ul>
</li>
@@ -596,17 +597,17 @@ a qualsiasi sistema coinvolto nella consegna di Notifiche Push.</p>
<ul>
<li>
<p>Unapp Delta Chat ottiene un “gettone del dispositivo” localmente e lo memorizza
sul server <a href="https://delta.chat/chatmail">chatmail</a>.</p>
<p>A Delta Chat app obtains a “device token” locally, encrypts it and stores it
on the <a href="https://delta.chat/chatmail">chatmail</a> server.</p>
</li>
<li>
<p>Quando un server <a href="https://delta.chat/chatmail">chatmail</a> riceve une-mail per un utente Delta Chat
inoltra il “gettone del dispositivo” al proxy di notifica centrale di Delta Chat.</p>
<p>When a <a href="https://delta.chat/chatmail">chatmail</a> server receives an e-mail for a Delta Chat user
it forwards the encrypted device token to the central Delta Chat notification proxy.</p>
</li>
<li>
<p>Il proxy di notifica centrale di Delta Chat inoltra
il “gettone del dispositivo” al rispettivo servizio Push (Apple, Google, ecc.),
senza mai conoscere lIP o lindirizzo e-mail degli utenti Delta Chat.</p>
<p>The central Delta Chat notification proxy decrypts the device token
and forwards it to the respective Push service (Apple, Google, etc.),
without ever knowing the IP or e-mail address of Delta Chat users.</p>
</li>
<li>
<p>Il Servizio Push centrale (Apple, Google, ecc.)
@@ -618,14 +619,15 @@ e inoltre non vedono mai il contenuto del messaggio (anche non in forma crittogr
</li>
</ul>
<p>A partire da Maggio 2024, i server chatmail conoscono i “gettoni del dispositivo”
ma prevediamo di crittografare queste informazioni nel proxy di notifica
in modo tale che il server chatmail non apprenda mai il gettone del dispositivo.</p>
<p>Il proxy di notifica centrale di Delta Chat <a href="https://github.com/deltachat/notifiers">è piccolo e completamente implementato in Rust</a>
e si dimentica dei gettoni del dispositivo non appena Apple/Google/ecc li elabora,
di solito nel giro di pochi millisecondi.</p>
<p>Note that the device token is encrypted between apps and notification proxy
but it is not signed.
The notification proxy thus never sees e-mail addresses, IP-addresses or
any cryptographic identity information associated with a users device (token).</p>
<p>Come risultato di questo disegno complessivo sulla riservatezza, anche il sequestro di un server chatmail,
o il sequestro totale del proxy di notifica centrale di Delta Chat
non rivelerebbe informazioni private che i servizi Push non abbiano già.</p>
@@ -1302,6 +1304,12 @@ Un dispositivo non è necessario perché laltro funzioni.</p>
e assicurati che <strong>Rete Privata</strong> sia selezionata come “Tipo di profilo di rete”
(dopo il trasferimento è possibile ripristinare il valore originale)</p>
</li>
<li>
<p>Su <strong>iOS</strong>, assicurati che laccesso a “Impostazioni di Sistema / App / Delta Chat / <strong>Rete locale</strong>” sia concesso</p>
</li>
<li>
<p>Su <strong>macOS</strong>, abilita “Impostazioni di Sistema / Privacy &amp; Sicurezza / <strong>Rete locale</strong> / Delta Chat”</p>
</li>
<li>
<p>Il sistema potrebbe avere un “personal firewall”,
che è noto per causare problemi (soprattutto su Windows).
@@ -1845,6 +1853,35 @@ Altrimenti potresti ricevere messaggi non decifrabili da quelle chat di gruppo.<
<li>Vedi <a href="https://github.com/deltachat/deltachat-core-rust/blob/master/standards.md#standards-used-in-delta-chat">Standard usati in Delta Chat</a>.</li>
</ul>
<h3 id="dove-possono-trovare-delta-chat-i-miei-amici">
Dove possono trovare Delta Chat i miei amici? <a href="#dove-possono-trovare-delta-chat-i-miei-amici" class="anchor"></a>
</h3>
<p>Delta Chat è disponibile per tutte le piattaforme principali e alcune minori:</p>
<ul>
<li>
<p>Il <strong>sito ufficiale</strong>, <a href="https://delta.chat/download">https://delta.chat/download</a> mostra tutte le opzioni in dettaglio</p>
</li>
<li>
<p>Se non disponibile, utilizzare <strong>mirror</strong> su <a href="https://deltachat.github.io/deltachat-pages">https://deltachat.github.io/deltachat-pages</a></p>
</li>
<li>
<p>Apri uno dei seguenti <strong>app store e cerca “Delta Chat”:</strong>
Google Play Store, F-Droid, Huawei App Gallery, Amazon App Store, iOS e macOS App Store, Microsoft Store</p>
</li>
<li>
<p>Controlla il <strong>gestore pacchetti</strong> delle tue distribuzioni Linux</p>
</li>
<li>
<p><strong>APK Android</strong> sono disponibili anche su <a href="https://github.com/deltachat/deltachat-android/releases">https://github.com/deltachat/deltachat-android/releases</a></p>
</li>
</ul>
<h3 id="come-viene-finanziato-lo-sviluppo-di-delta-chat">
+46 -8
View File
@@ -99,6 +99,7 @@
<li><a href="#is-delta-chat-compatibel-met-protonmailtutanotacriptext">Is Delta Chat compatibel met Protonmail/Tutanota/Criptext?</a></li>
<li><a href="#remove-account">Hoe kan ik mijn account verwijderen?</a></li>
<li><a href="#ik-wil-graag-meer-weten-over-de-gebruikte-technieken-waar-kan-ik-meer-informatie-vinden">Ik wil graag meer weten over de gebruikte technieken. Waar kan ik meer informatie vinden?</a></li>
<li><a href="#where-can-my-friends-find-delta-chat">Where can my friends find Delta Chat?</a></li>
<li><a href="#hoe-wordt-de-ontwikkeling-van-delta-chat-gefinancierd">Hoe wordt de ontwikkeling van Delta Chat gefinancierd?</a></li>
</ul>
</li>
@@ -596,16 +597,16 @@ to any system involved in the delivery of Push Notifications.</p>
<ul>
<li>
<p>A Delta Chat app obtains a “device token” locally and stores it
<p>A Delta Chat app obtains a “device token” locally, encrypts it and stores it
on the <a href="https://delta.chat/chatmail">chatmail</a> server.</p>
</li>
<li>
<p>When a <a href="https://delta.chat/chatmail">chatmail</a> server receives an e-mail for a Delta Chat user
it forwards the device token to the central Delta Chat notification proxy.</p>
it forwards the encrypted device token to the central Delta Chat notification proxy.</p>
</li>
<li>
<p>The central Delta Chat notification proxy forwards
the “device token” to the respective Push service (Apple, Google, etc.),
<p>The central Delta Chat notification proxy decrypts the device token
and forwards it to the respective Push service (Apple, Google, etc.),
without ever knowing the IP or e-mail address of Delta Chat users.</p>
</li>
<li>
@@ -618,14 +619,15 @@ and also never see any message content (also not in encrypted forms).</p>
</li>
</ul>
<p>As of May 2024, chatmail servers know about “device tokens”
but we plan to encrypt this information to the notification proxy
such that the chatmail server never learns the device token.</p>
<p>The central Delta Chat notification proxy <a href="https://github.com/deltachat/notifiers">is small and fully implemented in Rust</a>
and forgets about device-tokens as soon as Apple/Google/etc processed them,
usually in a matter of milliseconds.</p>
<p>Note that the device token is encrypted between apps and notification proxy
but it is not signed.
The notification proxy thus never sees e-mail addresses, IP-addresses or
any cryptographic identity information associated with a users device (token).</p>
<p>Resulting from this overall privacy design, even the seizure of a chatmail server,
or the full seizure of the central Delta Chat notification proxy
would not reveal private information that Push services do not already have.</p>
@@ -1306,6 +1308,12 @@ op beide apparaten</strong>. Hierdoor hoef je niet het ene apparaat bij de hand
and make sure, <strong>Private Network</strong> is selected as “Network profile type”
(after transfer, you can change back to the original value)</p>
</li>
<li>
<p>On <strong>iOS</strong>, make sure “System Settings / Apps / Delta Chat / <strong>Local Network</strong>” access is granted</p>
</li>
<li>
<p>On <strong>macOS</strong>, enable “System Settings / Privacy &amp; Security / <strong>Local Network</strong> / Delta Chat”</p>
</li>
<li>
<p>Wellicht is een firewall actief op je apparaat,
welke problemen kan veroorzaken (met name op Windows).
@@ -1423,6 +1431,7 @@ you only open attachments from senders you trust, and not from spammers.</li>
<ul>
<li>In general, anyone can share webxdc apps with each
other without restrictions.</li>
<li>From <a href="https://webxdc.org/apps/">webxdc.org/apps</a>.</li>
<li>You can <a href="https://delta.chat/en/2023-08-11-xstore">send hi to xstore@testrun.org</a>
to see an experimental webxdc appstore.
All of the apps are open source and for free.</li>
@@ -1868,6 +1877,35 @@ Otherwise you might receive undecryptable messages from those group chats.</p>
<li>Bekijk de pagina <a href="https://github.com/deltachat/deltachat-core-rust/blob/master/standards.md#standards-used-in-delta-chat">Door Delta Chat gebruikte standaarden</a>.</li>
</ul>
<h3 id="where-can-my-friends-find-delta-chat">
Where can my friends find Delta Chat? <a href="#where-can-my-friends-find-delta-chat" class="anchor"></a>
</h3>
<p>Delta Chat is available for all major and some minor platforms:</p>
<ul>
<li>
<p>The <strong>official website</strong>, <a href="https://delta.chat/download">https://delta.chat/download</a> shows all options in detail</p>
</li>
<li>
<p>If unavailable, use the <strong>mirror</strong> at <a href="https://deltachat.github.io/deltachat-pages">https://deltachat.github.io/deltachat-pages</a></p>
</li>
<li>
<p>Open one of the following <strong>app stores and search for “Delta Chat”:</strong>
Google Play Store, F-Droid, Huawei App Gallery, Amazon App Store, iOS and macOS App Store, Microsoft Store</p>
</li>
<li>
<p>Check the <strong>package manager</strong> of your Linux distributions</p>
</li>
<li>
<p><strong>Android APKs</strong> are also available on <a href="https://github.com/deltachat/deltachat-android/releases">https://github.com/deltachat/deltachat-android/releases</a></p>
</li>
</ul>
<h3 id="hoe-wordt-de-ontwikkeling-van-delta-chat-gefinancierd">
+42 -7
View File
@@ -99,6 +99,7 @@
<li><a href="#czy-delta-chat-jest-kompatybilny-z-protonmail--tutanota--criptext">Czy Delta Chat jest kompatybilny z Protonmail / Tutanota / Criptext?</a></li>
<li><a href="#remove-account">Jak mogę usunąć swoje konto?</a></li>
<li><a href="#interesują-mnie-szczegóły-techniczne-możesz-powiedzieć-mi-coś-więcej">Interesują mnie szczegóły techniczne. Możesz powiedzieć mi coś więcej?</a></li>
<li><a href="#gdzie-moi-znajomi-mogą-znaleźć-delta-chat">Gdzie moi znajomi mogą znaleźć Delta Chat?</a></li>
<li><a href="#w-jaki-sposób-finansowany-jest-rozwój-delta-chat">W jaki sposób finansowany jest rozwój Delta Chat?</a></li>
</ul>
</li>
@@ -265,8 +266,7 @@
</li>
</ul>
<p>Aby zarchiwizować lub przypiąć czat, dotknij i przytrzymaj (Android), yj menu czatu (Android/Desktop) lub przesuń palcem w lewo (iOS);
aby wyciszyć czat, użyj menu czatu (Android/Desktop) lub profilu czatu (iOS).</p>
<p>Aby skorzystać z tych funkcji, przytrzymaj ej lub kliknij prawym przyciskiem myszy czat na liście czatów.</p>
<h3 id="co-oznacza-zielona-kropka">
@@ -494,23 +494,23 @@ nadal będziesz mógł pisać, ale nie będziesz już powiadamiany o żadnych no
<ul>
<li>
<p>Aplikacja Delta Chat uzyskuje lokalnie „token urządzenia” i przechowuje go na serwerze <a href="https://delta.chat/chatmail">chatmail</a>.</p>
<p>Aplikacja Delta Chat uzyskuje lokalnie „token urządzenia”, szyfruje i przechowuje go na serwerze <a href="https://delta.chat/chatmail">chatmail</a>.</p>
</li>
<li>
<p>Kiedy serwer <a href="https://delta.chat/chatmail">chatmail</a> odbierze wiadomość e-mail od użytkownika Delta Chat, przekazuje token urządzenia do centralnego serwera proxy powiadomień Delta Chat.</p>
<p>Kiedy serwer <a href="https://delta.chat/chatmail">chatmail</a> odbierze wiadomość e-mail od użytkownika Delta Chat, przekazuje zaszyfrowany token urządzenia do centralnego serwera proxy powiadomień Delta Chat.</p>
</li>
<li>
<p>Centralny serwer proxy powiadomień Delta Chat przekazuje token urządzenia do odpowiedniej usługi Push (Apple, Google itp.), nie znając nawet adresu IP ani adresu e-mail użytkowników Delta Chat.</p>
<p>Centralny serwer proxy powiadomień Delta Chat deszyfruje token urządzenia i przekazuje go do odpowiedniej usługi Push (Apple, Google itp.), nie znając nawet adresu IP ani adresu e-mail użytkowników Delta Chat.</p>
</li>
<li>
<p>Centralna usługa Push (Apple, Google itp.) budzi aplikację Delta Chat na twoim urządzeniu, aby sprawdzić w tle nowe wiadomości. Nie zna chatmaila ani adresu e-mail urządzenia, na którym się budzi. Centralne usługi push Apple/Google nigdy nie widzą adresu e-mail (nadawcy ani odbiorcy), a także nigdy nie widzą treści wiadomości (również w formie zaszyfrowanej).</p>
</li>
</ul>
<p>Od maja 2024 r. serwery chatmail znają „tokeny urządzenia”, ale planujemy szyfrować te informacje na serwerze proxy powiadomień, tak aby serwer chatmail nigdy nie poznał tokena urządzenia.</p>
<p>Centralny serwer proxy powiadomień Delta Chat <a href="https://github.com/deltachat/notifiers">jest mały i w pełni zaimplementowany w Rust</a> i zapomina o tokenach urządzeń zaraz po ich przetworzeniu przez Apple/Google/itp, zwykle w ciągu kilku milisekund.</p>
<p>Pamiętaj, że token urządzenia jest szyfrowany między aplikacjami a serwerem proxy powiadomień, ale nie jest podpisany. Serwer proxy powiadomień nigdy nie widzi adresów e-mail, adresów IP ani żadnych kryptograficznych informacji identyfikujących powiązanych z urządzeniem użytkownika (tokenem).</p>
<p>W wyniku tego ogólnego projektu ochrony prywatności nawet przejęcie serwera chatmail lub pełne przejęcie centralnego serwera proxy powiadomień Delta Chat nie spowodowałoby ujawnienia prywatnych informacji, których usługi Push jeszcze nie posiadają.</p>
<h3 id="dlaczego-delta-chat-integruje-się-ze-scentralizowanymi-zastrzeżonymi-usługami-push-applegoogle">
@@ -941,6 +941,12 @@ W przypadku innych programów można znaleźć rozwiązanie online.</p>
<p>Na <strong>Windowsie</strong>, przejdź do <strong>Panel sterowania / Sieć i internet</strong> i upewnij się, że <strong>Sieć prywatna</strong> jest wybrana jako “Typ profilu sieci”
(po przeniesieniu możesz wrócić do pierwotnej wartości)</p>
</li>
<li>
<p>W systemie <strong>iOS</strong> upewnij się, że jest przydzielony dostęp do opcji „Ustawienia » Aplikacje » Delta Chat » <strong>Sieć lokalna</strong></p>
</li>
<li>
<p>W systemie <strong>macOS</strong> włącz „Preferencje systemowe » Ochrona i prywatność » <strong>Sieć lokalna</strong> » Delta Chat”</p>
</li>
<li>
<p>Twój system może mieć „zaporę ogniową”, o której wiadomo, że powoduje problemy (szczególnie w systemie Windows).
<strong>Wyłącz zaporę</strong> dla Delta Chat po obu stronach i spróbuj ponownie</p>
@@ -1031,6 +1037,7 @@ W przypadku innych programów można znaleźć rozwiązanie online.</p>
<ul>
<li>Ogólnie rzecz biorąc, każdy może udostępniać sobie aplikacje webxdc bez ograniczeń.</li>
<li>Od <a href="https://webxdc.org/apps/">webxdc.org/apps</a>.</li>
<li>Możesz <a href="https://delta.chat/en/2023-08-11-xstore">wysłać „hi” na adres xstore@testrun.org</a>, aby zobaczyć eksperymentalny sklep z aplikacjami webxdc. Wszystkie aplikacje są otwarto źródłowe i są bezpłatne.</li>
<li>Wiele osób pisze własne, aplikacje webxdc i publikuje je na <a href="https://support.delta.chat/c/webxdc/20">forum Delta Chat</a>.</li>
</ul>
@@ -1356,6 +1363,34 @@ jeśli chcesz sprawdzić, czy Twoje poświadczenia są przetwarzane w bezpieczny
<li>Zobacz <a href="https://github.com/deltachat/deltachat-core-rust/blob/master/standards.md#standards-used-in-delta-chat">Standardy używane w Delta Chat</a>.</li>
</ul>
<h3 id="gdzie-moi-znajomi-mogą-znaleźć-delta-chat">
Gdzie moi znajomi mogą znaleźć Delta Chat? <a href="#gdzie-moi-znajomi-mogą-znaleźć-delta-chat" class="anchor"></a>
</h3>
<p>Delta Chat jest dostępny na wszystkich głównych i niektórych mniejszych platformach:</p>
<ul>
<li>
<p>Oficjalna <strong>strona internetowa</strong> <a href="https://delta.chat/download">https://delta.chat/download</a> pokazuje wszystkie opcje szczegółowo</p>
</li>
<li>
<p>Jeśli nie jest dostępna, użyj <strong>kopii strony</strong> pod adresem <a href="https://deltachat.github.io/deltachat-pages">https://deltachat.github.io/deltachat-pages</a></p>
</li>
<li>
<p>Otwórz jeden z następujących <strong>sklepów z aplikacjami i wyszukaj „Delta Chat”</strong>: Google Play Store, F-Droid, Huawei App Gallery, Amazon App Store, iOS i macOS App Store, Microsoft Store</p>
</li>
<li>
<p>Sprawdź <strong>menedżera pakietów</strong> swoich dystrybucji Linuksa</p>
</li>
<li>
<p><strong>Aplikacje na Androida</strong> są również dostępne na <a href="https://github.com/deltachat/deltachat-android/releases">https://github.com/deltachat/deltachat-android/releases</a></p>
</li>
</ul>
<h3 id="w-jaki-sposób-finansowany-jest-rozwój-delta-chat">
+47 -10
View File
@@ -99,6 +99,7 @@
<li><a href="#o-delta-chat-é-compatível-com-protonmail--tutanota--criptext">O Delta Chat é compatível com Protonmail / Tutanota / Criptext?</a></li>
<li><a href="#remove-account">How can I delete my account?</a></li>
<li><a href="#estou-interessado-nos-detalhes-técnicos-pode-me-dizer-mais">Estou interessado nos detalhes técnicos. Pode me dizer mais?</a></li>
<li><a href="#where-can-my-friends-find-delta-chat">Where can my friends find Delta Chat?</a></li>
<li><a href="#como-são-os-desenvolvimentos-do-delta-chat-financiados">Como são os desenvolvimentos do Delta Chat financiados?</a></li>
</ul>
</li>
@@ -297,8 +298,7 @@ Archived chats remain accessible above the chat list or via search.</p>
</li>
</ul>
<p>To archive or pin a chat, long tap (Android), use the chats menu (Android/Desktop) or swipe to the left (iOS);
to mute a chat, use the chats menu (Android/Desktop) or the chats profile (iOS).</p>
<p>To use the functions, long tap or right click a chat in the chat list.</p>
<h3 id="what-does-the-green-dot-mean">
@@ -597,16 +597,16 @@ to any system involved in the delivery of Push Notifications.</p>
<ul>
<li>
<p>A Delta Chat app obtains a “device token” locally and stores it
<p>A Delta Chat app obtains a “device token” locally, encrypts it and stores it
on the <a href="https://delta.chat/chatmail">chatmail</a> server.</p>
</li>
<li>
<p>When a <a href="https://delta.chat/chatmail">chatmail</a> server receives an e-mail for a Delta Chat user
it forwards the device token to the central Delta Chat notification proxy.</p>
it forwards the encrypted device token to the central Delta Chat notification proxy.</p>
</li>
<li>
<p>The central Delta Chat notification proxy forwards
the “device token” to the respective Push service (Apple, Google, etc.),
<p>The central Delta Chat notification proxy decrypts the device token
and forwards it to the respective Push service (Apple, Google, etc.),
without ever knowing the IP or e-mail address of Delta Chat users.</p>
</li>
<li>
@@ -619,14 +619,15 @@ and also never see any message content (also not in encrypted forms).</p>
</li>
</ul>
<p>As of May 2024, chatmail servers know about “device tokens”
but we plan to encrypt this information to the notification proxy
such that the chatmail server never learns the device token.</p>
<p>The central Delta Chat notification proxy <a href="https://github.com/deltachat/notifiers">is small and fully implemented in Rust</a>
and forgets about device-tokens as soon as Apple/Google/etc processed them,
usually in a matter of milliseconds.</p>
<p>Note that the device token is encrypted between apps and notification proxy
but it is not signed.
The notification proxy thus never sees e-mail addresses, IP-addresses or
any cryptographic identity information associated with a users device (token).</p>
<p>Resulting from this overall privacy design, even the seizure of a chatmail server,
or the full seizure of the central Delta Chat notification proxy
would not reveal private information that Push services do not already have.</p>
@@ -1309,6 +1310,12 @@ One device is not needed for the other to work.</p>
and make sure, <strong>Private Network</strong> is selected as “Network profile type”
(after transfer, you can change back to the original value)</p>
</li>
<li>
<p>On <strong>iOS</strong>, make sure “System Settings / Apps / Delta Chat / <strong>Local Network</strong>” access is granted</p>
</li>
<li>
<p>On <strong>macOS</strong>, enable “System Settings / Privacy &amp; Security / <strong>Local Network</strong> / Delta Chat”</p>
</li>
<li>
<p>Your system might have a “personal firewall”,
which is known to cause problems (especially on Windows).
@@ -1426,6 +1433,7 @@ you only open attachments from senders you trust, and not from spammers.</li>
<ul>
<li>In general, anyone can share webxdc apps with each
other without restrictions.</li>
<li>From <a href="https://webxdc.org/apps/">webxdc.org/apps</a>.</li>
<li>You can <a href="https://delta.chat/en/2023-08-11-xstore">send hi to xstore@testrun.org</a>
to see an experimental webxdc appstore.
All of the apps are open source and for free.</li>
@@ -1869,6 +1877,35 @@ Otherwise you might receive undecryptable messages from those group chats.</p>
<li>Veja <a href="https://github.com/deltachat/deltachat-core-rust/blob/master/standards.md#standards-used-in-delta-chat">As normas usadas no Delta Chat</a>.</li>
</ul>
<h3 id="where-can-my-friends-find-delta-chat">
Where can my friends find Delta Chat? <a href="#where-can-my-friends-find-delta-chat" class="anchor"></a>
</h3>
<p>Delta Chat is available for all major and some minor platforms:</p>
<ul>
<li>
<p>The <strong>official website</strong>, <a href="https://delta.chat/download">https://delta.chat/download</a> shows all options in detail</p>
</li>
<li>
<p>If unavailable, use the <strong>mirror</strong> at <a href="https://deltachat.github.io/deltachat-pages">https://deltachat.github.io/deltachat-pages</a></p>
</li>
<li>
<p>Open one of the following <strong>app stores and search for “Delta Chat”:</strong>
Google Play Store, F-Droid, Huawei App Gallery, Amazon App Store, iOS and macOS App Store, Microsoft Store</p>
</li>
<li>
<p>Check the <strong>package manager</strong> of your Linux distributions</p>
</li>
<li>
<p><strong>Android APKs</strong> are also available on <a href="https://github.com/deltachat/deltachat-android/releases">https://github.com/deltachat/deltachat-android/releases</a></p>
</li>
</ul>
<h3 id="como-são-os-desenvolvimentos-do-delta-chat-financiados">
+75 -39
View File
@@ -87,7 +87,7 @@
<li><a href="#разное">Разное</a>
<ul>
<li><a href="#какие-разрешения-нужны-delta-chat">Какие разрешения нужны Delta Chat?</a></li>
<li><a href="#работает-ли-delta-chat-работу-с-моим-провайдером-электронной-почты">Работает ли Delta Chat работу с <em>моим</em> провайдером электронной почты?</a></li>
<li><a href="#работает-ли-delta-chat-с-моим-провайдером-электронной-почты">Работает ли Delta Chat с <em>моим</em> провайдером электронной почты?</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>
@@ -99,6 +99,7 @@
<li><a href="#совместим-ли-delta-chat-с-protonmail--tutanota--criptext">Совместим ли Delta Chat с Protonmail / Tutanota / Criptext?</a></li>
<li><a href="#remove-account">Как я могу удалить свой аккаунт?</a></li>
<li><a href="#меня-интересуют-технические-детали-можете-рассказать-больше">Меня интересуют технические детали. Можете рассказать больше?</a></li>
<li><a href="#где-мои-друзья-могут-найти-delta-chat">Где мои друзья могут найти Delta Chat?</a></li>
<li><a href="#как-финансируются-разработки-delta-chat">Как финансируются разработки Delta Chat?</a></li>
</ul>
</li>
@@ -217,7 +218,7 @@
</h3>
<p>Профиль - это <strong>имя, изображение</strong> и некоторая дополнительная информация для шифрования сообщений.
<p>Профиль это <strong>имя, изображение</strong> и некоторая дополнительная информация для шифрования сообщений.
Профиль существует только на вашем устройстве(ах)
и использует серверы chatmail или обычные серверы электронной почты для передачи сообщений.</p>
@@ -301,8 +302,7 @@
</li>
</ul>
<p>Чтобы архивировать или закрепить чат, нажмите на него долгим нажатием (Android), воспользуйтесь меню чата (Android/Desktop) или проведите пальцем влево (iOS);
чтобы отключить уведомления, воспользуйтесь меню чата (Android/Desktop) или профиль чата (iOS).</p>
<p>Чтобы использовать функции, нажмите долгим нажатием или щелкните правой кнопкой мыши по чату в списке чатов.</p>
<h3 id="что-означает-зеленая-точка">
@@ -350,7 +350,7 @@
приложение Delta Chat каждого участника чата позаботится
об удалении сообщений
по истечении выбранного периода времени.
Отсчет времени начинается
Отсчет времени начинается,
когда получатель впервые видит сообщение в Delta Chat.
Сообщения удаляются
как в каждой учетной записи электронной почты на сервере,
@@ -429,7 +429,7 @@
Если позже вы снова захотите присоединиться к группе, попросите другого участника группы добавить вас.</p>
</li>
<li>
<p>Или, вместо этого, вы можете “отключить уведомления” для группы - это означает, что вы будете получать все сообщения и сможете их писать, но больше не будете получать уведомления о новых сообщениях.</p>
<p>Или, вместо этого, вы можете “отключить уведомления” для группы это означает, что вы будете получать все сообщения и сможете их писать, но больше не будете получать уведомления о новых сообщениях.</p>
</li>
</ul>
@@ -474,7 +474,7 @@
По истечении этого срока все сообщения, полученные Delta Chat, будут удалены с сервера.</p>
</li>
<li>
<p>Обратите внимание, что если вы используете Delta Chat на нескольких устройствах,
<p>Обратите внимание, что, если вы используете Delta Chat на нескольких устройствах,
необходимо оставлять сообщения на сервере с достаточным временным интервалом,
чтобы другое устройство(а) тоже смогло их загрузить.</p>
</li>
@@ -575,8 +575,8 @@ Push-уведомления недоступны.</p>
</li>
<li>
<p>Принудительное соединение в фоновом режиме: это запасной вариант
если предыдущие варианты недоступны или или не обеспечивают “мгновенную доставку”.
Включение этого параметра вызывает постоянное уведомление на вашем телефоне
если предыдущие варианты недоступны или не обеспечивают “мгновенную доставку”.
Включение этого параметра вызывает постоянное уведомление на вашем телефоне,
которое иногда может быть “сжато” на последних телефонах Android.</p>
</li>
</ul>
@@ -600,16 +600,16 @@ Push-уведомления недоступны.</p>
<ul>
<li>
<p>Приложение Delta Chat локально получает “токен устройства” и сохраняет его
<p>Приложение Delta Chat локально получает “токен устройства” шифрует его и сохраняет
на сервере <a href="https://delta.chat/chatmail">chatmail</a>.</p>
</li>
<li>
<p>Когда сервер <a href="https://delta.chat/chatmail">chatmail</a> получает электронную почту для пользователя Delta Chat
он пересылает “токен устройства” центральному прокси-серверу уведомлений Delta Chat.</p>
он пересылает “зашифрованный токен устройства” центральному прокси-серверу уведомлений Delta Chat.</p>
</li>
<li>
<p>Центральный прокси-сервер уведомлений Delta Chat пересылает
“токен устройства” в соответствующую службу Push (Apple, Google и т. д.),
<p>Центральный прокси-сервер уведомлений Delta Chat расшифровывает “токен устройства” и
пересылает его в соответствующую службу Push (Apple, Google и т. д.),
даже не зная IP-адрес или адрес электронной почты пользователей Delta Chat.</p>
</li>
<li>
@@ -622,14 +622,15 @@ Push-уведомления недоступны.</p>
</li>
</ul>
<p>По состоянию на май 2024 года серверы chatmail знают о “токенах устройства”,
но мы планируем зашифровать эту информацию для прокси-сервера уведомлений
так, чтобы сервер chatmail не смог получить доступ к токену устройства.</p>
<p>Центральный прокси-сервер уведомлений Delta Chat <a href="https://github.com/deltachat/notifiers">небольшой и полностью реализован на Rust</a>
забывает о токенах устройств, как только Apple/Google/и т. д. обработали их,
обычно за несколько миллисекунд.</p>
<p>Обратите внимание, что токен устройства шифруется между приложениями и прокси-сервером уведомлений,
но не подписывается.
Прокси-сервер уведомлений не получает доступ к адресам электронной почты, IP-адресам
или криптографическим идентификационным данным устройства пользователя (токену).</p>
<p>В результате такого общего подхода к обеспечению конфиденциальности, даже захват почтового сервера chatmail,
или полный захват центрального прокси-сервера уведомлений Delta Chat
не раскроет конфиденциальную информацию, которой сервисы Push уже не обладают.</p>
@@ -642,7 +643,7 @@ Push-уведомления недоступны.</p>
</h3>
<p>Delta Chat - это бесплатный децентрализованный мессенджер с открытым исходным кодом и возможностью выбора сервера,
<p>Delta Chat это бесплатный децентрализованный мессенджер с открытым исходным кодом и возможностью выбора сервера,
но мы хотим, чтобы пользователи гарантированно получали “мгновенную доставку” сообщений,
такую же, что и в приложениях WhatsApp, Signal или Telegram,
не задавая вопросов, которые больше подходят для опытных пользователей или разработчиков.</p>
@@ -671,7 +672,7 @@ Push-уведомления недоступны.</p>
<p><a href="https://autocrypt.org">Autocrypt</a> используется для автоматической
установки сквозного шифрования при работе с контактами и групповыми чатами.
Autocrypt использует ограниченное и <a href="#openpgp-secure">безопасное подмножество стандарта OpenPGP</a>.
Сообщения, зашифрованные сквозным шифрованием помечаются замком
Сообщения, зашифрованные сквозным шифрованием, помечаются замком
<img style="vertical-align:middle; width:1.2em; margin:1px" src="../lock-icon.png" alt="padlock" />.</p>
<p><a href="https://securejoin.delta.chat/en/latest/new.html">Протоколы Secure-Join</a>
@@ -689,7 +690,7 @@ Autocrypt использует ограниченное и <a href="#openpgp-sec
</h3>
<p>Все сообщения зашифрованые сквозным шифрованием имеют значок замка:</p>
<p>Все сообщения, зашифрованные сквозным шифрованием, имеют значок замка:</p>
<p><img style="width:160px; margin:1px" src="../lock-screenshot.png" alt="Значок замка в пузырьке" /></p>
@@ -779,7 +780,7 @@ Autocrypt использует ограниченное и <a href="#openpgp-sec
В профиле контакта можно несколько раз нажать на текст “Представлен …” несколько раз
пока не дойдёте до того, с кем вы непосредственно провели <a href="#howtoe2ee">QR-сканирование</a>.</p>
<p>Обратите внимание, что в профиле контакта вы можете увидеть и присоеденённых знакомых
<p>Обратите внимание, что в профиле контакта вы можете увидеть и присоединённых знакомых,
но в заголовке профиля нет зелёной галочки.
Обычно это означает, что контакт <a href="#nocryptanymore">“отправил сообщение с другого устройства”</a>.</p>
@@ -797,10 +798,10 @@ Autocrypt использует ограниченное и <a href="#openpgp-sec
</h3>
<p>Ваш чат с контактом утратил гарантированное сквозное шифрование.
Зелёная галочка была удалёна для этого чата и контакта, и когда вы увидели предупреждение.
Зелёная галочка была удалена для этого чата и контакта, и когда вы увидели предупреждение.
<strong>Если вы обнаружили внезапное прекращение гарантированного сквозного шифрования
для этого контакта, не принимайте предупреждение!</strong>
Вместо этого свяжитесь со своим контактом по второму каналу
Вместо этого свяжитесь со своим контактом по второму каналу,
например, видеозвонок, другой мессенджер или телефонный звонок,
чтобы узнать, что произошло.</p>
@@ -935,7 +936,7 @@ Delta Chat вместо этого использует реализацию Ope
и возвращает <a href="https://docs.rs/pgp/latest/pgp/errors/enum.Error.html#variant.MdcError">ошибку</a>
если код обнаружения модификаций не совпадает.</p>
<p>Delta Chat также никогда не был уязвим к атаке “Direct Exfiltration” EFAIL
<p>Delta Chat также никогда не был уязвим к атаке “Direct Exfiltration” EFAIL,
потому что он расшифровывает только <code class="language-plaintext highlighter-rouge">многочастные/зашифрованные</code> сообщения,
которые содержат ровно одну зашифрованную и подписанную часть,
как определено спецификацией Autocrypt Level 1.</p>
@@ -1172,16 +1173,16 @@ Look for something like <strong>Start Autocrypt Setup Transfer</strong> in the s
</h3>
<p>Наиболее вероятная причина - это то, что ваш ключ зашифрован и/или имеет пароль.
<p>Наиболее вероятная причина это то, что ваш ключ зашифрован и/или имеет пароль.
Delta Chat не поддерживает такие ключи.
Вы можете снять шифрование пароля и пароль, а затем повторить попытку импорта.</p>
<p>Другая распространенная ошибка - неправильное расширение файла.
Используйте формат ASCII armored и расширение файла <code class="language-plaintext highlighter-rouge">.asc</code>.</p>
<p>Delta Chat поддерживает расспространённые форматы закрытых ключей OpenPGP, однако
<p>Delta Chat поддерживает распространённые форматы закрытых ключей OpenPGP, однако
маловероятно, что мы будем поддерживать все закрытые ключи из любых источников. Это
не является основной целью Delta Chat. На самом деле, подавляющее большинство пользователей 
не является основной целью Delta Chat. На самом деле, подавляющее большинство пользователей
Delta Chat не будут иметь никакого ключа, прежде чем они начнут использовать его.
Однако мы стремимся поддерживать закрытые ключи из как можно большего числа источников.</p>
@@ -1305,13 +1306,19 @@ Chat <a href="https://github.com/rpgp/rpgp">PGP</a> и
<ul>
<li>
<p>Перепроверьте, что оба устройства находятся в <strong>в одной Wi-Fi или локальной сети</strong>.</p>
<p>Перепроверьте, что оба устройства находятся <strong>в одной Wi-Fi или локальной сети</strong>.</p>
</li>
<li>
<p>В <strong>Windows</strong> перейдите в <strong>Панель управления / Сеть и Интернет</strong>
и убедитесь, что в качестве “Типа сетевого профиля” выбрана <strong>Частная сеть</strong>.
(после передачи, вы можете изменить обратно на исходное значение)</p>
</li>
<li>
<p>На <strong>iOS</strong>, убедитесь, что предоставлен доступ “Настройки системы / Приложения / Delta Chat / <strong>Локальная сеть</strong></p>
</li>
<li>
<p>На <strong>macOS</strong>, включите “Системные настройки / Конфиденциальность и безопасность / <strong>Локальная сеть</strong> / Delta Chat”</p>
</li>
<li>
<p>В вашей системе может быть установлен “персональный брандмауэр”,
который может вызвать проблемы (особенно на Windows).
@@ -1407,12 +1414,12 @@ PIN-код разблокировки экрана, графический кл
</h3>
<ul>
<li>Приложения webxdc webxdc не могут отправлять данные в Интернет или скачивать что-либо.</li>
<li>Приложения webxdc не могут отправлять данные в Интернет или скачивать что-либо.</li>
<li>Приложение webxdc может обмениваться данными только внутри чата Delta Chat, с его
копиями на устройствах ваших собеседников по чату.
В остальном, оно полностью
изолировано от Интернета.</li>
<li>Конфиденциальность, которую обеспечивает приложение webxdc - это конфиденциальность вашего чата - пока
<li>Конфиденциальность, которую обеспечивает приложение webxdc это конфиденциальность вашего чата - пока
вы доверяете людям, с которыми вы общаетесь, вы можете доверять приложению webxdc.</li>
<li>Это также означает, что открытие приложений webxdc в чатах с участниками, которым вы
не доверяете, тоже самое, что и с вложениями электронной почты, когда вы открываете
@@ -1430,11 +1437,11 @@ PIN-код разблокировки экрана, графический кл
<ul>
<li>В общем, каждый может поделиться приложениями webxdc
друг с другом без ограничений.</li>
<li>Из <a href="https://webxdc.org/apps/">webxdc.org/apps</a>.</li>
<li>Вы можете <a href="https://delta.chat/en/2023-08-11-xstore">отправить hi на xstore@testrun.org</a>
чтобы увидеть экспериментальный магазин приложений webxdc.
Все приложения с открытым исходным кодом и бесплатны.</li>
<li>Многие люди пишут свои собственные приложения webxdc и публикуют их на <a href="https://support.delta.chat/c/webxdc/20">форуме
Delta Chat</a>.</li>
<li>Многие люди создают свои собственные приложения webxdc и публикуют их на <a href="https://support.delta.chat/c/webxdc/20">форуме Delta Chat</a>.</li>
</ul>
<h3 id="как-я-могу-создать-свои-собственные-приложения-webxdc">
@@ -1446,7 +1453,7 @@ Delta Chat</a>.</li>
</h3>
<ul>
<li>Приложения webxdc - это просто архивы zip, содержащие код html, css и javascript.</li>
<li>Приложения webxdc это просто архивы zip, содержащие код html, css и javascript.</li>
<li>Вы можете расширить <a href="https://github.com/webxdc/hello">пример приложения Hello World</a>
для начала.</li>
<li>Все остальное, что вам нужно знать, написано в
@@ -1572,7 +1579,7 @@ Delta Chat</a>.</li>
<ol>
<li>
<p>Измените свой адрес в разделе “Настройки → Дополнительные параметры → Пароль и аккаунт” и
введите пароль вашей новой электронной почты (и если необходимо, настройки сервера).
введите пароль вашей новой электронной почты (и, если необходимо, настройки сервера).
Вы получите информационное сообщение о том, что переходите на новый адрес.
Дополнительное уведомление также появится в вашем чате “Сообщения устройства”.</p>
</li>
@@ -1656,10 +1663,10 @@ Delta Chat</a>.</li>
</li>
</ul>
<h3 id="работает-ли-delta-chat-работу-с-моим-провайдером-электронной-почты">
<h3 id="работает-ли-delta-chat-с-моим-провайдером-электронной-почты">
Работает ли Delta Chat работу с <em>моим</em> провайдером электронной почты? <a href="#работает-ли-delta-chat-работу-с-моим-провайдером-электронной-почты" class="anchor"></a>
Работает ли Delta Chat с <em>моим</em> провайдером электронной почты? <a href="#работает-ли-delta-chat-с-моим-провайдером-электронной-почты" class="anchor"></a>
</h3>
@@ -1791,7 +1798,7 @@ Delta Chat необходим пароль, чтобы использовать
</h3>
<p>Единственная причина, по которой вы можете захотеть наблюдать за папкой “Отправленные”, - это если вы используете другую
<p>Единственная причина, по которой вы можете захотеть наблюдать за папкой “Отправленные”, это если вы используете другую
почтовую программу (например, Thunderbird) вместе с приложением Delta Chat, и хотите, чтобы ваш почтовый клиент
мог участвовать в разговорах в чате.</p>
@@ -1879,6 +1886,35 @@ Chat.</li>
<li>Смотрите <a href="https://github.com/deltachat/deltachat-core-rust/blob/master/standards.md#standards-used-in-delta-chat">Стандарты, используемые в Delta Chat</a>.</li>
</ul>
<h3 id="где-мои-друзья-могут-найти-delta-chat">
Где мои друзья могут найти Delta Chat? <a href="#где-мои-друзья-могут-найти-delta-chat" class="anchor"></a>
</h3>
<p>Delta Chat доступен на всех популярных и некоторых менее известных платформах:</p>
<ul>
<li>
<p>На <strong>официальной странице загрузки</strong>, <a href="https://delta.chat/download">https://delta.chat/download</a> можно найти подробную информацию о всех вариантах</p>
</li>
<li>
<p>Если основной сайт недоступен, используйте <strong>зеркало</strong> <a href="https://deltachat.github.io/deltachat-pages">https://deltachat.github.io/deltachat-pages</a></p>
</li>
<li>
<p>Откройте один из следующих <strong>онлайн-магазинов приложений и введите запрос “Delta Chat”:</strong>
Google Play Store, F-Droid, Huawei App Gallery, Amazon App Store, App Store для iOS и macOS, Microsoft Store</p>
</li>
<li>
<p>Проверьте <strong>менеджер пакетов</strong> вашего дистрибутива Linux</p>
</li>
<li>
<p>Файлы <strong>APK для Android</strong> доступны на <a href="https://github.com/deltachat/deltachat-android/releases">https://github.com/deltachat/deltachat-android/releases</a></p>
</li>
</ul>
<h3 id="как-финансируются-разработки-delta-chat">
@@ -1895,7 +1931,7 @@ Chat.</li>
основанную на Свободном и Открытом исходном коде.</p>
<p>В частности, разработка Delta Chat финансировалась из следующих источников,
перечисленны в хронологическом порядке:</p>
перечислены в хронологическом порядке:</p>
<ul>
<li>
@@ -1910,7 +1946,7 @@ Chat.</li>
и выпустили первую бета-версию приложения для настольных систем, а также провели
исследования в области UX в контексте прав человека,
см. наш заключительный отчет <a href="https://delta.chat/en/2019-07-19-uxreport">Needfinding and UX report</a>.
Второй грант, полученый в 2019/2020 году (~$300тыс.), помог нам
Второй грант, полученный в 2019/2020 году (~$300 тыс.), помог нам
выпустить версии Delta/iOS, перевести наш основной код на Rust и
предоставить новые функции для всех платформ.</p>
</li>
+47 -10
View File
@@ -99,6 +99,7 @@
<li><a href="#je-delta-chat-kompatibilný-s-protonmail--tutanota--criptext">Je Delta Chat kompatibilný s Protonmail / Tutanota / Criptext?</a></li>
<li><a href="#remove-account">How can I delete my account?</a></li>
<li><a href="#zaujímajú-ma-technické-detaily-môžete-mi-povedať-viac">Zaujímajú ma technické detaily. Môžete mi povedať viac?</a></li>
<li><a href="#where-can-my-friends-find-delta-chat">Where can my friends find Delta Chat?</a></li>
<li><a href="#ako-sa-financuje-vývoj-delta-chat">Ako sa financuje vývoj Delta Chat?</a></li>
</ul>
</li>
@@ -301,8 +302,7 @@ Archived chats remain accessible above the chat list or via search.</p>
</li>
</ul>
<p>To archive or pin a chat, long tap (Android), use the chats menu (Android/Desktop) or swipe to the left (iOS);
to mute a chat, use the chats menu (Android/Desktop) or the chats profile (iOS).</p>
<p>To use the functions, long tap or right click a chat in the chat list.</p>
<h3 id="what-does-the-green-dot-mean">
@@ -603,16 +603,16 @@ to any system involved in the delivery of Push Notifications.</p>
<ul>
<li>
<p>A Delta Chat app obtains a “device token” locally and stores it
<p>A Delta Chat app obtains a “device token” locally, encrypts it and stores it
on the <a href="https://delta.chat/chatmail">chatmail</a> server.</p>
</li>
<li>
<p>When a <a href="https://delta.chat/chatmail">chatmail</a> server receives an e-mail for a Delta Chat user
it forwards the device token to the central Delta Chat notification proxy.</p>
it forwards the encrypted device token to the central Delta Chat notification proxy.</p>
</li>
<li>
<p>The central Delta Chat notification proxy forwards
the “device token” to the respective Push service (Apple, Google, etc.),
<p>The central Delta Chat notification proxy decrypts the device token
and forwards it to the respective Push service (Apple, Google, etc.),
without ever knowing the IP or e-mail address of Delta Chat users.</p>
</li>
<li>
@@ -625,14 +625,15 @@ and also never see any message content (also not in encrypted forms).</p>
</li>
</ul>
<p>As of May 2024, chatmail servers know about “device tokens”
but we plan to encrypt this information to the notification proxy
such that the chatmail server never learns the device token.</p>
<p>The central Delta Chat notification proxy <a href="https://github.com/deltachat/notifiers">is small and fully implemented in Rust</a>
and forgets about device-tokens as soon as Apple/Google/etc processed them,
usually in a matter of milliseconds.</p>
<p>Note that the device token is encrypted between apps and notification proxy
but it is not signed.
The notification proxy thus never sees e-mail addresses, IP-addresses or
any cryptographic identity information associated with a users device (token).</p>
<p>Resulting from this overall privacy design, even the seizure of a chatmail server,
or the full seizure of the central Delta Chat notification proxy
would not reveal private information that Push services do not already have.</p>
@@ -1315,6 +1316,12 @@ One device is not needed for the other to work.</p>
and make sure, <strong>Private Network</strong> is selected as “Network profile type”
(after transfer, you can change back to the original value)</p>
</li>
<li>
<p>On <strong>iOS</strong>, make sure “System Settings / Apps / Delta Chat / <strong>Local Network</strong>” access is granted</p>
</li>
<li>
<p>On <strong>macOS</strong>, enable “System Settings / Privacy &amp; Security / <strong>Local Network</strong> / Delta Chat”</p>
</li>
<li>
<p>Your system might have a “personal firewall”,
which is known to cause problems (especially on Windows).
@@ -1432,6 +1439,7 @@ you only open attachments from senders you trust, and not from spammers.</li>
<ul>
<li>In general, anyone can share webxdc apps with each
other without restrictions.</li>
<li>From <a href="https://webxdc.org/apps/">webxdc.org/apps</a>.</li>
<li>You can <a href="https://delta.chat/en/2023-08-11-xstore">send hi to xstore@testrun.org</a>
to see an experimental webxdc appstore.
All of the apps are open source and for free.</li>
@@ -1879,6 +1887,35 @@ Otherwise you might receive undecryptable messages from those group chats.</p>
<li>Pozrite si <a href="https://github.com/deltachat/deltachat-core-rust/blob/master/standards.md#standards-used-in-delta-chat">Štandardy používané v Delta Chate</a>.</li>
</ul>
<h3 id="where-can-my-friends-find-delta-chat">
Where can my friends find Delta Chat? <a href="#where-can-my-friends-find-delta-chat" class="anchor"></a>
</h3>
<p>Delta Chat is available for all major and some minor platforms:</p>
<ul>
<li>
<p>The <strong>official website</strong>, <a href="https://delta.chat/download">https://delta.chat/download</a> shows all options in detail</p>
</li>
<li>
<p>If unavailable, use the <strong>mirror</strong> at <a href="https://deltachat.github.io/deltachat-pages">https://deltachat.github.io/deltachat-pages</a></p>
</li>
<li>
<p>Open one of the following <strong>app stores and search for “Delta Chat”:</strong>
Google Play Store, F-Droid, Huawei App Gallery, Amazon App Store, iOS and macOS App Store, Microsoft Store</p>
</li>
<li>
<p>Check the <strong>package manager</strong> of your Linux distributions</p>
</li>
<li>
<p><strong>Android APKs</strong> are also available on <a href="https://github.com/deltachat/deltachat-android/releases">https://github.com/deltachat/deltachat-android/releases</a></p>
</li>
</ul>
<h3 id="ako-sa-financuje-vývoj-delta-chat">
+45 -8
View File
@@ -99,6 +99,7 @@
<li><a href="#a-është-i-përputhshëm-delta-chat-i-me-protonmail-in--tutanota-n--criptext-in">A është i përputhshëm Delta Chat-i me Protonmail-in / Tutanota-n / Criptext-in?</a></li>
<li><a href="#remove-account">Si mund ta fshij llogarinë time?</a></li>
<li><a href="#më-interesojnë-hollësitë-teknike-mund-të-më-tregoni-diçka-më-tepër">Më interesojnë hollësitë teknike. Mund të më tregoni diçka më tepër?</a></li>
<li><a href="#where-can-my-friends-find-delta-chat">Where can my friends find Delta Chat?</a></li>
<li><a href="#si-financohet-zhvillimi-i-delta-chat-it">Si financohet zhvillimi i Delta Chat-it?</a></li>
</ul>
</li>
@@ -604,16 +605,16 @@ to any system involved in the delivery of Push Notifications.</p>
<ul>
<li>
<p>A Delta Chat app obtains a “device token” locally and stores it
<p>A Delta Chat app obtains a “device token” locally, encrypts it and stores it
on the <a href="https://delta.chat/chatmail">chatmail</a> server.</p>
</li>
<li>
<p>When a <a href="https://delta.chat/chatmail">chatmail</a> server receives an e-mail for a Delta Chat user
it forwards the device token to the central Delta Chat notification proxy.</p>
it forwards the encrypted device token to the central Delta Chat notification proxy.</p>
</li>
<li>
<p>The central Delta Chat notification proxy forwards
the “device token” to the respective Push service (Apple, Google, etc.),
<p>The central Delta Chat notification proxy decrypts the device token
and forwards it to the respective Push service (Apple, Google, etc.),
without ever knowing the IP or e-mail address of Delta Chat users.</p>
</li>
<li>
@@ -626,14 +627,15 @@ and also never see any message content (also not in encrypted forms).</p>
</li>
</ul>
<p>As of May 2024, chatmail servers know about “device tokens”
but we plan to encrypt this information to the notification proxy
such that the chatmail server never learns the device token.</p>
<p>The central Delta Chat notification proxy <a href="https://github.com/deltachat/notifiers">is small and fully implemented in Rust</a>
and forgets about device-tokens as soon as Apple/Google/etc processed them,
usually in a matter of milliseconds.</p>
<p>Note that the device token is encrypted between apps and notification proxy
but it is not signed.
The notification proxy thus never sees e-mail addresses, IP-addresses or
any cryptographic identity information associated with a users device (token).</p>
<p>Resulting from this overall privacy design, even the seizure of a chatmail server,
or the full seizure of the central Delta Chat notification proxy
would not reveal private information that Push services do not already have.</p>
@@ -1315,6 +1317,12 @@ Njëra pajisja ska nevojë për tjetrën që të funksionojë.</p>
and make sure, <strong>Private Network</strong> is selected as “Network profile type”
(after transfer, you can change back to the original value)</p>
</li>
<li>
<p>On <strong>iOS</strong>, make sure “System Settings / Apps / Delta Chat / <strong>Local Network</strong>” access is granted</p>
</li>
<li>
<p>On <strong>macOS</strong>, enable “System Settings / Privacy &amp; Security / <strong>Local Network</strong> / Delta Chat”</p>
</li>
<li>
<p>Sistemi juaj mund të ketë një “firewall personal”,
që dihet se shkakton probleme (veçanërisht në Windows).
@@ -1890,6 +1898,35 @@ Otherwise you might receive undecryptable messages from those group chats.</p>
<li>Shihni <a href="https://github.com/deltachat/deltachat-core-rust/blob/master/standards.md#standards-used-in-delta-chat">Standarde të përdorur në Delta Chat</a>.</li>
</ul>
<h3 id="where-can-my-friends-find-delta-chat">
Where can my friends find Delta Chat? <a href="#where-can-my-friends-find-delta-chat" class="anchor"></a>
</h3>
<p>Delta Chat is available for all major and some minor platforms:</p>
<ul>
<li>
<p>The <strong>official website</strong>, <a href="https://delta.chat/download">https://delta.chat/download</a> shows all options in detail</p>
</li>
<li>
<p>If unavailable, use the <strong>mirror</strong> at <a href="https://deltachat.github.io/deltachat-pages">https://deltachat.github.io/deltachat-pages</a></p>
</li>
<li>
<p>Open one of the following <strong>app stores and search for “Delta Chat”:</strong>
Google Play Store, F-Droid, Huawei App Gallery, Amazon App Store, iOS and macOS App Store, Microsoft Store</p>
</li>
<li>
<p>Check the <strong>package manager</strong> of your Linux distributions</p>
</li>
<li>
<p><strong>Android APKs</strong> are also available on <a href="https://github.com/deltachat/deltachat-android/releases">https://github.com/deltachat/deltachat-android/releases</a></p>
</li>
</ul>
<h3 id="si-financohet-zhvillimi-i-delta-chat-it">
+46 -9
View File
@@ -99,6 +99,7 @@
<li><a href="#чи-сумісний-delta-chat-із-protonmail--tutanota--criptext">Чи сумісний Delta Chat із Protonmail / Tutanota / Criptext?</a></li>
<li><a href="#remove-account">Як мені видалити свій обліковий запис?</a></li>
<li><a href="#мене-цікавлять-технічні-деталі-можете-розповісти-більше">Мене цікавлять технічні деталі. Можете розповісти більше?</a></li>
<li><a href="#де-мої-друзі-можуть-знайти-delta-chat">Де мої друзі можуть знайти Delta Chat?</a></li>
<li><a href="#як-фінансується-розробка-delta-chat">Як фінансується розробка Delta Chat?</a></li>
</ul>
</li>
@@ -267,7 +268,7 @@
</li>
</ul>
<p>Щоб заархівувати або закріпити чат, довго торкніться (Android), скористайтеся меню чату (Android/комп’ютер) або проведіть пальцем ліворуч (iOS); щоб вимкнути звук чату, скористайтеся меню чату (Android/комп’ютер) або профілем чату (iOS).</p>
<p>Щоб скористатися функціями, утримуйте натиснутою клавішу або клацніть правою кнопкою миші на чаті у списку чатів.</p>
<h3 id="що-означає-зелена-точка">
@@ -497,23 +498,23 @@ Push-сповіщення автоматично активуються для
<ul>
<li>
<p>Додаток Delta Chat отримує “токен пристрою” локально і зберігає його на сервері <a href="https://delta.chat/chatmail">chatmail</a>.</p>
<p>Додаток Delta Chat отримує “токен пристрою” локально, шифрує його і зберігає на сервері <a href="https://delta.chat/chatmail">chatmail</a>.</p>
</li>
<li>
<p>Коли <a href="https://delta.chat/chatmail">chatmail</a>-сервер отримує електронний лист від користувача Delta Chat він пересилає токен пристрою до центрального проксі-сповіщення Delta Chat.</p>
<p>Коли сервер <a href="https://delta.chat/chatmail">chatmail</a> отримує електронний лист від користувача Delta Chat він пересилає зашифрований токен пристрою до центрального проксі-сервера сповіщень Delta Chat.</p>
</li>
<li>
<p>Центральний проксі-сервер сповіщень Delta Chat пересилає токен пристрою до відповідного Push-сервісу (Apple, Google тощо), навіть не знаючи IP-адреси чи електронної пошти користувачів Delta Chat.</p>
<p>Центральний проксі-сервер сповіщень Delta Chat розшифровує токен пристрою і пересилає його до відповідного Push-сервісу (Apple, Google тощо), навіть не знаючи IP-адреси або електронної пошти користувачів Delta Chat.</p>
</li>
<li>
<p>Центральний Push-сервіс (Apple, Google тощо) запускає додаток Delta Chat на вашому пристрої щоб перевірити наявність нових повідомлень у фоновому режимі. Він не знає про пошту чату або адресу електронної пошти пристрою, який він пробуджує. Центральні служби Apple/Google Push ніколи не бачать адресу електронної пошти (відправника або одержувача) а також ніколи не бачать жодного вмісту повідомлення (навіть в зашифрованому вигляді).</p>
</li>
</ul>
<p>Станом на травень 2024 року chatmail-сервери знають про “токени пристроїв” але ми плануємо зашифрувати цю інформацію для проксі-сповіщень таким чином, щоб сервер чату ніколи не дізнався токен пристрою.</p>
<p>Центральний проксі для сповіщень Delta Chat <a href="https://github.com/deltachat/notifiers">невеликий і повністю реалізований на Rust</a> забуває про токени пристроїв, як тільки Apple/Google/etc обробили їх, зазвичай за лічені мілісекунди.</p>
<p>Зверніть увагу, що токен пристрою шифрується між програмами та проксі-сповіщеннями але не підписується. Таким чином, проксі-служба сповіщень ніколи не бачить адреси електронної пошти, IP-адреси або будь-яку криптографічну ідентифікаційну інформацію, пов’язану з пристроєм користувача (токеном).</p>
<p>В результаті цього загального дизайну конфіденційності, навіть захоплення chatmail-сервера, або повне вилучення центрального проксі-сервера повідомлень Delta Chat не призведе до розкриття приватної інформації, якої ще не мають Push-сервіси.</p>
<h3 id="чому-delta-chat-інтегрується-з-централізованими-пропрієтарними-push-сервісами-applegoogle">
@@ -944,6 +945,12 @@ Look for something like <strong>Start Autocrypt Setup Transfer</strong> in the s
<li>
<p>У <strong>Windows</strong> перейдіть до <strong>Панель керування / Мережа та Інтернет</strong> і переконайтеся, що <strong>Приватна мережа</strong> вибрано як “Тип мережевого профілю” (після перенесення ви можете повернути початкове значення)</p>
</li>
<li>
<p>На <strong>iOS</strong> переконайтеся, що доступ до “Системні налаштування / Програми / Delta Chat / <strong>Локальна мережа</strong>” дозволено</p>
</li>
<li>
<p>У <strong>macOS</strong> увімкніть “Системні налаштування / Конфіденційність і безпека / <strong>Локальна мережа</strong> / Delta Chat”</p>
</li>
<li>
<p>Ваша система може мати “персональний брандмауер”, який, як відомо, викликає проблеми (особливо у Windows). <strong>Вимкніть персональний брандмауер</strong> для Delta Chat на обох кінцях і повторіть спробу</p>
</li>
@@ -1032,9 +1039,11 @@ Look for something like <strong>Start Autocrypt Setup Transfer</strong> in the s
</h3>
<ul>
<li>Загалом, будь-хто може ділитися додатками webxdc один з одним один з одним без обмежень.</li>
<li>Ви можете <a href="https://delta.chat/en/2023-08-11-xstore">надіслати “hi” на xstore@testrun.org</a> щоб побачити експериментальний магазин додатків webxdc. Всі програми мають відкритий вихідний код і є безкоштовними.</li>
<li>Багато людей пишуть власні програми для webxdc і публікують їх на <a href="https://support.delta.chat/c/webxdc/20">форумі Delta Chat</a>.</li>
<li>Загалом, будь-хто може ділитися додатками webxdc один з одним без обмежень.</li>
<li>З <a href="https://webxdc.org/apps/">webxdc.org/apps</a>.</li>
<li>Ви можете <a href="https://delta.chat/en/2023-08-11-xstore">надіслати “привіт” на xstore@testrun.org</a> щоб побачити експериментальний магазин додатків webxdc.
Всі програми мають відкритий вихідний код і є безкоштовними.</li>
<li>Багато людей пишуть власні програми webxdc і публікують їх на <a href="https://support.delta.chat/c/webxdc/20">форумі Delta Chat</a>.</li>
</ul>
<h3 id="як-я-можу-створювати-власні-програми-webxdc">
@@ -1374,6 +1383,34 @@ Look for something like <strong>Start Autocrypt Setup Transfer</strong> in the s
<li>Дивіться <a href="https://github.com/deltachat/deltachat-core-rust/blob/master/standards.md#standards-used-in-delta-chat">Стандарти, що використовуються у Delta Chat</a>.</li>
</ul>
<h3 id="де-мої-друзі-можуть-знайти-delta-chat">
Де мої друзі можуть знайти Delta Chat? <a href="#де-мої-друзі-можуть-знайти-delta-chat" class="anchor"></a>
</h3>
<p>Delta Chat доступний для всіх основних і деяких другорядних платформ:</p>
<ul>
<li>
<p>На <strong>офіційному сайті</strong>, <a href="https://delta.chat/download">https://delta.chat/download</a> детально описані всі варіанти</p>
</li>
<li>
<p>Якщо вона недоступна, скористайтеся <strong>дзеркалом</strong> за адресою <a href="https://deltachat.github.io/deltachat-pages">https://deltachat.github.io/deltachat-pages</a></p>
</li>
<li>
<p>Відкрийте один з наступних <strong>магазинів додатків і введіть у пошук “Delta Chat”:</strong> Google Play Store, F-Droid, Huawei App Gallery, Amazon App Store, iOS та macOS App Store, Microsoft Store</p>
</li>
<li>
<p>Перевірте <strong>менеджер пакунків</strong> вашого дистрибутива Linux</p>
</li>
<li>
<p><strong>APK для Android</strong> також доступні на <a href="https://github.com/deltachat/deltachat-android/releases">https://github.com/deltachat/deltachat-android/releases</a></p>
</li>
</ul>
<h3 id="як-фінансується-розробка-delta-chat">
File diff suppressed because it is too large Load Diff
Binary file not shown.
@@ -2,16 +2,14 @@ package com.b44t.messenger;
public class DcContext {
public final static int DC_PREF_DEFAULT_MDNS_ENABLED = 1;
public final static int DC_PREF_DEFAULT_TRIM_ENABLED = 0;
public final static int DC_PREF_DEFAULT_TRIM_LENGTH = 500;
public final static int DC_EVENT_INFO = 100;
public final static int DC_EVENT_WARNING = 300;
public final static int DC_EVENT_ERROR = 400;
public final static int DC_EVENT_ERROR_SELF_NOT_IN_GROUP = 410;
public final static int DC_EVENT_MSGS_CHANGED = 2000;
public final static int DC_EVENT_REACTIONS_CHANGED = 2001;
public final static int DC_EVENT_INCOMING_REACTION = 2002;
public final static int DC_EVENT_INCOMING_WEBXDC_NOTIFY = 2003;
public final static int DC_EVENT_INCOMING_MSG = 2005;
public final static int DC_EVENT_MSGS_NOTICED = 2008;
public final static int DC_EVENT_MSG_DELIVERED = 2010;
@@ -82,16 +80,13 @@ public class DcContext {
public final static int DC_MEDIA_QUALITY_BALANCED = 0;
public final static int DC_MEDIA_QUALITY_WORSE = 1;
public final static int DC_DECISION_START_CHAT = 0;
public final static int DC_DECISION_BLOCK = 1;
public final static int DC_DECISION_NOT_NOW = 2;
public final static int DC_CONNECTIVITY_NOT_CONNECTED = 1000;
public final static int DC_CONNECTIVITY_CONNECTING = 2000;
public final static int DC_CONNECTIVITY_WORKING = 3000;
public final static int DC_CONNECTIVITY_CONNECTED = 4000;
private static final String CONFIG_ACCOUNT_ENABLED = "ui.enabled";
private static final String CONFIG_MUTE_MENTIONS_IF_MUTED = "ui.mute_mentions_if_muted";
// when using DcAccounts, use DcAccounts.addAccount() instead
public DcContext(String osName, String dbfile) {
@@ -200,11 +195,10 @@ public class DcContext {
public native void deleteMsgs (int msg_ids[]);
public native void forwardMsgs (int msg_ids[], int chat_id);
public native boolean resendMsgs (int msg_ids[]);
public native int prepareMsg (int chat_id, DcMsg msg);
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, String descr);
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);
public native int initWebxdcIntegration(int chat_id);
@@ -232,22 +226,12 @@ public class DcContext {
}
}
public String getNameNAddr() {
String displayname = getConfig("displayname");
String addr = getConfig("addr");
String ret = "";
public boolean isMentionsEnabled() {
return getConfigInt(CONFIG_MUTE_MENTIONS_IF_MUTED) != 1;
}
if (!displayname.isEmpty() && !addr.isEmpty()) {
ret = String.format("%s (%s)", displayname, addr);
} else if (!addr.isEmpty()) {
ret = addr;
}
if (ret.isEmpty() || isConfigured() == 0) {
ret += " (not configured)";
}
return ret.trim();
public void setMentionsEnabled(boolean enabled) {
setConfigInt(CONFIG_MUTE_MENTIONS_IF_MUTED, enabled? 0 : 1);
}
public String getName() {
+10 -4
View File
@@ -148,6 +148,7 @@ public class DcMsg {
return new JSONObject();
}
}
public native String getWebxdcHref ();
public native boolean isForwarded ();
public native boolean isInfo ();
public native boolean isSetupMessage ();
@@ -155,25 +156,26 @@ public class DcMsg {
public native String getSetupCodeBegin ();
public native String getVideochatUrl ();
public native int getVideochatType ();
public native boolean isIncreation ();
public native void setText (String text);
public native void setSubject (String text);
public native void setHtml (String text);
public native void setFile (String file, String filemime);
public native void forceSticker ();
public native void setFileAndDeduplicate(String file, String name, String filemime);
public native void setDimension (int width, int height);
public native void setDuration (int duration);
public native void setLocation (float latitude, float longitude);
public native String getPOILocation ();
public void setQuote (DcMsg quote) { setQuoteCPtr(quote.msgCPtr); }
public native String getQuotedText ();
public native String getError ();
public native String getOverrideSenderName();
public native boolean isOutgoing();
public native int getSenderColor();
public String getSenderName(DcContact dcContact, boolean markOverride) {
public String getSenderName(DcContact dcContact) {
String overrideName = getOverrideSenderName();
if (overrideName != null) {
return (markOverride ? "~" : "") + overrideName;
return "~" + overrideName;
} else {
return dcContact.getDisplayName();
}
@@ -208,6 +210,10 @@ public class DcMsg {
return ids;
}
public boolean isOutgoing() {
return getFromId() == DcContact.DC_CONTACT_ID_SELF;
}
public String getDisplayBody() {
return getText();
}
@@ -79,23 +79,6 @@ public class Rpc {
}
}
public int addAccount() throws RpcException {
return gson.fromJson(getResult("add_account"), int.class);
}
public void startIO() throws RpcException {
getResult("start_io_for_all_accounts");
}
public void stopIO() throws RpcException {
getResult("stop_io_for_all_accounts");
}
public Map<String, String> getSystemInfo() throws RpcException {
TypeToken<Map<String, String>> mapType = new TypeToken<Map<String, String>>(){};
return gson.fromJson(getResult("get_system_info"), mapType.getType());
}
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());
@@ -27,7 +27,6 @@ import com.b44t.messenger.DcEvent;
import com.b44t.messenger.DcEventEmitter;
import com.b44t.messenger.rpc.Rpc;
import org.thoughtcrime.securesms.components.emoji.EmojiProvider;
import org.thoughtcrime.securesms.connect.AccountManager;
import org.thoughtcrime.securesms.connect.DcEventCenter;
import org.thoughtcrime.securesms.connect.DcHelper;
@@ -37,7 +36,6 @@ import org.thoughtcrime.securesms.connect.KeepAliveService;
import org.thoughtcrime.securesms.connect.NetworkStateReceiver;
import org.thoughtcrime.securesms.crypto.DatabaseSecret;
import org.thoughtcrime.securesms.crypto.DatabaseSecretProvider;
import org.thoughtcrime.securesms.crypto.PRNGFixes;
import org.thoughtcrime.securesms.geolocation.DcLocationManager;
import org.thoughtcrime.securesms.jobmanager.JobManager;
import org.thoughtcrime.securesms.notifications.FcmReceiveService;
@@ -107,11 +105,6 @@ public class ApplicationContext extends MultiDexApplication {
Log.i("DeltaChat", "++++++++++++++++++ ApplicationContext.onCreate() ++++++++++++++++++");
// The first call to `getInstance` takes about 100ms-300ms, so, do it on a background thread
Thread t = new Thread(() -> EmojiProvider.getInstance(this), "InitEmojiProviderThread");
t.setPriority(Thread.MIN_PRIORITY);
t.start();
System.loadLibrary("native-utils");
dcAccounts = new DcAccounts(new File(getFilesDir(), "accounts").getAbsolutePath());
@@ -131,9 +124,6 @@ public class ApplicationContext extends MultiDexApplication {
e.printStackTrace();
}
}
if ("deltafans@nine.testrun.org".equals(ac.getConfig("configured_addr")) && !ac.isCommunity()) {
ac.setCommunityMode(true);
}
}
if (allAccounts.length == 0) {
dcAccounts.addAccount();
@@ -209,7 +199,6 @@ public class ApplicationContext extends MultiDexApplication {
KeepAliveService.maybeStartSelf(this);
initializeRandomNumberFix();
initializeLogging();
initializeJobManager();
InChatSounds.getInstance(this);
@@ -240,11 +229,10 @@ public class ApplicationContext extends MultiDexApplication {
TimeUnit.MILLISECONDS)
.setConstraints(constraints)
.build();
try {
// in Android 4 this throws exception due to R8/shrinking
WorkManager.getInstance(this)
.enqueueUniquePeriodicWork("FetchWorker", ExistingPeriodicWorkPolicy.KEEP, fetchWorkRequest);
} catch (Throwable e) {}
WorkManager.getInstance(this).enqueueUniquePeriodicWork(
"FetchWorker",
ExistingPeriodicWorkPolicy.KEEP,
fetchWorkRequest);
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
if (Prefs.isPushEnabled(this)) {
@@ -258,10 +246,6 @@ public class ApplicationContext extends MultiDexApplication {
return jobManager;
}
private void initializeRandomNumberFix() {
PRNGFixes.apply();
}
private void initializeLogging() {
SignalProtocolLoggerProvider.setProvider(new AndroidSignalProtocolLogger());
}
@@ -156,10 +156,6 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarA
this.findPreference(PREFERENCE_CATEGORY_HELP)
.setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_HELP));
if (VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
tintIcons(getActivity());
}
DcHelper.getEventCenter(getActivity()).addObserver(DcContext.DC_EVENT_CONNECTIVITY_CHANGED, this);
}
@@ -33,9 +33,6 @@ public abstract class BaseActionBarActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
onPreCreate();
if (BaseActivity.isMenuWorkaroundRequired()) {
forceOverflowMenu();
}
super.onCreate(savedInstanceState);
}
@@ -46,20 +43,6 @@ public abstract class BaseActionBarActivity extends AppCompatActivity {
dynamicTheme.onResume(this);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return (keyCode == KeyEvent.KEYCODE_MENU && BaseActivity.isMenuWorkaroundRequired()) || super.onKeyDown(keyCode, event);
}
@Override
public boolean onKeyUp(int keyCode, @NonNull KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && BaseActivity.isMenuWorkaroundRequired()) {
openOptionsMenu();
return true;
}
return super.onKeyUp(keyCode, event);
}
private void initializeScreenshotSecurity() {
if (Prefs.isScreenSecurityEnabled(this)) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
@@ -1,28 +0,0 @@
package org.thoughtcrime.securesms;
import android.os.Build;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity;
import android.view.KeyEvent;
public abstract class BaseActivity extends FragmentActivity {
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return (keyCode == KeyEvent.KEYCODE_MENU && isMenuWorkaroundRequired()) || super.onKeyDown(keyCode, event);
}
@Override
public boolean onKeyUp(int keyCode, @NonNull KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && isMenuWorkaroundRequired()) {
openOptionsMenu();
return true;
}
return super.onKeyUp(keyCode, event);
}
public static boolean isMenuWorkaroundRequired() {
return VERSION.SDK_INT < VERSION_CODES.KITKAT && ("LGE".equalsIgnoreCase(Build.MANUFACTURER) || "E6710".equalsIgnoreCase(Build.DEVICE));
}
}
@@ -364,9 +364,7 @@ public abstract class BaseConversationListFragment extends Fragment implements A
mode.setTitle("1");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
requireActivity().getWindow().setStatusBarColor(getResources().getColor(R.color.action_mode_status_bar));
}
requireActivity().getWindow().setStatusBarColor(getResources().getColor(R.color.action_mode_status_bar));
return true;
}
@@ -395,11 +393,9 @@ public abstract class BaseConversationListFragment extends Fragment implements A
actionMode = null;
getListAdapter().initializeBatchMode(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
TypedArray color = requireActivity().getTheme().obtainStyledAttributes(new int[] {android.R.attr.statusBarColor});
requireActivity().getWindow().setStatusBarColor(color.getColor(0, Color.BLACK));
color.recycle();
}
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) {
@@ -136,9 +136,7 @@ public class ContactSelectionListFragment extends Fragment
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.contact_list, menu);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getActivity().getWindow().setStatusBarColor(getResources().getColor(R.color.action_mode_status_bar));
}
getActivity().getWindow().setStatusBarColor(getResources().getColor(R.color.action_mode_status_bar));
setCorrectMenuVisibility(menu);
actionMode.setTitle("1");
return true;
@@ -170,11 +168,9 @@ public class ContactSelectionListFragment extends Fragment
ContactSelectionListFragment.this.actionMode = null;
getContactSelectionListAdapter().resetActionModeSelection();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
TypedArray color = getActivity().getTheme().obtainStyledAttributes(new int[] {android.R.attr.statusBarColor});
getActivity().getWindow().setStatusBarColor(color.getColor(0, Color.BLACK));
color.recycle();
}
TypedArray color = getActivity().getTheme().obtainStyledAttributes(new int[]{android.R.attr.statusBarColor});
getActivity().getWindow().setStatusBarColor(color.getColor(0, Color.BLACK));
color.recycle();
}
};
@@ -45,6 +45,7 @@ import android.text.TextWatcher;
import android.util.Log;
import android.util.Pair;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@@ -53,6 +54,7 @@ import android.view.View.OnFocusChangeListener;
import android.view.View.OnKeyListener;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
@@ -89,8 +91,6 @@ import org.thoughtcrime.securesms.components.InputPanel;
import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout.OnKeyboardShownListener;
import org.thoughtcrime.securesms.components.ScaleStableImageView;
import org.thoughtcrime.securesms.components.SendButton;
import org.thoughtcrime.securesms.components.emoji.EmojiKeyboardProvider;
import org.thoughtcrime.securesms.components.emoji.EmojiProvider;
import org.thoughtcrime.securesms.components.emoji.MediaKeyboard;
import org.thoughtcrime.securesms.connect.AccountManager;
import org.thoughtcrime.securesms.connect.DcEventCenter;
@@ -119,7 +119,7 @@ import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
import org.thoughtcrime.securesms.util.concurrent.AssertedSuccessListener;
import org.thoughtcrime.securesms.util.guava.Optional;
import org.thoughtcrime.securesms.util.views.Stub;
import org.thoughtcrime.securesms.util.views.ProgressDialog;
import org.thoughtcrime.securesms.video.recode.VideoRecoder;
import org.thoughtcrime.securesms.videochat.VideochatUtil;
@@ -162,8 +162,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
private static final int GROUP_EDIT = 6;
private static final int TAKE_PHOTO = 7;
private static final int RECORD_VIDEO = 8;
private static final int PICK_LOCATION = 9; // TODO: i think, this can be deleted
private static final int SMS_DEFAULT = 11; // TODO: i think, this can be deleted
private static final int PICK_WEBXDC = 9;
private GlideRequests glideRequests;
protected ComposeText composeText;
@@ -176,11 +175,13 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
private View composePanel;
private ScaleStableImageView backgroundView;
private MessageRequestsBottomView messageRequestBottomView;
private ProgressDialog progressDialog;
private AttachmentTypeSelector attachmentTypeSelector;
private AttachmentManager attachmentManager;
private AudioRecorder audioRecorder;
private Stub<MediaKeyboard> emojiDrawerStub;
private FrameLayout emojiPickerContainer;
private MediaKeyboard emojiPicker;
protected HidingLinearLayout quickAttachmentToggle;
private InputPanel inputPanel;
@@ -320,10 +321,11 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
super.onConfigurationChanged(newConfig);
composeText.setTransport(sendButton.getSelectedTransport());
if (emojiDrawerStub.resolved() && container.getCurrentInput() == emojiDrawerStub.get()) {
if (emojiPicker != null && container.getCurrentInput() == emojiPicker) {
container.hideAttachedInput(true);
}
emojiPicker = null; // force reloading next time onEmojiToggle() is called
initializeBackground();
}
@@ -337,8 +339,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
public void onActivityResult(final int reqCode, int resultCode, Intent data) {
super.onActivityResult(reqCode, resultCode, data);
if ((data == null && reqCode != TAKE_PHOTO && reqCode != RECORD_VIDEO && reqCode != SMS_DEFAULT) ||
(resultCode != RESULT_OK && reqCode != SMS_DEFAULT))
if (resultCode != RESULT_OK || (data == null && reqCode != TAKE_PHOTO && reqCode != RECORD_VIDEO))
{
return;
}
@@ -362,7 +363,11 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
for (int i = 0; i < uriCount; i++) {
uriList.add(multipleUris.getItemAt(i).getUri());
}
askSendingFiles(uriList, () -> SendRelayedMessageUtil.sendMultipleMsgs(this, chatId, uriList, null));
askSendingFiles(uriList, () -> {
Util.runOnAnyBackgroundThread(() -> {
SendRelayedMessageUtil.sendMultipleMsgs(this, chatId, uriList, null);
});
});
}
}
}
@@ -374,6 +379,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
setMedia(data.getData(), docMediaType);
break;
case PICK_WEBXDC:
setMedia(data.getData(), MediaType.DOCUMENT);
break;
case PICK_CONTACT:
addAttachmentContactInfo(data.getIntExtra(AttachContactActivity.CONTACT_ID_EXTRA, 0));
break;
@@ -401,16 +410,9 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
}
break;
case PICK_LOCATION:
break;
case ScribbleActivity.SCRIBBLE_REQUEST_CODE:
setMedia(data.getData(), MediaType.IMAGE);
break;
case SMS_DEFAULT:
initializeSecurity(isSecureText, isDefaultSms);
break;
}
}
@@ -710,7 +712,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
DcMsg draft = dcContext.getDraft(chatId);
final String sharedText = RelayUtil.getSharedText(this);
if (draft == null) {
if (!draft.isOk()) {
if (TextUtils.isEmpty(sharedText)) {
composeText.setText("");
future.set(false);
@@ -737,8 +739,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
handleReplyMessage(quote);
}
String filename = draft.getFile();
if (filename.isEmpty() || !new File(filename).exists()) {
String file = draft.getFile();
if (file.isEmpty() || !new File(file).exists()) {
future.set(!text.isEmpty());
updateToggleButtonState();
return future;
@@ -758,26 +760,21 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
}
};
File file = new File(filename);
Uri uri = Uri.fromFile(file);
switch (draft.getType()) {
case DcMsg.DC_MSG_IMAGE:
setMedia(uri, MediaType.IMAGE).addListener(listener);
setMedia(draft, MediaType.IMAGE).addListener(listener);
break;
case DcMsg.DC_MSG_GIF:
setMedia(uri, MediaType.GIF).addListener(listener);
setMedia(draft, MediaType.GIF).addListener(listener);
break;
case DcMsg.DC_MSG_AUDIO:
setMedia(uri, MediaType.AUDIO).addListener(listener);
setMedia(draft, MediaType.AUDIO).addListener(listener);
break;
case DcMsg.DC_MSG_VIDEO:
setMedia(uri, MediaType.VIDEO).addListener(listener);
break;
case DcMsg.DC_MSG_WEBXDC:
setMedia(draft, MediaType.DOCUMENT).addListener(listener);
setMedia(draft, MediaType.VIDEO).addListener(listener);
break;
default:
setMedia(uri, MediaType.DOCUMENT).addListener(listener);
setMedia(draft, MediaType.DOCUMENT).addListener(listener);
break;
}
@@ -811,7 +808,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
sendButton = ViewUtil.findById(this, R.id.send_button);
attachButton = ViewUtil.findById(this, R.id.attach_button);
composeText = ViewUtil.findById(this, R.id.embedded_text_editor);
emojiDrawerStub = ViewUtil.findStubById(this, R.id.emoji_drawer_stub);
emojiPickerContainer = ViewUtil.findById(this, R.id.emoji_picker_container);
composePanel = ViewUtil.findById(this, R.id.bottom_panel);
container = ViewUtil.findById(this, R.id.layout_container);
quickAttachmentToggle = ViewUtil.findById(this, R.id.quick_attachment_toggle);
@@ -931,13 +928,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
case AttachmentTypeSelector.TAKE_PHOTO:
attachmentManager.capturePhoto(this, TAKE_PHOTO); break;
case AttachmentTypeSelector.RECORD_VIDEO:
if(VideoRecoder.canRecode()) {
attachmentManager.captureVideo(this, RECORD_VIDEO);
}
else {
Toast.makeText(this, "This device does not support video-compression (requires Android 4.4 KitKat)", Toast.LENGTH_LONG).show();
}
attachmentManager.captureVideo(this, RECORD_VIDEO);
break;
case AttachmentTypeSelector.ADD_WEBXDC:
AttachmentManager.selectWebxdc(this, PICK_WEBXDC); break;
}
}
@@ -986,14 +980,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
protected static final int ACTION_SEND_OUT = 1;
protected static final int ACTION_SAVE_DRAFT = 2;
private String getSelfReaction(int msgId) {
try {
final String [] selfReactions = rpc.getMsgReactions(dcContext.getAccountId(), msgId).getReactionsByContact().get(DcContact.DC_CONTACT_ID_SELF);
if (selfReactions != null && selfReactions.length > 0) return selfReactions[0];
} catch(Exception e) { e.printStackTrace(); }
return null;
}
protected ListenableFuture<Integer> processComposeControls(int action) {
return processComposeControls(action, composeText.getTextTrimmed(),
attachmentManager.isAttachmentPresent() ?
@@ -1042,7 +1028,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
msg = new DcMsg(dcContext, DcMsg.DC_MSG_FILE);
}
String path = attachment.getRealPath(this);
msg.setFile(path, null);
msg.setFileAndDeduplicate(path, attachment.getFileName(), null);
}
}
msg.setText(body);
@@ -1079,7 +1065,23 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
{
boolean doSend = true;
if (recompress==DcMsg.DC_MSG_VIDEO) {
Util.runOnMain(() -> {
progressDialog = ProgressDialog.show(
ConversationActivity.this,
"",
getString(R.string.one_moment),
true,
false
);
});
doSend = VideoRecoder.prepareVideo(ConversationActivity.this, dcChat.getId(), msg);
Util.runOnMain(() -> {
try {
progressDialog.dismiss();
} catch (final IllegalArgumentException e) {
// The activity is finishing/destroyed, do nothing.
}
});
}
if (doSend) {
@@ -1235,17 +1237,23 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
});
}
private void reloadEmojiPicker() {
emojiPickerContainer.removeAllViews();
emojiPicker = (MediaKeyboard) LayoutInflater.from(this).inflate(R.layout.conversation_activity_emojidrawer_stub, emojiPickerContainer, false);
emojiPickerContainer.addView(emojiPicker);
inputPanel.setMediaKeyboard(emojiPicker);
}
@Override
public void onEmojiToggle() {
if (!emojiDrawerStub.resolved()) {
initializeMediaKeyboardProviders(emojiDrawerStub.get(), false);
inputPanel.setMediaKeyboard(emojiDrawerStub.get());
if (emojiPicker == null) {
reloadEmojiPicker();
}
if (container.getCurrentInput() == emojiDrawerStub.get()) {
if (container.getCurrentInput() == emojiPicker) {
container.showSoftkey(composeText);
} else {
container.show(composeText, emojiDrawerStub.get());
container.show(composeText, emojiPicker);
}
}
@@ -1273,17 +1281,11 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
if (quote.isPresent()) {
msg.setQuote(quote.get().getQuotedMsg());
}
msg.setFile(path, null);
msg.setFileAndDeduplicate(path, null, null);
msg.forceSticker();
dcContext.sendMsg(chatId, msg);
}
private void initializeMediaKeyboardProviders(@NonNull MediaKeyboard mediaKeyboard, boolean stickersAvailable) {
boolean isSystemEmojiPreferred = Prefs.isSystemEmojiPreferred(this);
if (!isSystemEmojiPreferred) {
mediaKeyboard.setProviders(0, new EmojiKeyboardProvider(this, inputPanel));
}
}
// Listeners
private class AttachmentTypeListener implements AttachmentTypeSelector.AttachmentClickedListener {
@@ -24,9 +24,9 @@ import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
@@ -211,7 +211,7 @@ public class ConversationFragment extends MessageSelectorFragment
public void onResume() {
super.onResume();
dcContext.marknoticedChat((int) chatId);
Util.runOnBackground(() -> dcContext.marknoticedChat((int) chatId));
if (list.getAdapter() != null) {
list.getAdapter().notifyDataSetChanged();
}
@@ -442,7 +442,7 @@ public class ConversationFragment extends MessageSelectorFragment
if (msg.getFromId() != prevMsg.getFromId() && !singleMsg) {
DcContact contact = dcContext.getContact(msg.getFromId());
result.append(msg.getSenderName(contact, false)).append(":\n");
result.append(msg.getSenderName(contact)).append(":\n");
}
if (msg.getType() == DcMsg.DC_MSG_TEXT || (singleMsg && !msg.getText().isEmpty())) {
result.append(msg.getText());
@@ -704,7 +704,7 @@ public class ConversationFragment extends MessageSelectorFragment
index++;
}
}
dcContext.markseenMsgs(ids);
Util.runOnAnyBackgroundThread(() -> dcContext.markseenMsgs(ids));
}
@@ -810,7 +810,10 @@ public class ConversationFragment extends MessageSelectorFragment
DozeReminder.dozeReminderTapped(getContext());
}
else if(messageRecord.getInfoType() == DcMsg.DC_INFO_WEBXDC_INFO_MESSAGE) {
scrollMaybeSmoothToMsgId(messageRecord.getParent().getId());
WebxdcActivity.openWebxdcActivity(getContext(), messageRecord.getParent(), messageRecord.getWebxdcHref());
}
else if (!TextUtils.isEmpty(messageRecord.getPOILocation()) && messageRecord.getType() == DcMsg.DC_MSG_TEXT && !messageRecord.hasHtml()) {
WebxdcActivity.openMaps(getContext(), getListAdapter().getChat().getId(), "index.html#"+messageRecord.getPOILocation());
}
else {
String self_mail = dcContext.getConfig("configured_mail_user");
@@ -911,11 +914,9 @@ public class ConversationFragment extends MessageSelectorFragment
mode.setTitle("1");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getActivity().getWindow();
statusBarColor = window.getStatusBarColor();
window.setStatusBarColor(getResources().getColor(R.color.action_mode_status_bar));
}
Window window = getActivity().getWindow();
statusBarColor = window.getStatusBarColor();
window.setStatusBarColor(getResources().getColor(R.color.action_mode_status_bar));
setCorrectMenuVisibility(menu);
ConversationAdaptiveActionsToolbar.adjustMenuActions(menu, 10, requireActivity().getWindow().getDecorView().getMeasuredWidth());
@@ -932,9 +933,7 @@ public class ConversationFragment extends MessageSelectorFragment
((ConversationAdapter)list.getAdapter()).clearSelection();
list.getAdapter().notifyDataSetChanged();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getActivity().getWindow().setStatusBarColor(statusBarColor);
}
getActivity().getWindow().setStatusBarColor(statusBarColor);
actionMode = null;
hideAddReactionView();
@@ -22,12 +22,10 @@ import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.os.Build;
import android.text.Spannable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
@@ -56,7 +54,6 @@ import org.thoughtcrime.securesms.components.DocumentView;
import org.thoughtcrime.securesms.components.QuoteView;
import org.thoughtcrime.securesms.components.VcardView;
import org.thoughtcrime.securesms.components.WebxdcView;
import org.thoughtcrime.securesms.components.emoji.EmojiTextView;
import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.mms.AudioSlide;
import org.thoughtcrime.securesms.mms.DocumentSlide;
@@ -69,10 +66,10 @@ import org.thoughtcrime.securesms.mms.StickerSlide;
import org.thoughtcrime.securesms.mms.VcardSlide;
import org.thoughtcrime.securesms.reactions.ReactionsConversationView;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.Linkifier;
import org.thoughtcrime.securesms.util.LongClickMovementMethod;
import org.thoughtcrime.securesms.util.MarkdownUtil;
import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.Prefs;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
import org.thoughtcrime.securesms.util.views.Stub;
@@ -112,6 +109,7 @@ public class ConversationItem extends BaseConversationItem
protected ViewGroup contactPhotoHolder;
private ViewGroup container;
private Button msgActionButton;
private Button showFullButton;
private @NonNull Stub<ConversationItemThumbnail> mediaThumbnailStub;
private @NonNull Stub<AudioView> audioViewStub;
@@ -158,6 +156,7 @@ public class ConversationItem extends BaseConversationItem
this.container = findViewById(R.id.container);
this.replyView = findViewById(R.id.reply_icon);
this.msgActionButton = findViewById(R.id.msg_action_button);
this.showFullButton = findViewById(R.id.show_full_button);
setOnClickListener(new ClickListener(null));
@@ -385,7 +384,6 @@ public class ConversationItem extends BaseConversationItem
private void setBodyText(DcMsg messageRecord) {
bodyText.setClickable(false);
bodyText.setFocusable(false);
bodyText.setTextSize(TypedValue.COMPLEX_UNIT_SP, Prefs.getMessageBodyTextSize(context));
String text = messageRecord.getText();
@@ -399,7 +397,7 @@ public class ConversationItem extends BaseConversationItem
else {
Spannable spannable = (Spannable) MarkdownUtil.toMarkdown(context, text);
if (batchSelected.isEmpty()) {
spannable = EmojiTextView.linkify(spannable);
spannable = Linkifier.linkify(spannable);
}
bodyText.setText(spannable);
bodyText.setVisibility(View.VISIBLE);
@@ -407,6 +405,7 @@ public class ConversationItem extends BaseConversationItem
int downloadState = messageRecord.getDownloadState();
if (downloadState == DcMsg.DC_DOWNLOAD_AVAILABLE || downloadState == DcMsg.DC_DOWNLOAD_FAILURE || downloadState == DcMsg.DC_DOWNLOAD_IN_PROGRESS) {
showFullButton.setVisibility(View.GONE);
msgActionButton.setVisibility(View.VISIBLE);
if (downloadState==DcMsg.DC_DOWNLOAD_IN_PROGRESS) {
msgActionButton.setEnabled(false);
@@ -427,6 +426,7 @@ public class ConversationItem extends BaseConversationItem
}
});
} else if (messageRecord.getType() == DcMsg.DC_MSG_WEBXDC) {
showFullButton.setVisibility(View.GONE);
msgActionButton.setVisibility(View.VISIBLE);
msgActionButton.setEnabled(true);
msgActionButton.setText(webxdcViewStub.get().isCommunity()? R.string.join: R.string.start_app);
@@ -439,10 +439,11 @@ public class ConversationItem extends BaseConversationItem
});
}
else if (messageRecord.hasHtml()) {
msgActionButton.setVisibility(View.VISIBLE);
msgActionButton.setEnabled(true);
msgActionButton.setText(R.string.show_full_message);
msgActionButton.setOnClickListener(view -> {
msgActionButton.setVisibility(View.GONE);
showFullButton.setVisibility(View.VISIBLE);
showFullButton.setEnabled(true);
showFullButton.setText(R.string.show_full_message);
showFullButton.setOnClickListener(view -> {
if (eventListener != null && batchSelected.isEmpty()) {
eventListener.onShowFullClicked(messageRecord);
} else {
@@ -451,6 +452,7 @@ public class ConversationItem extends BaseConversationItem
});
} else {
msgActionButton.setVisibility(View.GONE);
showFullButton.setVisibility(View.GONE);
}
}
@@ -492,9 +494,7 @@ public class ConversationItem extends BaseConversationItem
audioViewStub.get().setAudio(new AudioSlide(context, messageRecord), duration);
audioViewStub.get().setOnClickListener(passthroughClickListener);
audioViewStub.get().setOnLongClickListener(passthroughClickListener);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
audioViewStub.get().setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
}
audioViewStub.get().setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
ViewUtil.updateLayoutParams(bodyText, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
ViewUtil.updateLayoutParams(groupSenderHolder, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
@@ -512,9 +512,7 @@ public class ConversationItem extends BaseConversationItem
documentViewStub.get().setDocument(new DocumentSlide(context, messageRecord));
documentViewStub.get().setDocumentClickListener(new ThumbnailClickListener());
documentViewStub.get().setOnLongClickListener(passthroughClickListener);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
documentViewStub.get().setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
}
documentViewStub.get().setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
ViewUtil.updateLayoutParams(bodyText, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
ViewUtil.updateLayoutParams(groupSenderHolder, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
@@ -531,9 +529,7 @@ public class ConversationItem extends BaseConversationItem
webxdcViewStub.get().setWebxdc(messageRecord, context.getString(R.string.webxdc_app));
webxdcViewStub.get().setWebxdcClickListener(new ThumbnailClickListener());
webxdcViewStub.get().setOnLongClickListener(passthroughClickListener);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
webxdcViewStub.get().setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
}
webxdcViewStub.get().setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
ViewUtil.updateLayoutParams(bodyText, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
ViewUtil.updateLayoutParams(groupSenderHolder, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
@@ -551,9 +547,7 @@ public class ConversationItem extends BaseConversationItem
vcardViewStub.get().setVcardClickListener(new ThumbnailClickListener());
vcardViewStub.get().setOnLongClickListener(passthroughClickListener);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
vcardViewStub.get().setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
}
vcardViewStub.get().setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
ViewUtil.updateLayoutParams(bodyText, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
ViewUtil.updateLayoutParams(groupSenderHolder, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
@@ -589,9 +583,7 @@ public class ConversationItem extends BaseConversationItem
mediaThumbnailStub.get().setOnLongClickListener(passthroughClickListener);
mediaThumbnailStub.get().setOnClickListener(passthroughClickListener);
mediaThumbnailStub.get().showShade(TextUtils.isEmpty(messageRecord.getText()));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
mediaThumbnailStub.get().setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
}
mediaThumbnailStub.get().setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
setThumbnailOutlineCorners(messageRecord, showSender);
@@ -614,9 +606,7 @@ public class ConversationItem extends BaseConversationItem
stickerStub.get().setThumbnailClickListener(new StickerClickListener());
stickerStub.get().setOnLongClickListener(passthroughClickListener);
stickerStub.get().setOnClickListener(passthroughClickListener);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
stickerStub.get().setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
}
stickerStub.get().setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
ViewUtil.updateLayoutParams(bodyText, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
ViewUtil.updateLayoutParams(groupSenderHolder, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
@@ -677,7 +667,7 @@ public class ConversationItem extends BaseConversationItem
contactPhoto.setVisibility(View.GONE);
} else {
int color = messageRecord.getSenderColor();
Recipient recipient = new Recipient(context, dcContact, messageRecord.getSenderName(dcContact, !dcContext.isCommunity()), color);
Recipient recipient = new Recipient(context, dcContact, messageRecord.getSenderName(dcContact), color);
contactPhoto.setAvatar(glideRequests, recipient, true);
contactPhoto.setVisibility(View.VISIBLE);
}
@@ -802,14 +792,14 @@ public class ConversationItem extends BaseConversationItem
if (messageRecord.isForwarded()) {
if (showSender && dcContact !=null) {
this.groupSender.setText(context.getString(R.string.forwarded_by, messageRecord.getSenderName(dcContact, false)));
this.groupSender.setText(context.getString(R.string.forwarded_by, messageRecord.getSenderName(dcContact)));
} else {
this.groupSender.setText(context.getString(R.string.forwarded_message));
}
this.groupSender.setTextColor(context.getResources().getColor(R.color.unknown_sender));
}
else if (showSender && dcContact !=null) {
this.groupSender.setText(messageRecord.getSenderName(dcContact, true));
this.groupSender.setText(messageRecord.getSenderName(dcContact));
int color = messageRecord.getSenderColor();
this.groupSender.setTextColor(Util.rgbToArgbColor(color!=0? color : dcContact.getColor()));
}
@@ -174,9 +174,7 @@ class ConversationItemSwipeCallback extends ItemTouchHelper.SimpleCallback {
vibrate(viewHolder.itemView.getContext());
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
recyclerView.cancelPendingInputEvents();
}
recyclerView.cancelPendingInputEvents();
}
private static void resetProgress(RecyclerView.ViewHolder viewHolder) {
@@ -199,11 +197,7 @@ class ConversationItemSwipeCallback extends ItemTouchHelper.SimpleCallback {
}
private static float getSignFromDirection(@NonNull View view) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
return view.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL ? -1f : 1f;
} else {
return 1f;
}
return view.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL ? -1f : 1f;
}
private static boolean sameSign(float dX, float sign) {
@@ -89,7 +89,6 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
public static final String CLEAR_NOTIFICATIONS = "clear_notifications";
public static final String ACCOUNT_ID_EXTRA = "account_id";
public static final String FROM_WELCOME = "from_welcome";
public static final String WARN_CANNOT_ENCRYPT = "warn_cannot_encrypt";
private ConversationListFragment conversationListFragment;
public TextView title;
@@ -113,7 +112,7 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
// it is not needed to keep all past update messages, however, when deleted, also the strings should be deleted.
try {
DcContext dcContext = DcHelper.getContext(this);
final String deviceMsgLabel = "update_1_46_0l_android";
final String deviceMsgLabel = "update_1_50_0_android";
if (!dcContext.wasDeviceMsgEverAdded(deviceMsgLabel)) {
DcMsg msg = null;
if (!getIntent().getBooleanExtra(FROM_WELCOME, false)) {
@@ -124,7 +123,7 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
// Util.copy(inputStream, new FileOutputStream(outputFile));
// msg.setFile(outputFile, "image/jpeg");
msg.setText(getString(R.string.update_1_46_android, "https://raw.githubusercontent.com/ArcaneChat/android/refs/heads/main/CHANGELOG.md"));
msg.setText(getString(R.string.update_1_50_android, "https://raw.githubusercontent.com/ArcaneChat/android/refs/heads/main/CHANGELOG.md"));
}
dcContext.addDeviceMsg(deviceMsgLabel, msg);
@@ -257,6 +256,10 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
@Override
protected void onNewIntent(Intent intent) {
if (isFinishing()) {
Log.w(TAG, "Activity is finishing, aborting onNewIntent()");
return;
}
super.onNewIntent(intent);
setIntent(intent);
refresh();
@@ -274,11 +277,6 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
AccountManager.getInstance().switchAccountAndStartActivity(this, accountId);
}
String warnAddr = getIntent().getStringExtra(WARN_CANNOT_ENCRYPT);
if (!TextUtils.isEmpty(warnAddr)) {
DcHelper.showEncryptionRequiredDialog(this, warnAddr);
}
refreshAvatar();
refreshUnreadIndicator();
refreshTitle();
@@ -458,11 +456,8 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
case R.id.menu_all_media:
startActivity(new Intent(this, ProfileActivity.class));
return true;
case R.id.menu_webxdc_apps_store:
handleShowBot("juegos@buzon.uy", "OPENPGP4FPR:d3d403a734be71fe9293a00311fef80dbe5dbc89#a=juegos%40buzon.uy&n=&i=WQZY-8FODS3&s=ZQBkaclFzao");
return true;
case R.id.menu_public_bots:
handleShowBot("puente@buzon.uy", "OPENPGP4FPR:4B41E5AFAF78A0C71DB56138D5BEFED00A45F97A#a=puente%40buzon.uy&n=Public%20Bots&i=ZC_oaJtuvJP&s=5SE96rRovsK");
handleShowBot("botsindex@arcanechat.me", "https://i.delta.chat/#67889B0362BEDBFEE05ACD92C1D737FA632A9582&a=botsindex%40arcanechat.me&n=Public%20Bots&i=336MTEz38EH-RJxM9OKWygYK&s=TpVVGK6C4KrJmRG0bwHLalXt");
return true;
}
@@ -564,7 +559,7 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
private void shareInvite() {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
String inviteURL = Util.QrDataToInviteURL(DcHelper.getContext(this).getSecurejoinQr(0));
String inviteURL = DcHelper.getContext(this).getSecurejoinQr(0);
intent.putExtra(Intent.EXTRA_TEXT, getString(R.string.invite_friends_text, inviteURL));
startActivity(Intent.createChooser(intent, getString(R.string.chat_share_with_title)));
}
@@ -29,7 +29,6 @@ public class ConversationListItemInboxZero extends LinearLayout implements Binda
super(context, attrs, defStyleAttr);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public ConversationListItemInboxZero(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@@ -5,7 +5,6 @@ import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
@@ -31,12 +30,9 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.google.android.material.textfield.TextInputLayout;
import com.soundcloud.android.crop.Crop;
import org.thoughtcrime.securesms.components.AvatarSelector;
import org.thoughtcrime.securesms.components.InputAwareLayout;
import org.thoughtcrime.securesms.components.emoji.EmojiKeyboardProvider;
import org.thoughtcrime.securesms.components.emoji.MediaKeyboard;
import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.contacts.avatars.ResourceContactPhoto;
import org.thoughtcrime.securesms.mms.AttachmentManager;
@@ -54,7 +50,7 @@ import java.security.SecureRandom;
@SuppressLint("StaticFieldLeak")
public class CreateProfileActivity extends BaseActionBarActivity implements EmojiKeyboardProvider.EmojiEventListener {
public class CreateProfileActivity extends BaseActionBarActivity {
private static final String TAG = CreateProfileActivity.class.getSimpleName();
@@ -66,7 +62,6 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Emoj
private ImageView avatar;
private EditText name;
private EditText overridenName;
private MediaKeyboard emojiDrawer;
private EditText statusView;
private boolean fromWelcome;
@@ -91,7 +86,6 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Emoj
attachmentManager = new AttachmentManager(this, () -> {});
avatarChanged = false;
initializeResources();
initializeEmojiInput();
initializeProfileName();
initializeProfileAvatar();
initializeStatusText();
@@ -130,15 +124,6 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Emoj
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (container.getCurrentInput() == emojiDrawer) {
container.hideAttachedInput(true);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
Permissions.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
@@ -161,10 +146,6 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Emoj
case ScribbleActivity.SCRIBBLE_REQUEST_CODE:
setAvatarView(data.getData());
break;
case Crop.REQUEST_CROP:
setAvatarView(Crop.getOutput(data));
break;
}
}
@@ -206,7 +187,6 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Emoj
this.avatar = ViewUtil.findById(this, R.id.avatar);
this.name = ViewUtil.findById(this, R.id.name_text);
this.overridenName = ViewUtil.findById(this, R.id.overriden_name);
this.emojiDrawer = ViewUtil.findById(this, R.id.emoji_drawer);
this.container = ViewUtil.findById(this, R.id.container);
this.statusView = ViewUtil.findById(this, R.id.status_text);
@@ -261,33 +241,6 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Emoj
);
}
@Override
public void onEmojiSelected(String emoji) {
final int start = name.getSelectionStart();
final int end = name.getSelectionEnd();
name.getText().replace(Math.min(start, end), Math.max(start, end), emoji);
name.setSelection(start + emoji.length());
}
@Override
public void onKeyEvent(KeyEvent keyEvent) {
name.dispatchKeyEvent(keyEvent);
}
private void initializeMediaKeyboardProviders(@NonNull MediaKeyboard mediaKeyboard) {
boolean isSystemEmojiPreferred = Prefs.isSystemEmojiPreferred(this);
if (!isSystemEmojiPreferred) {
mediaKeyboard.setProviders(0, new EmojiKeyboardProvider(this, this));
}
}
private void initializeEmojiInput() {
initializeMediaKeyboardProviders(emojiDrawer);
this.name.setOnClickListener(v -> container.showSoftkey(name));
}
private void initializeStatusText() {
String status = DcHelper.get(this, DcHelper.CONFIG_SELF_STATUS);
statusView.setText(status);
@@ -17,7 +17,6 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.loader.app.LoaderManager;
import com.b44t.messenger.DcChat;
@@ -26,7 +25,6 @@ import com.b44t.messenger.DcContext;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.soundcloud.android.crop.Crop;
import org.thoughtcrime.securesms.components.AvatarSelector;
import org.thoughtcrime.securesms.connect.DcHelper;
@@ -221,22 +219,7 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
updateGroup(groupName);
} else {
verified = !broadcast && allMembersVerified();
if (verified && getAdapter().getContacts().size() == 1) {
new AlertDialog.Builder(this)
.setMessage(R.string.create_verified_group_ask)
.setNeutralButton(R.string.learn_more, (d, w) -> DcHelper.openHelp(this, "#e2eeguarantee"))
.setPositiveButton(R.string.yes, (d, w) -> {
createGroup(groupName);
})
.setNegativeButton(R.string.no, (d, w) -> {
verified = false;
createGroup(groupName);
})
.setCancelable(true)
.show();
} else {
createGroup(groupName);
}
createGroup(groupName);
}
return true;
@@ -360,10 +343,6 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
case ScribbleActivity.SCRIBBLE_REQUEST_CODE:
setAvatarView(data.getData());
break;
case Crop.REQUEST_CROP:
setAvatarView(Crop.getOutput(data));
break;
}
}
@@ -41,7 +41,6 @@ import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
import com.soundcloud.android.crop.Crop;
import org.thoughtcrime.securesms.components.AvatarSelector;
import org.thoughtcrime.securesms.connect.AccountManager;
@@ -56,6 +55,7 @@ import org.thoughtcrime.securesms.profiles.ProfileMediaConstraints;
import org.thoughtcrime.securesms.proxy.ProxySettingsActivity;
import org.thoughtcrime.securesms.qr.RegistrationQrActivity;
import org.thoughtcrime.securesms.scribbles.ScribbleActivity;
import org.thoughtcrime.securesms.util.IntentUtils;
import org.thoughtcrime.securesms.util.Prefs;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.views.ProgressDialog;
@@ -71,7 +71,7 @@ public class InstantOnboardingActivity extends BaseActionBarActivity implements
private static final String DCACCOUNT = "dcaccount";
private static final String DCLOGIN = "dclogin";
private static final String INSTANCES_URL = "https://delta.chat/chatmail";
private static final String DEFAULT_CHATMAIL_HOST = "nine.testrun.org";
private static final String DEFAULT_CHATMAIL_HOST = "arcanechat.me";
public static final String QR_ACCOUNT_EXTRA = "qr_account_extra";
public static final String FROM_WELCOME = "from_welcome";
@@ -191,10 +191,6 @@ public class InstantOnboardingActivity extends BaseActionBarActivity implements
setAvatarView(data.getData());
break;
case Crop.REQUEST_CROP:
setAvatarView(Crop.getOutput(data));
break;
case IntentIntegrator.REQUEST_CODE:
String qrRaw = data.getStringExtra(RegistrationQrActivity.QRDATA_EXTRA);
if (qrRaw == null) {
@@ -246,16 +242,22 @@ public class InstantOnboardingActivity extends BaseActionBarActivity implements
protected void onPause() {
super.onPause();
final String displayName = name.getText().toString();
DcHelper.set(this, DcHelper.CONFIG_DISPLAY_NAME, TextUtils.isEmpty(displayName)? null : displayName);
// Save display name and avatar in the unconfigured profile.
// If the currently selected profile is configured, then this means that rollbackAccountCreation()
// was called (see handleOnBackPressed() above), i.e. the newly created profile was removed already
// and we can't save the display name & avatar.
if (DcHelper.getContext(this).isConfigured() == 0) {
final String displayName = name.getText().toString();
DcHelper.set(this, DcHelper.CONFIG_DISPLAY_NAME, TextUtils.isEmpty(displayName) ? null : displayName);
if (avatarChanged) {
try {
AvatarHelper.setSelfAvatar(InstantOnboardingActivity.this, avatarBmp);
Prefs.setProfileAvatarId(InstantOnboardingActivity.this, new SecureRandom().nextInt());
avatarChanged = false;
} catch (IOException e) {
Log.e(TAG, "Failed to save avatar", e);
if (avatarChanged) {
try {
AvatarHelper.setSelfAvatar(InstantOnboardingActivity.this, avatarBmp);
Prefs.setProfileAvatarId(InstantOnboardingActivity.this, new SecureRandom().nextInt());
avatarChanged = false;
} catch (IOException e) {
Log.e(TAG, "Failed to save avatar", e);
}
}
}
}
@@ -327,14 +329,14 @@ public class InstantOnboardingActivity extends BaseActionBarActivity implements
privacyPolicyBtn.setOnClickListener(view -> {
if (!isDcLogin) {
WebViewActivity.openUrlInBrowser(this, "https://" + providerHost + "/privacy.html");
IntentUtils.showInBrowser(this, "https://" + providerHost + "/privacy.html");
}
});
signUpBtn.setOnClickListener(view -> createProfile());
findViewById(R.id.use_other_server).setOnClickListener((v) -> {
WebViewActivity.openUrlInBrowser(this, INSTANCES_URL);
IntentUtils.showInBrowser(this, INSTANCES_URL);
});
findViewById(R.id.login_button).setOnClickListener((v) -> {
startRegistrationActivity();
@@ -62,16 +62,16 @@ public class LocalHelpActivity extends WebViewActivity
webView.scrollTo(0, 0);
return true;
case R.id.learn_more:
openOnlineUrl("https://delta.chat");
openOnlineUrl("https://arcanechat.me");
return true;
case R.id.privacy_policy:
openOnlineUrl("https://delta.chat/gdpr");
openOnlineUrl("https://arcanechat.me/privacy.html");
return true;
case R.id.contribute:
openOnlineUrl("https://github.com/deltachat/deltachat-android");
openOnlineUrl("https://arcanechat.me/#contribute");
return true;
case R.id.report_issue:
openOnlineUrl("https://github.com/deltachat/deltachat-android/issues");
openOnlineUrl("https://github.com/ArcaneChat/android/issues");
return true;
}
return false;
@@ -197,12 +197,11 @@ public class LogViewFragment extends Fragment {
asMegs(info.maxMemory()));
}
@TargetApi(VERSION_CODES.KITKAT)
public static String getMemoryClass(Context context) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
String lowMem = "";
if (VERSION.SDK_INT >= VERSION_CODES.KITKAT && activityManager.isLowRamDevice()) {
if (activityManager.isLowRamDevice()) {
lowMem = ", low-mem device";
}
return activityManager.getMemoryClass() + lowMem;
@@ -252,10 +251,8 @@ public class LogViewFragment extends Fragment {
Locale locale = Util.getLocale();
builder.append("lang=").append(locale.toString()).append("\n");
if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1) {
boolean isRtl = Util.getLayoutDirection(context) == View.LAYOUT_DIRECTION_RTL;
builder.append("rtl=").append(isRtl).append("\n");
}
boolean isRtl = Util.getLayoutDirection(context) == View.LAYOUT_DIRECTION_RTL;
builder.append("rtl=").append(isRtl).append("\n");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
boolean notifPermGranted = PermissionChecker.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) == PermissionChecker.PERMISSION_GRANTED;
@@ -207,7 +207,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity
messageRecord = null;
long date = getIntent().getLongExtra(DATE_EXTRA, 0);
long size = getIntent().getLongExtra(SIZE_EXTRA, 0);
initialMedia = new MediaItem(null, getIntent().getData(), getIntent().getType(),
initialMedia = new MediaItem(null, getIntent().getData(), null, getIntent().getType(),
DcMsg.DC_MSG_NO_ID, date, size, false);
if (address != null) {
@@ -218,7 +218,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity
} else {
messageRecord = dcContext.getMsg(msgId);
initialMedia = new MediaItem(Recipient.fromChat(context, msgId), Uri.fromFile(messageRecord.getFileAsFile()),
messageRecord.getFilemime(), messageRecord.getId(), messageRecord.getDateReceived(),
messageRecord.getFilename(), messageRecord.getFilemime(), messageRecord.getId(), messageRecord.getDateReceived(),
messageRecord.getFilebytes(), messageRecord.isOutgoing());
conversationRecipient = Recipient.fromChat(context, msgId);
}
@@ -232,12 +232,11 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity
// if you search for the place where the media are loaded, go to 'onCreateLoader'.
Log.w(TAG, "Loading Part URI: " + initialMedia);
if (messageRecord != null) {
getSupportLoaderManager().restartLoader(0, null, this);
} else {
mediaPager.setAdapter(new SingleItemPagerAdapter(this, GlideApp.with(this),
getWindow(), initialMedia.uri, initialMedia.type, initialMedia.size));
getWindow(), initialMedia.uri, initialMedia.name, initialMedia.type, initialMedia.size));
}
}
@@ -313,7 +312,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity
private void performSavetoDisk(@NonNull MediaItem mediaItem) {
SaveAttachmentTask saveTask = new SaveAttachmentTask(MediaPreviewActivity.this);
long saveDate = (mediaItem.date > 0) ? mediaItem.date : System.currentTimeMillis();
saveTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new Attachment(mediaItem.uri, mediaItem.type, saveDate, null));
saveTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new Attachment(mediaItem.uri, mediaItem.type, saveDate, mediaItem.name));
}
private void showInChat() {
@@ -473,9 +472,12 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity
MediaItemAdapter adapter = (MediaItemAdapter)mediaPager.getAdapter();
if (adapter != null) {
MediaItem item = adapter.getMediaItemFor(position);
if (item.recipient != null) item.recipient.removeListener(MediaPreviewActivity.this);
try {
MediaItem item = adapter.getMediaItemFor(position);
if (item.recipient != null) item.recipient.removeListener(MediaPreviewActivity.this);
} catch (IllegalArgumentException e) {
Log.w(TAG, "Ignoring invalid position index");
}
adapter.pause(position);
}
}
@@ -486,18 +488,20 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity
private final GlideRequests glideRequests;
private final Window window;
private final Uri uri;
private final String name;
private final String mediaType;
private final long size;
private final LayoutInflater inflater;
SingleItemPagerAdapter(@NonNull Context context, @NonNull GlideRequests glideRequests,
@NonNull Window window, @NonNull Uri uri, @NonNull String mediaType,
@NonNull Window window, @NonNull Uri uri, @Nullable String name, @NonNull String mediaType,
long size)
{
this.glideRequests = glideRequests;
this.window = window;
this.uri = uri;
this.name = name;
this.mediaType = mediaType;
this.size = size;
this.inflater = LayoutInflater.from(context);
@@ -519,7 +523,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity
MediaView mediaView = itemView.findViewById(R.id.media_view);
try {
mediaView.set(glideRequests, window, uri, mediaType, size, true);
mediaView.set(glideRequests, window, uri, name, mediaType, size, true);
} catch (IOException e) {
Log.w(TAG, e);
}
@@ -539,7 +543,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity
@Override
public MediaItem getMediaItemFor(int position) {
return new MediaItem(null, uri, mediaType, DcMsg.DC_MSG_NO_ID, -1, -1, true);
return new MediaItem(null, uri, name, mediaType, DcMsg.DC_MSG_NO_ID, -1, -1, true);
}
@Override
@@ -604,7 +608,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity
try {
//noinspection ConstantConditions
mediaView.set(glideRequests, window, Uri.fromFile(msg.getFileAsFile()),
mediaView.set(glideRequests, window, Uri.fromFile(msg.getFileAsFile()), msg.getFilename(),
msg.getFilemime(), msg.getFilebytes(), autoplay);
} catch (IOException e) {
Log.w(TAG, e);
@@ -633,6 +637,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity
return new MediaItem(Recipient.fromChat(context, msg.getId()),
Uri.fromFile(msg.getFileAsFile()),
msg.getFilename(),
msg.getFilemime(),
msg.getId(),
msg.getDateReceived(),
@@ -655,6 +660,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity
private static class MediaItem {
private final @Nullable Recipient recipient;
private final @NonNull Uri uri;
private final @Nullable String name;
private final @NonNull String type;
private final int msgId;
private final long date;
@@ -663,6 +669,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity
private MediaItem(@Nullable Recipient recipient,
@NonNull Uri uri,
@Nullable String name,
@NonNull String type,
int msgId,
long date,
@@ -671,6 +678,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity
{
this.recipient = recipient;
this.uri = uri;
this.name = name;
this.type = type;
this.msgId = msgId;
this.date = date;
@@ -111,8 +111,6 @@ public class NewConversationActivity extends ContactSelectionActivity {
int contactId = dcContext.lookupContactIdByAddr(addr);
if (contactId!=0 && dcContext.getChatIdByContactId(contactId)!=0) {
openConversation(dcContext.getChatIdByContactId(contactId));
} else if (contactId == 0 && dcContext.isChatmail()) {
DcHelper.showEncryptionRequiredDialog(this, addr);
} else {
String nameNAddr = contactId == 0 ? addr : dcContext.getContact(contactId).getNameNAddr();
new AlertDialog.Builder(this)
@@ -122,7 +122,13 @@ public class ProfileDocumentsFragment
noMedia.setVisibility(recyclerView.getAdapter().getItemCount() > 0 ? View.GONE : View.VISIBLE);
if (chatId == DC_CHAT_NO_CHAT) {
noMedia.setText(R.string.tab_all_media_empty_hint);
if (showWebxdc) {
noMedia.setText(R.string.all_apps_empty_hint);
} else if (!showAudio){
noMedia.setText(R.string.all_files_empty_hint);
} else {
noMedia.setText(R.string.tab_all_media_empty_hint);
}
} else if (showAudio) {
noMedia.setText(R.string.tab_audio_empty_hint);
} else if (showWebxdc) {
@@ -229,11 +235,9 @@ public class ProfileDocumentsFragment
mode.getMenuInflater().inflate(R.menu.profile_context, menu);
mode.setTitle("1");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getActivity().getWindow();
originalStatusBarColor = window.getStatusBarColor();
window.setStatusBarColor(getResources().getColor(R.color.action_mode_status_bar));
}
Window window = getActivity().getWindow();
originalStatusBarColor = window.getStatusBarColor();
window.setStatusBarColor(getResources().getColor(R.color.action_mode_status_bar));
setCorrectMenuVisibility(menu);
return true;
}
@@ -283,9 +287,7 @@ public class ProfileDocumentsFragment
actionMode = null;
getListAdapter().clearSelection();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getActivity().getWindow().setStatusBarColor(originalStatusBarColor);
}
getActivity().getWindow().setStatusBarColor(originalStatusBarColor);
}
}
}
@@ -219,11 +219,9 @@ public class ProfileGalleryFragment
mode.getMenuInflater().inflate(R.menu.profile_context, menu);
mode.setTitle("1");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getActivity().getWindow();
originalStatusBarColor = window.getStatusBarColor();
window.setStatusBarColor(getResources().getColor(R.color.action_mode_status_bar));
}
Window window = getActivity().getWindow();
originalStatusBarColor = window.getStatusBarColor();
window.setStatusBarColor(getResources().getColor(R.color.action_mode_status_bar));
setCorrectMenuVisibility(menu);
return true;
}
@@ -269,9 +267,7 @@ public class ProfileGalleryFragment
actionMode = null;
getListAdapter().clearSelection();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getActivity().getWindow().setStatusBarColor(originalStatusBarColor);
}
getActivity().getWindow().setStatusBarColor(originalStatusBarColor);
}
}
}
@@ -268,11 +268,9 @@ public class ProfileSettingsFragment extends Fragment
menu.findItem(R.id.menu_select_all).setVisible(false);
mode.setTitle("1");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getActivity().getWindow();
originalStatusBarColor = window.getStatusBarColor();
window.setStatusBarColor(getResources().getColor(R.color.action_mode_status_bar));
}
Window window = getActivity().getWindow();
originalStatusBarColor = window.getStatusBarColor();
window.setStatusBarColor(getResources().getColor(R.color.action_mode_status_bar));
return true;
}
@@ -314,9 +312,7 @@ public class ProfileSettingsFragment extends Fragment
public void onDestroyActionMode(ActionMode mode) {
actionMode = null;
adapter.clearSelection();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getActivity().getWindow().setStatusBarColor(originalStatusBarColor);
}
getActivity().getWindow().setStatusBarColor(originalStatusBarColor);
}
}
@@ -6,12 +6,14 @@ import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
import org.thoughtcrime.securesms.components.emoji.EmojiTextView;
import androidx.appcompat.widget.AppCompatTextView;
import org.thoughtcrime.securesms.util.Linkifier;
import org.thoughtcrime.securesms.util.LongClickMovementMethod;
public class ProfileStatusItem extends LinearLayout {
private EmojiTextView statusTextView;
private AppCompatTextView statusTextView;
private final PassthroughClickListener passthroughClickListener = new PassthroughClickListener();
public ProfileStatusItem(Context context) {
@@ -32,7 +34,7 @@ public class ProfileStatusItem extends LinearLayout {
}
public void set(String status) {
statusTextView.setText(EmojiTextView.linkify(new SpannableString(status)));
statusTextView.setText(Linkifier.linkify(new SpannableString(status)));
}
private class PassthroughClickListener implements View.OnLongClickListener, View.OnClickListener {
@@ -16,7 +16,6 @@ import static org.thoughtcrime.securesms.connect.DcHelper.CONFIG_PROXY_ENABLED;
import static org.thoughtcrime.securesms.connect.DcHelper.getContext;
import static org.thoughtcrime.securesms.service.IPCAddAccountsService.ACCOUNT_DATA;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
@@ -31,7 +30,6 @@ import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
@@ -59,6 +57,7 @@ import org.thoughtcrime.securesms.proxy.ProxySettingsActivity;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.IntentUtils;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
import org.thoughtcrime.securesms.util.views.ProgressDialog;
import java.lang.ref.WeakReference;
@@ -185,7 +184,7 @@ public class RegistrationActivity extends BaseActionBarActivity implements DcEve
expandAdvanced = expandAdvanced || !TextUtils.isEmpty(strVal);
intVal = DcHelper.getInt(this, CONFIG_MAIL_SECURITY);
imapSecurity.setSelection(intVal);
imapSecurity.setSelection(ViewUtil.checkBounds(intVal, imapSecurity));
expandAdvanced = expandAdvanced || intVal != 0;
TextInputEditText smtpLoginInput = findViewById(R.id.smtp_login_text);
@@ -207,7 +206,7 @@ public class RegistrationActivity extends BaseActionBarActivity implements DcEve
expandAdvanced = expandAdvanced || !TextUtils.isEmpty(strVal);
intVal = DcHelper.getInt(this, CONFIG_SEND_SECURITY);
smtpSecurity.setSelection(intVal);
smtpSecurity.setSelection(ViewUtil.checkBounds(intVal, smtpSecurity));
expandAdvanced = expandAdvanced || intVal != 0;
int serverFlags = DcHelper.getInt(this, CONFIG_SERVER_FLAGS);
@@ -222,12 +221,15 @@ public class RegistrationActivity extends BaseActionBarActivity implements DcEve
}
// /remove gmail oauth2
}
authMethod.setSelection(sel);
authMethod.setSelection(ViewUtil.checkBounds(sel, authMethod));
expandAdvanced = expandAdvanced || sel != 0;
int certCheckFlags = DcHelper.getInt(this, "imap_certificate_checks");
certCheck.setSelection(certCheckFlags);
expandAdvanced = expandAdvanced || certCheckFlags != 0;
int imapCertificateChecks = DcHelper.getInt(this, "imap_certificate_checks");
if (imapCertificateChecks == 3) {
imapCertificateChecks = 2; // 3 is a deprecated alias for 2
}
certCheck.setSelection(ViewUtil.checkBounds(imapCertificateChecks, certCheck));
expandAdvanced = expandAdvanced || imapCertificateChecks != 0;
} else if (getIntent() != null && getIntent().getBundleExtra(ACCOUNT_DATA) != null) {
// Companion app might have sent account data
Bundle b = getIntent().getBundleExtra(ACCOUNT_DATA);
@@ -435,7 +437,7 @@ public class RegistrationActivity extends BaseActionBarActivity implements DcEve
.setPositiveButton(R.string.perm_continue, (dialog, which)-> {
// pass control to browser, we'll be back in business at (**)
activity.oauth2Requested = System.currentTimeMillis();
IntentUtils.showBrowserIntent(activity, oauth2url);
IntentUtils.showInBrowser(activity, oauth2url);
oauth2started.set(true);
})
.setCancelable(false)
@@ -490,11 +492,7 @@ public class RegistrationActivity extends BaseActionBarActivity implements DcEve
if (provider!=null) {
String url = provider.getOverviewPage();
if(!url.isEmpty()) {
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
} catch (ActivityNotFoundException e) {
Toast.makeText(this, R.string.no_browser_installed, Toast.LENGTH_LONG).show();
}
IntentUtils.showInBrowser(this, url);
} else {
// this should normally not happen
Toast.makeText(this, "ErrProviderWithoutUrl", Toast.LENGTH_LONG).show();
@@ -58,6 +58,7 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity implement
{
private static final String TAG = ShareActivity.class.getSimpleName();
public static final String EXTRA_ACC_ID = "acc_id";
public static final String EXTRA_CHAT_ID = "chat_id";
public static final String EXTRA_MSG_TYPE = "msg_type";
public static final String EXTRA_MSG_SUBJECT = "msg_subject";
@@ -213,14 +214,10 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity implement
}
private void handleResolvedMedia(Intent intent) {
int accId = intent.getIntExtra(EXTRA_ACC_ID, -1);
int chatId = intent.getIntExtra(EXTRA_CHAT_ID, -1);
String msgType = intent.getStringExtra(EXTRA_MSG_TYPE);
String shortcutId = intent.getStringExtra(ShortcutManagerCompat.EXTRA_SHORTCUT_ID);
if (chatId == -1 && shortcutId != null) {
chatId = Integer.parseInt(shortcutId);
}
String[] extraEmail = getIntent().getStringArrayExtra(Intent.EXTRA_EMAIL);
/*
usually, external app will try to start "e-mail sharing" intent, providing it:
@@ -259,28 +256,21 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity implement
}
*/
String addr = null;
if(chatId == -1 && extraEmail != null && extraEmail.length > 0) {
addr = extraEmail[0];
final String addr = extraEmail[0];
int contactId = dcContext.lookupContactIdByAddr(addr);
if(contactId != 0 || !dcContext.isChatmail()) {
if(contactId == 0) {
contactId = dcContext.createContact(null, addr);
}
chatId = dcContext.createChatByContactId(contactId);
addr = null;
if(contactId == 0) {
contactId = dcContext.createContact(null, addr);
}
chatId = dcContext.createChatByContactId(contactId);
}
Intent composeIntent;
if (addr != null) {
composeIntent = new Intent(this, ConversationListActivity.class);
composeIntent.putExtra(ConversationListActivity.WARN_CANNOT_ENCRYPT, addr);
startActivity(composeIntent);
} else if (chatId != -1) {
if (accId != -1 && chatId != -1) {
composeIntent = getBaseShareIntent(ConversationActivity.class);
composeIntent.putExtra(ConversationActivity.CHAT_ID_EXTRA, chatId);
composeIntent.putExtra(ConversationActivity.ACCOUNT_ID_EXTRA, accId);
RelayUtil.setSharedType(composeIntent, msgType);
RelayUtil.setSharedUris(composeIntent, resolvedExtras);
startActivity(composeIntent);
@@ -26,6 +26,7 @@ import androidx.webkit.ProxyController;
import androidx.webkit.ProxyConfig;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.IntentUtils;
public class WebViewActivity extends PassphraseRequiredActionBarActivity
implements SearchView.OnQueryTextListener,
@@ -278,16 +279,8 @@ public class WebViewActivity extends PassphraseRequiredActionBarActivity
// onBackPressed() can be overwritten by derived classes as needed.
// the default behavior (close the activity) is just fine eg. for Webxdc, Connectivity, HTML-mails
public static void openUrlInBrowser(Context context, String url) {
try {
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
} catch (ActivityNotFoundException e) {
Toast.makeText(context, R.string.no_browser_installed, Toast.LENGTH_LONG).show();
}
}
protected boolean openOnlineUrl(String url) {
openUrlInBrowser(this, url);
IntentUtils.showInBrowser(this, url);
// returning `true` causes the WebView to abort loading
return true;
}
@@ -9,7 +9,6 @@ import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Base64;
@@ -40,11 +39,13 @@ 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;
import org.thoughtcrime.securesms.connect.AccountManager;
import org.thoughtcrime.securesms.connect.DcEventCenter;
import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.util.IntentUtils;
import org.thoughtcrime.securesms.util.JsonUtils;
import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.Prefs;
@@ -54,6 +55,8 @@ import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@@ -63,7 +66,9 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
private static final String EXTRA_ACCOUNT_ID = "accountId";
private static final String EXTRA_APP_MSG_ID = "appMessageId";
private static final String EXTRA_HIDE_ACTION_BAR = "hideActionBar";
private static final String EXTRA_HREF = "href";
private static final int REQUEST_CODE_FILE_PICKER = 51426;
private static long lastOpenTime = 0;
private ValueCallback<Uri[]> filePathCallback;
private DcContext dcContext;
@@ -71,12 +76,23 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
private DcMsg dcAppMsg;
private String baseURL;
private String sourceCodeUrl = "";
private String selfAddr;
private int sendUpdateMaxSize;
private int sendUpdateInterval;
private boolean internetAccess = false;
private boolean hideActionBar = false;
public static void openMaps(Context context, int chatId) {
openMaps(context, chatId, "");
}
public static void openMaps(Context context, int chatId, String href) {
DcContext dcContext = DcHelper.getContext(context);
int msgId = dcContext.initWebxdcIntegration(chatId);
int msgId = 0;
final int mapsVersion = 2;
if (dcContext.getConfigInt("ui.maps_version") >= mapsVersion) {
msgId = dcContext.initWebxdcIntegration(chatId);
}
if (msgId == 0) {
try {
InputStream inputStream = context.getResources().getAssets().open("webxdc/maps.xdc");
@@ -91,34 +107,36 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
Toast.makeText(context, "Cannot get maps.xdc, see log for details.", Toast.LENGTH_LONG).show();
return;
}
dcContext.setConfigInt("ui.maps_version", mapsVersion);
}
openWebxdcActivity(context, msgId, true);
openWebxdcActivity(context, msgId, true, href);
}
public static void openWebxdcActivity(Context context, DcMsg instance) {
openWebxdcActivity(context, instance.getId(), false);
openWebxdcActivity(context, instance, "");
}
public static void openWebxdcActivity(Context context, int msgId, boolean hideActionBar) {
public static void openWebxdcActivity(Context context, DcMsg instance, String href) {
openWebxdcActivity(context, instance.getId(), false, href);
}
public static void openWebxdcActivity(Context context, int msgId, boolean hideActionBar, String href) {
if (!Util.isClickedRecently()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (Prefs.isDeveloperModeEnabled(context)) {
WebView.setWebContentsDebuggingEnabled(true);
}
context.startActivity(getWebxdcIntent(context, msgId, hideActionBar));
} else {
Toast.makeText(context, "At least Android 5.0 (Lollipop) required for Webxdc.", Toast.LENGTH_LONG).show();
if (Prefs.isDeveloperModeEnabled(context)) {
WebView.setWebContentsDebuggingEnabled(true);
}
context.startActivity(getWebxdcIntent(context, msgId, hideActionBar, href));
}
}
private static Intent getWebxdcIntent(Context context, int msgId, boolean hideActionBar) {
private static Intent getWebxdcIntent(Context context, int msgId, boolean hideActionBar, String href) {
DcContext dcContext = DcHelper.getContext(context);
Intent intent = new Intent(context, WebxdcActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.putExtra(EXTRA_ACCOUNT_ID, dcContext.getAccountId());
intent.putExtra(EXTRA_APP_MSG_ID, msgId);
intent.putExtra(EXTRA_HIDE_ACTION_BAR, hideActionBar);
intent.putExtra(EXTRA_HREF, href);
return intent;
}
@@ -129,7 +147,7 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
.putExtra(ConversationActivity.CHAT_ID_EXTRA, dcContext.getMsg(msgId).getChatId())
.setAction(Intent.ACTION_VIEW);
final Intent webxdcIntent = getWebxdcIntent(context, msgId, false);
final Intent webxdcIntent = getWebxdcIntent(context, msgId, false, "");
return TaskStackBuilder.create(context)
.addNextIntentWithParentStack(chatIntent)
@@ -197,6 +215,9 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
// this is needed here because if the app is opened while already in landscape mode, onConfigurationChanged() is not triggered
setScreenMode(getResources().getConfiguration());
}
selfAddr = info.optString("self_addr");
sendUpdateMaxSize = info.optInt("send_update_max_size");
sendUpdateInterval = info.optInt("send_update_interval");
toggleFakeProxy(!internetAccess);
@@ -213,7 +234,20 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
webView.setNetworkAvailable(internetAccess); // this does not block network but sets `window.navigator.isOnline` in js land
webView.addJavascriptInterface(new InternalJSApi(), "InternalJSApi");
webView.loadUrl(this.baseURL + "/index.html");
String extraHref = b.getString(EXTRA_HREF, "");
if (TextUtils.isEmpty(extraHref)) {
extraHref = "index.html";
}
String href = baseURL + "/" + extraHref;
String encodedHref = "";
try {
encodedHref = URLEncoder.encode(href, Charsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
webView.loadUrl(this.baseURL + "/webxdc_bootstrap324567869.html?i=1&href=" + encodedHref);
Util.runOnAnyBackgroundThread(() -> {
final DcChat chat = dcContext.getChat(dcAppMsg.getChatId());
@@ -223,8 +257,21 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
});
}
@Override
public void onResume() {
super.onResume();
DcHelper.getNotificationCenter(this).updateVisibleWebxdc(dcContext.getAccountId(), dcAppMsg.getId());
}
@Override
protected void onPause() {
super.onPause();
DcHelper.getNotificationCenter(this).clearVisibleWebxdc();
}
@Override
protected void onDestroy() {
lastOpenTime = System.currentTimeMillis();
DcHelper.getEventCenter(this.getApplicationContext()).removeObservers(this);
leaveRealtimeChannel();
super.onDestroy();
@@ -247,7 +294,10 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
addToHomeScreen(this, dcAppMsg.getId());
return true;
case R.id.source_code:
openUrlInBrowser(this, sourceCodeUrl);
IntentUtils.showInBrowser(this, sourceCodeUrl);
return true;
case R.id.show_in_chat:
showInChat();
return true;
}
return false;
@@ -334,7 +384,7 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
res = new WebResourceResponse("text/plain", "UTF-8", targetStream);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && !internetAccess) {
if (!internetAccess) {
Map<String, String> headers = new HashMap<>();
headers.put("Content-Security-Policy",
"default-src 'self'; "
@@ -353,9 +403,7 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
}
private void callJavaScriptFunction(String func) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
webView.evaluateJavascript("window." + func + ";", null);
}
webView.evaluateJavascript("document.getElementById('frame').contentWindow." + func + ";", null);
}
@Override
@@ -394,6 +442,13 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
}
}
private void showInChat() {
Intent intent = new Intent(this, ConversationActivity.class);
intent.putExtra(ConversationActivity.CHAT_ID_EXTRA, dcAppMsg.getChatId());
intent.putExtra(ConversationActivity.STARTING_POSITION_EXTRA, DcMsg.getMessagePosition(dcAppMsg, dcContext));
startActivity(intent);
}
public static void addToHomeScreen(Activity activity, int msgId) {
Context context = activity.getApplicationContext();
try {
@@ -469,13 +524,23 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
return dcContext.isCommunity();
}
@JavascriptInterface
public int sendUpdateMaxSize() {
return WebxdcActivity.this.sendUpdateMaxSize;
}
@JavascriptInterface
public int sendUpdateInterval() {
return WebxdcActivity.this.sendUpdateInterval;
}
@JavascriptInterface
public String selfAddr() {
if (dcContext.isCommunity() && !TextUtils.isEmpty(dcContext.getCommunityUser())) {
int flags = Base64.NO_WRAP | Base64.NO_PADDING | Base64.URL_SAFE;
return Base64.encodeToString(dcContext.getCommunityUser().getBytes(), flags);
}
return dcContext.getConfig("configured_addr");
return WebxdcActivity.this.selfAddr;
}
/** @noinspection unused*/
@@ -493,9 +558,9 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
/** @noinspection unused*/
@JavascriptInterface
public boolean sendStatusUpdate(String payload, String descr) {
public boolean sendStatusUpdate(String payload) {
Log.i(TAG, "sendStatusUpdate");
if (!WebxdcActivity.this.dcContext.sendWebxdcStatusUpdate(WebxdcActivity.this.dcAppMsg.getId(), payload, descr)) {
if (!WebxdcActivity.this.dcContext.sendWebxdcStatusUpdate(WebxdcActivity.this.dcAppMsg.getId(), payload)) {
DcChat dcChat = WebxdcActivity.this.dcContext.getChat(WebxdcActivity.this.dcAppMsg.getChatId());
Toast.makeText(WebxdcActivity.this,
dcChat.isContactRequest() ?
@@ -0,0 +1,140 @@
package org.thoughtcrime.securesms;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.view.MenuItem;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
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.MediaUtil;
import org.thoughtcrime.securesms.util.Prefs;
import org.thoughtcrime.securesms.util.Util;
import java.io.ByteArrayInputStream;
import java.util.HashMap;
public class WebxdcStoreActivity extends PassphraseRequiredActionBarActivity {
private static final String TAG = WebxdcStoreActivity.class.getSimpleName();
private DcContext dcContext;
private Rpc rpc;
@Override
protected void onCreate(Bundle state, boolean ready) {
setContentView(R.layout.web_view_activity);
rpc = DcHelper.getRpc(this);
dcContext = DcHelper.getContext(this);
WebView webView = findViewById(R.id.webview);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle(R.string.webxdc_apps);
}
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
String ext = MediaUtil.getFileExtensionFromUrl(Uri.parse(url).getPath());
if ("xdc".equals(ext)) {
Util.runOnAnyBackgroundThread(() -> {
try {
HttpResponse httpResponse = rpc.getHttpResponse(dcContext.getAccountId(), url);
Uri uri = PersistentBlobProvider.getInstance().create(WebxdcStoreActivity.this, httpResponse.getBlob(), "application/octet-stream", "app.xdc");
Intent intent = new Intent();
intent.setData(uri);
setResult(Activity.RESULT_OK, intent);
finish();
} catch (RpcException e) {
e.printStackTrace();
Util.runOnMain(() -> Toast.makeText(WebxdcStoreActivity.this, "Error: " + e.getMessage(), Toast.LENGTH_LONG).show());
}
});
} else {
IntentUtils.showInBrowser(WebxdcStoreActivity.this, url);
}
return true;
}
@TargetApi(Build.VERSION_CODES.N)
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
return shouldOverrideUrlLoading(view, request.getUrl().toString());
}
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
return interceptRequest(request.getUrl().toString());
}
});
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setAllowFileAccess(false);
webSettings.setAllowContentAccess(false);
webSettings.setGeolocationEnabled(false);
webSettings.setAllowFileAccessFromFileURLs(false);
webSettings.setAllowUniversalAccessFromFileURLs(false);
webSettings.setDatabaseEnabled(true);
webSettings.setDomStorageEnabled(true);
webView.setNetworkAvailable(true); // this does not block network but sets `window.navigator.isOnline` in js land
webView.loadUrl(Prefs.getWebxdcStoreUrl(this));
}
private WebResourceResponse interceptRequest(String url) {
WebResourceResponse res = null;
try {
if (url == null) {
throw new Exception("no url specified");
}
HttpResponse httpResponse = rpc.getHttpResponse(dcContext.getAccountId(), url);
String mimeType = httpResponse.getMimetype();
if (mimeType == null) {
mimeType = "application/octet-stream";
}
ByteArrayInputStream data = new ByteArrayInputStream(httpResponse.getBlob());
res = new WebResourceResponse(mimeType, httpResponse.getEncoding(), data);
} catch (Exception e) {
e.printStackTrace();
ByteArrayInputStream data = new ByteArrayInputStream(("Could not load apps. Are you online?\n\n" + e.getMessage()).getBytes());
res = new WebResourceResponse("text/plain", "UTF-8", data);
}
HashMap<String, String> headers = new HashMap<>();
headers.put("access-control-allow-origin", "*");
res.setResponseHeaders(headers);
return res;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
}
return false;
}
}
@@ -93,7 +93,7 @@ public class WelcomeActivity extends BaseActionBarActivity implements DcEventCen
boolean canGoBack = AccountManager.getInstance().canRollbackAccountCreation(this);
supportActionBar.setDisplayHomeAsUpEnabled(canGoBack);
getSupportActionBar().setTitle(canGoBack? R.string.add_account : R.string.welcome_desktop);
getSupportActionBar().setTitle(canGoBack? R.string.add_account : R.string.app_name);
}
private void registerForEvents() {
@@ -166,7 +166,7 @@ public class WelcomeActivity extends BaseActionBarActivity implements DcEventCen
.withPermanentDenialDialog(getString(R.string.perm_explain_access_to_storage_denied))
.onAllGranted(() -> {
File imexDir = DcHelper.getImexDir();
if (Build.VERSION.SDK_INT >= 30) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
AttachmentManager.selectMediaType(this, "application/x-tar", null, PICK_BACKUP, StorageUtil.getDownloadUri());
} else {
final String backupFile = dcContext.imexHasBackup(imexDir.getAbsolutePath());
@@ -189,11 +189,16 @@ public class AccountSelectionListFragment extends DialogFragment implements DcEv
avatar.setAvatar(GlideApp.with(activity), recipient, false);
nameView.setText(name);
addrView.setText(contact.getAddr());
try {
sizeView.setText(Util.getPrettyFileSize(rpc.getAccountFileSize(accountId)));
} catch (RpcException e) {
e.printStackTrace();
}
Util.runOnAnyBackgroundThread(() -> {
try {
final int sizeBytes = rpc.getAccountFileSize(accountId);
Util.runOnMain(() -> {
sizeView.setText(Util.getPrettyFileSize(sizeBytes));
});
} catch (RpcException e) {
e.printStackTrace();
}
});
description.setText(activity.getString(R.string.delete_account_explain_with_name, name));
AlertDialog dialog = new AlertDialog.Builder(activity)
@@ -48,7 +48,7 @@ public class AudioRecorder {
ParcelFileDescriptor fds[] = ParcelFileDescriptor.createPipe();
captureUri = blobProvider.create(context, new ParcelFileDescriptor.AutoCloseInputStream(fds[0]),
MediaUtil.AUDIO_AAC, null, null);
MediaUtil.AUDIO_AAC, "voice.aac", null);
audioCodec = new AudioCodec(context);
audioCodec.start(new ParcelFileDescriptor.AutoCloseOutputStream(fds[1]));
@@ -87,11 +87,14 @@ public class AudioSlidePlayer {
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
if (playbackState == Player.STATE_READY) {
Util.runOnMain(() -> {
Log.d(TAG, "request duration " + durationCalculator.getDuration());
getListener().onReceivedDuration(Long.valueOf(durationCalculator.getDuration()).intValue());
durationCalculator.release();
durationCalculator.removeListener(this);
durationCalculator = null;
synchronized (AudioSlidePlayer.this) {
if (durationCalculator == null) return;
Log.d(TAG, "request duration " + durationCalculator.getDuration());
getListener().onReceivedDuration(Long.valueOf(durationCalculator.getDuration()).intValue());
durationCalculator.release();
durationCalculator.removeListener(this);
durationCalculator = null;
}
});
}
}
@@ -41,6 +41,7 @@ public class AttachmentTypeSelector extends PopupWindow {
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;
private static final int ANIMATION_DURATION = 300;
@@ -53,7 +54,7 @@ public class AttachmentTypeSelector extends PopupWindow {
//private final @NonNull ImageView cameraButton;
private final @NonNull ImageView videoButton;
private final @NonNull ImageView locationButton;
private final @NonNull ImageView closeButton;
private final @NonNull ImageView webxdcButton;
private @Nullable View currentAnchor;
private @Nullable AttachmentClickedListener listener;
@@ -76,7 +77,7 @@ public class AttachmentTypeSelector extends PopupWindow {
//this.cameraButton = ViewUtil.findById(layout, R.id.camera_button);
this.videoButton = ViewUtil.findById(layout, R.id.record_video_button);
this.locationButton = ViewUtil.findById(layout, R.id.location_button);
this.closeButton = ViewUtil.findById(layout, R.id.close_button);
this.webxdcButton = ViewUtil.findById(layout, R.id.webxdc_button);
this.imageButton.setOnClickListener(new PropagatingClickListener(ADD_GALLERY));
this.videoChatButton.setOnClickListener(new PropagatingClickListener(INVITE_VIDEO_CHAT));
@@ -85,7 +86,7 @@ public class AttachmentTypeSelector extends PopupWindow {
//this.cameraButton.setOnClickListener(new PropagatingClickListener(TAKE_PHOTO));
this.videoButton.setOnClickListener(new PropagatingClickListener(RECORD_VIDEO));
this.locationButton.setOnClickListener(new PropagatingClickListener(ADD_LOCATION));
this.closeButton.setOnClickListener(new CloseClickListener());
this.webxdcButton.setOnClickListener(new PropagatingClickListener(ADD_WEBXDC));
this.recentRail.setListener(new RecentPhotoSelectedListener());
if (!Prefs.isLocationStreamingEnabled(context)) {
@@ -130,33 +131,23 @@ public class AttachmentTypeSelector extends PopupWindow {
public void onGlobalLayout() {
getContentView().getViewTreeObserver().removeGlobalOnLayoutListener(this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
animateWindowInCircular(anchor, getContentView());
} else {
animateWindowInTranslate(getContentView());
}
animateWindowInCircular(anchor, getContentView());
}
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//animateButtonIn(cameraButton, ANIMATION_DURATION / 2);
animateButtonIn(videoButton, ANIMATION_DURATION / 2);
animateButtonIn(imageButton, ANIMATION_DURATION / 3);
animateButtonIn(contactButton, ANIMATION_DURATION / 3);
animateButtonIn(locationButton, ANIMATION_DURATION / 4);
animateButtonIn(documentButton, ANIMATION_DURATION / 4);
animateButtonIn(videoChatButton, 0);
animateButtonIn(closeButton, 0);
}
//animateButtonIn(cameraButton, ANIMATION_DURATION / 2);
animateButtonIn(videoButton, ANIMATION_DURATION / 2);
animateButtonIn(imageButton, ANIMATION_DURATION / 3);
animateButtonIn(contactButton, ANIMATION_DURATION / 3);
animateButtonIn(locationButton, ANIMATION_DURATION / 4);
animateButtonIn(documentButton, ANIMATION_DURATION / 4);
animateButtonIn(webxdcButton, 0);
animateButtonIn(videoChatButton, 0);
}
@Override
public void dismiss() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
animateWindowOutCircular(currentAnchor, getContentView());
} else {
animateWindowOutTranslate(getContentView());
}
animateWindowOutCircular(currentAnchor, getContentView());
}
public void setListener(@Nullable AttachmentClickedListener listener) {
@@ -186,7 +177,6 @@ public class AttachmentTypeSelector extends PopupWindow {
button.startAnimation(animation);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void animateWindowInCircular(@Nullable View anchor, @NonNull View contentView) {
Pair<Integer, Integer> coordinates = getClickOrigin(anchor, contentView);
Animator animator = ViewAnimationUtils.createCircularReveal(contentView,
@@ -205,7 +195,6 @@ public class AttachmentTypeSelector extends PopupWindow {
getContentView().startAnimation(animation);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void animateWindowOutCircular(@Nullable View anchor, @NonNull View contentView) {
Pair<Integer, Integer> coordinates = getClickOrigin(anchor, contentView);
Animator animator = ViewAnimationUtils.createCircularReveal(getContentView(),
@@ -301,13 +290,6 @@ public class AttachmentTypeSelector extends PopupWindow {
}
private class CloseClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
dismiss();
}
}
public interface AttachmentClickedListener {
public void onClick(int type);
public void onQuickAttachment(Uri uri);
@@ -71,12 +71,10 @@ public class AudioView extends FrameLayout implements AudioSlidePlayer.Listener
this.pauseButton.setOnClickListener(new PauseClickedListener());
this.seekBar.setOnSeekBarChangeListener(new SeekBarModifiedListener());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
this.playButton.setImageDrawable(context.getDrawable(R.drawable.play_icon));
this.pauseButton.setImageDrawable(context.getDrawable(R.drawable.pause_icon));
this.playButton.setBackground(context.getDrawable(R.drawable.ic_circle_fill_white_48dp));
this.pauseButton.setBackground(context.getDrawable(R.drawable.ic_circle_fill_white_48dp));
}
this.playButton.setImageDrawable(context.getDrawable(R.drawable.play_icon));
this.pauseButton.setImageDrawable(context.getDrawable(R.drawable.pause_icon));
this.playButton.setBackground(context.getDrawable(R.drawable.ic_circle_fill_white_48dp));
this.pauseButton.setBackground(context.getDrawable(R.drawable.ic_circle_fill_white_48dp));
setTint(getContext().getResources().getColor(R.color.audio_icon));
}
@@ -192,13 +190,8 @@ public class AudioView extends FrameLayout implements AudioSlidePlayer.Listener
}
public void setTint(int foregroundTint) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
this.playButton.setBackgroundTintList(ColorStateList.valueOf(foregroundTint));
this.pauseButton.setBackgroundTintList(ColorStateList.valueOf(foregroundTint));
} else {
this.playButton.setColorFilter(foregroundTint, PorterDuff.Mode.SRC_IN);
this.pauseButton.setColorFilter(foregroundTint, PorterDuff.Mode.SRC_IN);
}
this.playButton.setBackgroundTintList(ColorStateList.valueOf(foregroundTint));
this.pauseButton.setBackgroundTintList(ColorStateList.valueOf(foregroundTint));
this.seekBar.getProgressDrawable().setColorFilter(foregroundTint, PorterDuff.Mode.SRC_IN);
@@ -220,25 +213,20 @@ public class AudioView extends FrameLayout implements AudioSlidePlayer.Listener
private void togglePlayToPause() {
controlToggle.displayQuick(pauseButton);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
AnimatedVectorDrawable playToPauseDrawable = (AnimatedVectorDrawable)getContext().getDrawable(R.drawable.play_to_pause_animation);
pauseButton.setImageDrawable(playToPauseDrawable);
playToPauseDrawable.start();
}
AnimatedVectorDrawable playToPauseDrawable = (AnimatedVectorDrawable) getContext().getDrawable(R.drawable.play_to_pause_animation);
pauseButton.setImageDrawable(playToPauseDrawable);
playToPauseDrawable.start();
}
private void togglePauseToPlay() {
controlToggle.displayQuick(playButton);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
AnimatedVectorDrawable pauseToPlayDrawable = (AnimatedVectorDrawable)getContext().getDrawable(R.drawable.pause_to_play_animation);
playButton.setImageDrawable(pauseToPlayDrawable);
pauseToPlayDrawable.start();
}
AnimatedVectorDrawable pauseToPlayDrawable = (AnimatedVectorDrawable) getContext().getDrawable(R.drawable.pause_to_play_animation);
playButton.setImageDrawable(pauseToPlayDrawable);
pauseToPlayDrawable.start();
}
private class PlayClickedListener implements View.OnClickListener {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public void onClick(View v) {
try {
@@ -279,7 +267,6 @@ public class AudioView extends FrameLayout implements AudioSlidePlayer.Listener
}
private class PauseClickedListener implements View.OnClickListener {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public void onClick(View v) {
Log.w(TAG, "pausebutton onClick");
@@ -7,6 +7,7 @@ import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.widget.AppCompatEditText;
import androidx.core.view.inputmethod.EditorInfoCompat;
import androidx.core.view.inputmethod.InputConnectionCompat;
import androidx.core.view.inputmethod.InputContentInfoCompat;
@@ -25,10 +26,9 @@ import android.view.inputmethod.InputConnection;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.TransportOption;
import org.thoughtcrime.securesms.components.emoji.EmojiEditText;
import org.thoughtcrime.securesms.util.Prefs;
public class ComposeText extends EmojiEditText {
public class ComposeText extends AppCompatEditText {
private CharSequence hint;
private SpannableString subHint;
@@ -122,7 +122,6 @@ public class ComposeText extends EmojiEditText {
editorInfo.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION;
}
if (Build.VERSION.SDK_INT < 21) return inputConnection;
if (mediaListener == null) return inputConnection;
if (inputConnection == null) return null;
@@ -120,15 +120,10 @@ public class ConversationItemThumbnail extends FrameLayout {
@SuppressWarnings("SuspiciousNameCombination")
@Override
protected void dispatchDraw(Canvas canvas) {
if (cornerMask.isLegacy()) {
cornerMask.mask(canvas);
}
super.dispatchDraw(canvas);
if (!cornerMask.isLegacy()) {
cornerMask.mask(canvas);
}
cornerMask.mask(canvas);
final float halfStrokeWidth = outlinePaint.getStrokeWidth() / 2;
@@ -7,7 +7,7 @@ import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.os.Build;
import androidx.annotation.NonNull;
import android.view.View;
@@ -20,11 +20,7 @@ public class CornerMask {
private final RectF bounds = new RectF();
public CornerMask(@NonNull View view) {
if (isLegacy()) {
view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
} else {
view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
clearPaint.setColor(Color.BLACK);
clearPaint.setStyle(Paint.Style.FILL);
@@ -44,19 +40,10 @@ public class CornerMask {
// Note: There's a bug in the P beta where most PorterDuff modes aren't working. But CLEAR does.
// So we find and inverse path and use Mode.CLEAR for versions that support Path.op().
// See issue https://issuetracker.google.com/issues/111394085.
if (!isLegacy()) {
outline.reset();
outline.addRect(bounds, Path.Direction.CW);
outline.op(corners, Path.Op.DIFFERENCE);
canvas.drawPath(outline, clearPaint);
} else {
corners.addRoundRect(bounds, radii, Path.Direction.CW);
canvas.clipPath(corners);
}
}
public boolean isLegacy() {
return Build.VERSION.SDK_INT < 19;
outline.reset();
outline.addRect(bounds, Path.Direction.CW);
outline.op(corners, Path.Op.DIFFERENCE);
canvas.drawPath(outline, clearPaint);
}
public void setRadius(int radius) {
@@ -2,6 +2,8 @@ package org.thoughtcrime.securesms.components;
import android.content.Context;
import android.graphics.Typeface;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.core.view.ViewCompat;
import android.text.Spannable;
import android.text.SpannableString;
@@ -14,12 +16,11 @@ import android.text.style.TypefaceSpan;
import android.util.AttributeSet;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.components.emoji.EmojiTextView;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.ResUtil;
import org.thoughtcrime.securesms.util.spans.CenterAlignedRelativeSizeSpan;
public class FromTextView extends EmojiTextView {
public class FromTextView extends AppCompatTextView {
private static final String TAG = FromTextView.class.getSimpleName();
@@ -9,7 +9,6 @@ import android.os.Build;
import android.text.format.DateUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
@@ -29,14 +28,12 @@ import com.b44t.messenger.util.concurrent.SettableFuture;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.animation.AnimationCompleteListener;
import org.thoughtcrime.securesms.components.emoji.EmojiKeyboardProvider;
import org.thoughtcrime.securesms.components.emoji.EmojiToggle;
import org.thoughtcrime.securesms.components.emoji.MediaKeyboard;
import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.mms.QuoteModel;
import org.thoughtcrime.securesms.mms.SlideDeck;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.Prefs;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
import org.thoughtcrime.securesms.util.concurrent.AssertedSuccessListener;
@@ -46,9 +43,9 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
public class InputPanel extends ConstraintLayout
implements MicrophoneRecorderView.Listener,
KeyboardAwareLinearLayout.OnKeyboardShownListener,
EmojiKeyboardProvider.EmojiEventListener
implements MicrophoneRecorderView.Listener,
KeyboardAwareLinearLayout.OnKeyboardShownListener,
MediaKeyboard.MediaKeyboardListener
{
private static final String TAG = InputPanel.class.getSimpleName();
@@ -56,7 +53,7 @@ public class InputPanel extends ConstraintLayout
private static final int FADE_TIME = 150;
private QuoteView quoteView;
private EmojiToggle mediaKeyboard;
private EmojiToggle emojiToggle;
private ComposeText composeText;
private View quickCameraToggle;
private View quickAudioToggle;
@@ -70,7 +67,6 @@ public class InputPanel extends ConstraintLayout
private ValueAnimator quoteAnimator;
private @Nullable Listener listener;
private boolean emojiVisible;
public InputPanel(Context context) {
super(context);
@@ -92,7 +88,7 @@ public class InputPanel extends ConstraintLayout
View quoteDismiss = findViewById(R.id.quote_dismiss);
this.quoteView = findViewById(R.id.quote_view);
this.mediaKeyboard = findViewById(R.id.emoji_toggle);
this.emojiToggle = findViewById(R.id.emoji_toggle);
this.composeText = findViewById(R.id.embedded_text_editor);
this.quickCameraToggle = findViewById(R.id.quick_camera_toggle);
this.quickAudioToggle = findViewById(R.id.quick_audio_toggle);
@@ -106,21 +102,13 @@ public class InputPanel extends ConstraintLayout
this.recordLockCancel.setOnClickListener(v -> microphoneRecorderView.cancelAction());
if (Prefs.isSystemEmojiPreferred(getContext())) {
mediaKeyboard.setVisibility(View.GONE);
emojiVisible = false;
} else {
mediaKeyboard.setVisibility(View.VISIBLE);
emojiVisible = true;
}
quoteDismiss.setOnClickListener(v -> clearQuote());
}
public void setListener(final @NonNull Listener listener) {
this.listener = listener;
mediaKeyboard.setOnClickListener(v -> listener.onEmojiToggle());
emojiToggle.setOnClickListener(v -> listener.onEmojiToggle());
}
public void setMediaListener(@NonNull MediaListener listener) {
@@ -207,7 +195,7 @@ public class InputPanel extends ConstraintLayout
}
public void setMediaKeyboard(@NonNull MediaKeyboard mediaKeyboard) {
this.mediaKeyboard.attach(mediaKeyboard);
mediaKeyboard.setKeyboardListener(this);
}
@Override
@@ -221,7 +209,7 @@ public class InputPanel extends ConstraintLayout
recordTime.display();
slideToCancel.display();
if (emojiVisible) ViewUtil.fadeOut(mediaKeyboard, FADE_TIME, View.INVISIBLE);
ViewUtil.fadeOut(emojiToggle, FADE_TIME, View.INVISIBLE);
ViewUtil.fadeOut(composeText, FADE_TIME, View.INVISIBLE);
ViewUtil.fadeOut(quickCameraToggle, FADE_TIME, View.INVISIBLE);
ViewUtil.fadeOut(quickAudioToggle, FADE_TIME, View.INVISIBLE);
@@ -276,7 +264,7 @@ public class InputPanel extends ConstraintLayout
public void setEnabled(boolean enabled) {
composeText.setEnabled(enabled);
mediaKeyboard.setEnabled(enabled);
emojiToggle.setEnabled(enabled);
quickAudioToggle.setEnabled(enabled);
quickCameraToggle.setEnabled(enabled);
}
@@ -290,7 +278,7 @@ public class InputPanel extends ConstraintLayout
future.addListener(new AssertedSuccessListener<Void>() {
@Override
public void onSuccess(Void result) {
if (emojiVisible) ViewUtil.fadeIn(mediaKeyboard, FADE_TIME);
ViewUtil.fadeIn(emojiToggle, FADE_TIME);
ViewUtil.fadeIn(composeText, FADE_TIME);
ViewUtil.fadeIn(quickCameraToggle, FADE_TIME);
ViewUtil.fadeIn(quickAudioToggle, FADE_TIME);
@@ -304,17 +292,7 @@ public class InputPanel extends ConstraintLayout
@Override
public void onKeyboardShown() {
mediaKeyboard.setToMedia();
}
@Override
public void onKeyEvent(KeyEvent keyEvent) {
composeText.dispatchKeyEvent(keyEvent);
}
@Override
public void onEmojiSelected(String emoji) {
composeText.insertEmoji(emoji);
emojiToggle.setToMedia();
}
public boolean isRecordingInLockedMode() {
@@ -325,6 +303,25 @@ public class InputPanel extends ConstraintLayout
microphoneRecorderView.unlockAction();
}
@Override
public void onShown() {
emojiToggle.setToIme();
}
@Override
public void onHidden() {
emojiToggle.setToMedia();
}
@Override
public void onEmojiPicked(String emoji) {
final int start = composeText.getSelectionStart();
final int end = composeText.getSelectionEnd();
composeText.getText().replace(Math.min(start, end), Math.max(start, end), emoji);
composeText.setSelection(start + emoji.length());
}
public interface Listener {
void onRecorderStarted();
void onRecorderLocked();
@@ -104,7 +104,7 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
}
private void updateKeyboardState() {
if (viewInset == 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) viewInset = getViewInset();
if (viewInset == 0) viewInset = getViewInset();
getWindowVisibleDisplayFrame(rect);
@@ -148,7 +148,6 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
}
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
private int getViewInset() {
try {
Field attachInfoField = View.class.getDeclaredField("mAttachInfo");
@@ -219,11 +218,7 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
return Surface.ROTATION_0;
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
return ServiceUtil.getWindowManager(getContext()).getDefaultDisplay().getRotation();
}
if (Build.VERSION.SDK_INT >= 30) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
getContext().getDisplay().getRealMetrics(displayMetrics);
} else {
ServiceUtil.getWindowManager(getContext()).getDefaultDisplay().getRealMetrics(displayMetrics);
@@ -3,10 +3,8 @@ package org.thoughtcrime.securesms.components;
import android.content.Context;
import android.net.Uri;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import android.util.AttributeSet;
import android.view.View;
import android.view.Window;
@@ -40,7 +38,6 @@ public class MediaView extends FrameLayout {
initialize();
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public MediaView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
initialize();
@@ -56,6 +53,7 @@ public class MediaView extends FrameLayout {
public void set(@NonNull GlideRequests glideRequests,
@NonNull Window window,
@NonNull Uri source,
@Nullable String fileName,
@NonNull String mediaType,
long size,
boolean autoplay)
@@ -69,7 +67,7 @@ public class MediaView extends FrameLayout {
imageView.setVisibility(View.GONE);
videoView.get().setVisibility(View.VISIBLE);
videoView.get().setWindow(window);
videoView.get().setVideoSource(new VideoSlide(getContext(), source, size), autoplay);
videoView.get().setVideoSource(new VideoSlide(getContext(), source, fileName, size), autoplay);
} else {
throw new IOException("Unsupported media type: " + mediaType);
}
@@ -4,7 +4,6 @@ package org.thoughtcrime.securesms.components;
import android.content.Context;
import android.content.res.TypedArray;
import android.net.Uri;
import android.os.Build;
import android.text.Spannable;
import android.text.TextUtils;
import android.util.AttributeSet;
@@ -17,7 +16,6 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import com.annimon.stream.Stream;
import com.b44t.messenger.DcContact;
@@ -80,7 +78,6 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
initialize(attrs);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public QuoteView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
initialize(attrs);
@@ -158,7 +155,7 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
if (contact == null) {
authorView.setText(getContext().getString(R.string.forwarded_message));
} else {
authorView.setText(getContext().getString(R.string.forwarded_by, quotedMsg.getSenderName(contact, false)));
authorView.setText(getContext().getString(R.string.forwarded_by, quotedMsg.getSenderName(contact)));
}
authorView.setTextColor(getForwardedColor());
quoteBarView.setBackgroundColor(getForwardedColor());
@@ -169,7 +166,7 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
quoteBarView.setBackgroundColor(getForwardedColor());
} else {
authorView.setVisibility(VISIBLE);
authorView.setText(quotedMsg.getSenderName(contact, true));
authorView.setText(quotedMsg.getSenderName(contact));
if (hasSticker) {
authorView.setTextColor(getResources().getColor(R.color.core_dark_05));
quoteBarView.setBackgroundColor(getResources().getColor(R.color.core_dark_05));
@@ -29,7 +29,6 @@ public class RepeatableImageKey extends ImageButton {
init();
}
@TargetApi(VERSION_CODES.LOLLIPOP)
public RepeatableImageKey(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes)
{
@@ -130,15 +130,11 @@ public class SearchToolbar extends LinearLayout {
searchItem.expandActionView();
if (Build.VERSION.SDK_INT >= 21) {
Animator animator = ViewAnimationUtils.createCircularReveal(this, (int)x, (int)y, 0, getWidth());
animator.setDuration(400);
Animator animator = ViewAnimationUtils.createCircularReveal(this, (int) x, (int) y, 0, getWidth());
animator.setDuration(400);
setVisibility(View.VISIBLE);
animator.start();
} else {
setVisibility(View.VISIBLE);
}
setVisibility(View.VISIBLE);
animator.start();
}
}
@@ -153,19 +149,15 @@ public class SearchToolbar extends LinearLayout {
if (listener != null) listener.onSearchClosed();
if (Build.VERSION.SDK_INT >= 21) {
Animator animator = ViewAnimationUtils.createCircularReveal(this, (int)x, (int)y, getWidth(), 0);
animator.setDuration(400);
animator.addListener(new AnimationCompleteListener() {
@Override
public void onAnimationEnd(Animator animation) {
setVisibility(View.INVISIBLE);
}
});
animator.start();
} else {
setVisibility(View.INVISIBLE);
}
Animator animator = ViewAnimationUtils.createCircularReveal(this, (int) x, (int) y, getWidth(), 0);
animator.setDuration(400);
animator.addListener(new AnimationCompleteListener() {
@Override
public void onAnimationEnd(Animator animation) {
setVisibility(View.INVISIBLE);
}
});
animator.start();
}
}
@@ -18,7 +18,6 @@ public class SwitchPreferenceCompat extends CheckBoxPreference {
setLayoutRes();
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public SwitchPreferenceCompat(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
setLayoutRes();
@@ -1,12 +0,0 @@
package org.thoughtcrime.securesms.components.emoji;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Drawable.Callback;
import android.text.style.ImageSpan;
public class AnimatingImageSpan extends ImageSpan {
public AnimatingImageSpan(Drawable drawable, Callback callback) {
super(drawable, ALIGN_BOTTOM);
drawable.setCallback(callback);
}
}
@@ -1,60 +0,0 @@
package org.thoughtcrime.securesms.components.emoji;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import androidx.annotation.Nullable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.util.ResUtil;
public class AsciiEmojiView extends View {
private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
private String emoji;
public AsciiEmojiView(Context context) {
super(context);
}
public AsciiEmojiView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public void setEmoji(String emoji) {
this.emoji = emoji;
}
@Override
protected void onDraw(Canvas canvas) {
if (TextUtils.isEmpty(emoji)) {
return;
}
float targetFontSize = 0.75f * getHeight() - getPaddingTop() - getPaddingBottom();
paint.setTextSize(targetFontSize);
paint.setColor(ResUtil.getColor(getContext(), R.attr.emoji_text_color));
paint.setTextAlign(Paint.Align.CENTER);
int xPos = (getWidth() / 2);
int yPos = (int) ((getHeight() / 2) - ((paint.descent() + paint.ascent()) / 2));
float overflow = paint.measureText(emoji) / (getWidth() - getPaddingLeft() - getPaddingRight());
if (overflow > 1f) {
paint.setTextSize(targetFontSize / overflow);
yPos = (int) ((getHeight() / 2) - ((paint.descent() + paint.ascent()) / 2));
}
canvas.drawText(emoji, xPos, yPos, paint);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//noinspection SuspiciousNameCombination
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}
}
File diff suppressed because one or more lines are too long
@@ -1,55 +0,0 @@
package org.thoughtcrime.securesms.components.emoji;
import androidx.annotation.AttrRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.LinkedList;
import java.util.List;
public class CompositeEmojiPageModel implements EmojiPageModel {
@AttrRes private final int iconAttr;
@NonNull private final EmojiPageModel[] models;
public CompositeEmojiPageModel(@AttrRes int iconAttr, @NonNull EmojiPageModel... models) {
this.iconAttr = iconAttr;
this.models = models;
}
public int getIconAttr() {
return iconAttr;
}
@Override
public @NonNull List<String> getEmoji() {
List<String> emojis = new LinkedList<>();
for (EmojiPageModel model : models) {
emojis.addAll(model.getEmoji());
}
return emojis;
}
@Override
public @NonNull List<Emoji> getDisplayEmoji() {
List<Emoji> emojis = new LinkedList<>();
for (EmojiPageModel model : models) {
emojis.addAll(model.getDisplayEmoji());
}
return emojis;
}
@Override
public boolean hasSpriteMap() {
return false;
}
@Override
public @Nullable String getSprite() {
return null;
}
@Override
public boolean isDynamic() {
return false;
}
}
@@ -1,21 +0,0 @@
package org.thoughtcrime.securesms.components.emoji;
import java.util.Arrays;
import java.util.List;
public class Emoji {
private final List<String> variations;
public Emoji(String... variations) {
this.variations = Arrays.asList(variations);
}
public String getValue() {
return variations.get(0);
}
public List<String> getVariations() {
return variations;
}
}
@@ -1,62 +0,0 @@
package org.thoughtcrime.securesms.components.emoji;
import android.content.Context;
import android.graphics.drawable.Drawable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatEditText;
import android.text.InputFilter;
import android.util.AttributeSet;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.components.emoji.EmojiProvider.EmojiDrawable;
import org.thoughtcrime.securesms.util.Prefs;
public class EmojiEditText extends AppCompatEditText {
private static final String TAG = EmojiEditText.class.getSimpleName();
public EmojiEditText(Context context) {
this(context, null);
}
public EmojiEditText(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.editTextStyle);
}
public EmojiEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
if (!Prefs.isSystemEmojiPreferred(getContext())) {
setFilters(appendEmojiFilter(this.getFilters()));
}
}
public void insertEmoji(String emoji) {
final int start = getSelectionStart();
final int end = getSelectionEnd();
getText().replace(Math.min(start, end), Math.max(start, end), emoji);
setSelection(start + emoji.length());
}
@Override
public void invalidateDrawable(@NonNull Drawable drawable) {
if (drawable instanceof EmojiDrawable) invalidate();
else super.invalidateDrawable(drawable);
}
private InputFilter[] appendEmojiFilter(@Nullable InputFilter[] originalFilters) {
InputFilter[] result;
if (originalFilters != null) {
result = new InputFilter[originalFilters.length + 1];
System.arraycopy(originalFilters, 0, result, 1, originalFilters.length);
} else {
result = new InputFilter[1];
}
result[0] = new EmojiFilter(this);
return result;
}
}
@@ -1,30 +0,0 @@
package org.thoughtcrime.securesms.components.emoji;
import android.text.InputFilter;
import android.text.Spannable;
import android.text.Spanned;
import android.text.TextUtils;
import android.widget.TextView;
public class EmojiFilter implements InputFilter {
private final TextView view;
public EmojiFilter(TextView view) {
this.view = view;
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend)
{
char[] v = new char[end - start];
TextUtils.getChars(source, start, end, v, 0);
Spannable emojified = EmojiProvider.getInstance(view.getContext()).emojify(new String(v), view);
if (source instanceof Spanned && emojified != null) {
TextUtils.copySpansFrom((Spanned) source, start, end, null, emojified, 0);
}
return emojified;
}
}
@@ -1,20 +0,0 @@
package org.thoughtcrime.securesms.components.emoji;
import android.content.Context;
import android.util.AttributeSet;
import androidx.appcompat.widget.AppCompatImageView;
public class EmojiImageView extends AppCompatImageView {
public EmojiImageView(Context context) {
super(context);
}
public EmojiImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setImageEmoji(CharSequence emoji) {
setImageDrawable(EmojiProvider.getInstance(getContext()).getEmojiDrawable(emoji));
}
}
@@ -1,166 +0,0 @@
package org.thoughtcrime.securesms.components.emoji;
import android.content.Context;
import android.graphics.drawable.Drawable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewpager.widget.PagerAdapter;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.components.emoji.EmojiPageViewGridAdapter.VariationSelectorListener;
import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.util.ResUtil;
import org.thoughtcrime.securesms.util.ThemeUtil;
import java.util.LinkedList;
import java.util.List;
/**
* A provider to select emoji in the {@link org.thoughtcrime.securesms.components.emoji.MediaKeyboard}.
*/
public class EmojiKeyboardProvider implements MediaKeyboardProvider,
MediaKeyboardProvider.TabIconProvider,
MediaKeyboardProvider.BackspaceObserver,
VariationSelectorListener
{
private static final KeyEvent DELETE_KEY_EVENT = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL);
private static final String RECENT_STORAGE_KEY = "pref_recent_emoji2";
private final Context context;
private final List<EmojiPageModel> models;
private final RecentEmojiPageModel recentModel;
private final EmojiPagerAdapter emojiPagerAdapter;
private final EmojiEventListener emojiEventListener;
private Controller controller;
public EmojiKeyboardProvider(@NonNull Context context, @Nullable EmojiEventListener emojiEventListener) {
this.context = context;
this.emojiEventListener = emojiEventListener;
this.models = new LinkedList<>();
this.recentModel = new RecentEmojiPageModel(context, RECENT_STORAGE_KEY);
this.emojiPagerAdapter = new EmojiPagerAdapter(context, models, new EmojiEventListener() {
@Override
public void onEmojiSelected(String emoji) {
recentModel.onCodePointSelected(emoji);
if (emojiEventListener != null) {
emojiEventListener.onEmojiSelected(emoji);
}
}
@Override
public void onKeyEvent(KeyEvent keyEvent) {
if (emojiEventListener != null) {
emojiEventListener.onKeyEvent(keyEvent);
}
}
}, this);
models.add(recentModel);
models.addAll(EmojiPages.DISPLAY_PAGES);
}
@Override
public void requestPresentation(@NonNull Presenter presenter, boolean isSoloProvider) {
presenter.present(this, emojiPagerAdapter, this, this, null, null, recentModel.getEmoji().size() > 0 ? 0 : 1);
}
@Override
public void setController(@Nullable Controller controller) {
this.controller = controller;
}
@Override
public int getProviderIconView(boolean selected) {
if (selected) {
return ThemeUtil.isDarkTheme(context) ? R.layout.emoji_keyboard_icon_dark_selected : R.layout.emoji_keyboard_icon_light_selected;
} else {
return ThemeUtil.isDarkTheme(context) ? R.layout.emoji_keyboard_icon_dark : R.layout.emoji_keyboard_icon_light;
}
}
@Override
public void loadCategoryTabIcon(@NonNull GlideRequests glideRequests, @NonNull ImageView imageView, int index) {
Drawable drawable = ResUtil.getDrawable(context, models.get(index).getIconAttr());
imageView.setImageDrawable(drawable);
}
@Override
public void onBackspaceClicked() {
if (emojiEventListener != null) {
emojiEventListener.onKeyEvent(DELETE_KEY_EVENT);
}
}
@Override
public void onVariationSelectorStateChanged(boolean open) {
if (controller != null) {
controller.setViewPagerEnabled(!open);
}
}
@Override
public boolean equals(@Nullable Object obj) {
return obj instanceof EmojiKeyboardProvider;
}
private static class EmojiPagerAdapter extends PagerAdapter {
private final Context context;
private final List<EmojiPageModel> pages;
private final EmojiEventListener emojiSelectionListener;
private final VariationSelectorListener variationSelectorListener;
public EmojiPagerAdapter(@NonNull Context context,
@NonNull List<EmojiPageModel> pages,
@NonNull EmojiEventListener emojiSelectionListener,
@NonNull VariationSelectorListener variationSelectorListener)
{
super();
this.context = context;
this.pages = pages;
this.emojiSelectionListener = emojiSelectionListener;
this.variationSelectorListener = variationSelectorListener;
}
@Override
public int getCount() {
return pages.size();
}
@Override
public @NonNull Object instantiateItem(@NonNull ViewGroup container, int position) {
EmojiPageView page = new EmojiPageView(context, emojiSelectionListener, variationSelectorListener, true);
page.setModel(pages.get(position));
container.addView(page);
return page;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View)object);
}
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
EmojiPageView current = (EmojiPageView) object;
current.onSelected();
super.setPrimaryItem(container, position, object);
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
}
public interface EmojiEventListener {
void onEmojiSelected(String emoji);
void onKeyEvent(KeyEvent keyEvent);
}
}
@@ -1,12 +0,0 @@
package org.thoughtcrime.securesms.components.emoji;
import java.util.List;
public interface EmojiPageModel {
int getIconAttr();
List<String> getEmoji();
List<Emoji> getDisplayEmoji();
boolean hasSpriteMap();
String getSprite();
boolean isDynamic();
}

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