1
0
mirror of https://github.com/vector-im/riotX-android synced 2025-10-06 00:02:48 +02:00

Compare commits

...

329 Commits

Author SHA1 Message Date
Benoit Marty
fd6a45a3ae Merge branch 'release/1.6.5' into main 2023-07-25 14:56:37 +02:00
Benoit Marty
f8138a7860 Adding fastlane file for version 1.6.5 2023-07-25 14:56:31 +02:00
Benoit Marty
0dea54388c Changelog for version 1.6.5 2023-07-25 14:56:03 +02:00
Benoit Marty
9776839b50 Merge pull request #8589 from RiotTranslateBot/weblate-element-android-element-app
Translations update from Weblate
2023-07-25 09:59:16 +02:00
Edgars Andersons
f48ed3679b Translated using Weblate (Latvian)
Currently translated at 83.7% (2207 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/lv/
2023-07-25 02:31:19 +00:00
Edgars Andersons
d9a27b1514 Translated using Weblate (Latvian)
Currently translated at 83.0% (2189 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/lv/
2023-07-24 08:38:07 +00:00
Edgars Andersons
9d19ca6ec2 Translated using Weblate (Latvian)
Currently translated at 82.7% (2180 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/lv/
2023-07-22 11:22:15 +00:00
Weblate
657822891a Merge branch 'origin/develop' into Weblate. 2023-07-22 02:35:31 +00:00
raspin0
c86b4f9e9f Translated using Weblate (Polish)
Currently translated at 100.0% (2640 of 2640 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/pl/
2023-07-22 02:35:28 +00:00
Edgars Andersons
3fe71357dd Translated using Weblate (Latvian)
Currently translated at 82.3% (2170 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/lv/
2023-07-21 17:52:37 +00:00
Benoit Marty
14d691446a Merge pull request #8583 from RiotTranslateBot/weblate-element-android-element-app
Translations update from Weblate
2023-07-21 17:52:19 +02:00
Edgars Andersons
86a126b257 Translated using Weblate (Latvian)
Currently translated at 80.1% (2113 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/lv/
2023-07-19 13:13:54 +00:00
Srebrni
69b8e125e0 Translated using Weblate (Slovenian)
Currently translated at 2.6% (70 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sl/
2023-07-18 23:14:52 +00:00
Weblate
832b4680d2 Merge branch 'origin/develop' into Weblate. 2023-07-18 20:14:53 +00:00
Srebrni
b3e8a64ad5 Translated using Weblate (Slovenian)
Currently translated at 2.3% (63 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sl/
2023-07-18 20:14:50 +00:00
Poesty Li
37f62671f6 Translated using Weblate (Chinese (Simplified))
Currently translated at 99.1% (2613 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hans/
2023-07-18 20:14:49 +00:00
Srebrni
0c7fdae63a Translated using Weblate (Slovenian)
Currently translated at 2.3% (63 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sl/
2023-07-18 20:14:35 +00:00
th ad
2ec4d1c98a Translated using Weblate (Slovenian)
Currently translated at 2.3% (63 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sl/
2023-07-18 20:14:35 +00:00
th ad
9ce1034a5c Translated using Weblate (Slovenian)
Currently translated at 2.3% (62 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sl/
2023-07-18 20:13:21 +00:00
Srebrni
2af1516ebd Translated using Weblate (Slovenian)
Currently translated at 2.3% (62 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sl/
2023-07-18 20:13:06 +00:00
Edgars Andersons
2a158996e6 Translated using Weblate (Latvian)
Currently translated at 75.6% (1995 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/lv/
2023-07-18 20:01:58 +00:00
Benoit Marty
180a2eec60 Merge pull request #8578 from vector-im/feature/bma/crashFixes
Crash fixes
2023-07-17 16:12:24 +02:00
Benoit Marty
13596594a4 Merge pull request #8579 from RiotTranslateBot/weblate-element-android-element-app
Translations update from Weblate
2023-07-17 11:05:53 +02:00
Jozef Gaal
12a7506b57 Translated using Weblate (Slovak)
Currently translated at 100.0% (2640 of 2640 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sk/
2023-07-17 05:25:50 +00:00
Edgars Andersons
23f0f6ada3 Translated using Weblate (Latvian)
Currently translated at 75.1% (1982 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/lv/
2023-07-15 09:15:15 +00:00
Edgars Andersons
6ac5254ff3 Translated using Weblate (Latvian)
Currently translated at 73.1% (1929 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/lv/
2023-07-14 06:58:43 +00:00
Edgars Andersons
d98ba3c08e Translated using Weblate (Latvian)
Currently translated at 72.3% (1908 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/lv/
2023-07-14 06:13:43 +00:00
walito-arch
70744b2dad Translated using Weblate (Swahili)
Currently translated at 1.4% (38 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sw/
2023-07-14 00:15:56 +00:00
Nui Harime
e76063126b Translated using Weblate (Russian)
Currently translated at 99.8% (2633 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/ru/
2023-07-14 00:15:55 +00:00
Edgars Andersons
66f6cfcc6c Translated using Weblate (Latvian)
Currently translated at 71.6% (1888 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/lv/
2023-07-14 00:15:54 +00:00
Benoit Marty
ae52d4cd3c Fix crash in the setting when enabling/disabling integration manager and there is no network. 2023-07-11 18:10:54 +02:00
Benoit Marty
8433e222ad Fix unhandled crashes when network is not reacheable. 2023-07-11 18:10:38 +02:00
Benoit Marty
2a5df54ae4 Fix crash: show an error message with a Retry button when there is no network when displaying the BootstrapBottomSheet. 2023-07-11 18:09:00 +02:00
Edgars Andersons
8eccae44e5 Translated using Weblate (Latvian)
Currently translated at 69.9% (1844 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/lv/
2023-07-11 15:01:50 +00:00
Nui Harime
841028774e Translated using Weblate (Russian)
Currently translated at 99.8% (2633 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/ru/
2023-07-10 23:07:14 +00:00
Nui Harime
c08b99a4f1 Translated using Weblate (Russian)
Currently translated at 99.7% (2629 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/ru/
2023-07-10 09:16:09 +00:00
KuriakiMariaHere
6fd589440d Translated using Weblate (Greek)
Currently translated at 17.6% (465 of 2640 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/el/
2023-07-09 22:24:20 +00:00
KuriakiMariaHere
eef01ad8f9 Translated using Weblate (Greek)
Currently translated at 17.1% (452 of 2640 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/el/
2023-07-08 21:49:11 +00:00
Nui Harime
99e171dbee Translated using Weblate (Russian)
Currently translated at 99.6% (2628 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/ru/
2023-07-08 20:43:45 +00:00
KuriakiMariaHere
2bbd5ee7d9 Translated using Weblate (Greek)
Currently translated at 17.0% (451 of 2640 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/el/
2023-07-08 20:43:44 +00:00
KuriakiMariaHere
c3752f529a Translated using Weblate (Greek)
Currently translated at 16.7% (442 of 2640 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/el/
2023-07-08 00:56:30 +00:00
Nui Harime
c1e77c6dc9 Translated using Weblate (Russian)
Currently translated at 99.6% (2628 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/ru/
2023-07-07 12:56:21 +00:00
walito-arch
1ef2de0356 Translated using Weblate (Swahili)
Currently translated at 1.0% (28 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sw/
2023-07-06 11:54:16 +00:00
Theo
87f2a69fb1 Translated using Weblate (Greek)
Currently translated at 16.0% (425 of 2640 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/el/
2023-07-06 11:46:28 +00:00
Dimitris Vagiakakos
fedbfe4931 Translated using Weblate (Greek)
Currently translated at 16.0% (425 of 2640 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/el/
2023-07-06 11:46:28 +00:00
Edgars Andersons
85d0837f3b Translated using Weblate (Latvian)
Currently translated at 68.6% (1810 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/lv/
2023-07-05 12:21:22 +00:00
Edgars Andersons
1b43087eb3 Translated using Weblate (Latvian)
Currently translated at 68.5% (1807 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/lv/
2023-07-05 09:23:39 +00:00
Weblate
dab799e3cb Merge branch 'origin/develop' into Weblate. 2023-07-04 14:12:38 +00:00
Yoan Pintas
0573915a0a Update MSC3912 implementation: Redaction of related events (#8532) 2023-07-04 13:12:37 +00:00
Edgars Andersons
1ab2bb9bf8 Translated using Weblate (Latvian)
Currently translated at 68.1% (1797 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/lv/
2023-07-03 23:17:22 +00:00
Someone
0c9ebfdab6 Translated using Weblate (Vietnamese)
Currently translated at 88.1% (2324 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/vi/
2023-07-02 01:36:44 +00:00
Weblate
9a1f5fd1a0 Merge branch 'origin/develop' into Weblate. 2023-06-30 15:52:04 +00:00
Kat Gerasimova
bbcea97120 Send new issues to new triage board (#8567)
Issues should go to the V2 triage board
2023-06-30 16:18:15 +02:00
Someone
6fcd582f2d Translated using Weblate (Vietnamese)
Currently translated at 88.0% (2320 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/vi/
2023-06-30 11:16:51 +00:00
Someone
e4e17d865b Translated using Weblate (Vietnamese)
Currently translated at 56.0% (56 of 100 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/vi/
2023-06-30 11:16:51 +00:00
Someone
0a4bdceff8 Translated using Weblate (Vietnamese)
Currently translated at 88.0% (2320 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/vi/
2023-06-29 17:16:17 +00:00
Văn Huy Dương
05ce2cab27 Translated using Weblate (Vietnamese)
Currently translated at 88.0% (2320 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/vi/
2023-06-29 10:41:04 +00:00
Edgars Andersons
7080ee1c26 Translated using Weblate (Latvian)
Currently translated at 68.0% (1795 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/lv/
2023-06-29 07:27:45 +00:00
Vri
cf6de09483 Translated using Weblate (German)
Currently translated at 100.0% (2640 of 2640 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/de/
2023-06-28 09:00:05 +00:00
Weblate
0c7dcc767d Merge branch 'origin/develop' into Weblate. 2023-06-27 17:03:37 +00:00
Benoit Marty
2b4b5f05eb Merge pull request #8556 from vector-im/feature/bma/noJcenter
Feature/bma/no jcenter
2023-06-27 17:04:59 +02:00
Weblate
12bf1ea2eb Merge branch 'origin/develop' into Weblate. 2023-06-27 14:58:20 +00:00
Valere
7b8cf5d917 version++ 2023-06-27 13:30:17 +02:00
Valere
21200266e2 Merge branch 'release/1.6.3' into develop 2023-06-27 13:22:41 +02:00
Valere
f5f4d4a326 Merge branch 'release/1.6.3' into main 2023-06-27 12:52:17 +02:00
Valere
637b1483cc Adding fastlane file for version 1.6.3 2023-06-27 12:12:06 +02:00
Valere
042f144afe Changelog for version 1.6.3 2023-06-27 12:11:42 +02:00
Valere
8cd51ea803 Setting version for the release 1.6.3 2023-06-27 10:04:39 +02:00
Weblate
6e7078637f Merge branch 'origin/develop' into Weblate. 2023-06-26 23:36:45 +00:00
FIONover
61b05edd9e Translated using Weblate (Armenian)
Currently translated at 1.0% (1 of 100 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/hy/
2023-06-26 23:36:41 +00:00
Benoit Marty
218799e025 Merge pull request #8560 from RiotTranslateBot/weblate-element-android-element-app
Translations update from Weblate
2023-06-26 20:37:33 +02:00
Weblate
0f581dc391 Merge branch 'origin/develop' into Weblate. 2023-06-26 15:17:53 +00:00
Valere
75fd62aef9 Merge pull request #8536 from vector-im/feature/bca/new_login_detection
Fixes new device detections banner problems
2023-06-26 16:45:11 +02:00
valere
3c1c645806 fix sdk ts is already in milliseconds 2023-06-26 11:55:04 +02:00
valere
7205cd73d4 quality 2023-06-26 11:13:08 +02:00
Weblate
ac1ee734f4 Merge branch 'origin/develop' into Weblate. 2023-06-26 09:13:05 +00:00
valere
51c4dfc675 fix changelog 2023-06-26 10:48:58 +02:00
valere
5f20ceeb1c Add change log 2023-06-26 10:48:58 +02:00
valere
3e73137c18 Fixes new device detections banner problems 2023-06-26 10:48:58 +02:00
Valere
dfadc8eca1 Merge pull request #8554 from vector-im/feature/bca/bump_rust_sdk
Bump rust sdk version to 0.3.10
2023-06-26 10:45:27 +02:00
Benoit Marty
7940584674 Changelog. 2023-06-23 23:20:30 +02:00
Benoit Marty
9b63293e45 Rename files to avoid danger issue. 2023-06-23 23:13:52 +02:00
Benoit Marty
2c57453efd Fix detekt issue 2023-06-23 23:00:00 +02:00
Benoit Marty
ea424f29fb Fix ktlint issue 2023-06-23 22:58:28 +02:00
Benoit Marty
dc9e649703 Remove Jcenter repository ref (#2773) 2023-06-23 19:00:06 +02:00
Benoit Marty
e9f9decf00 Import source from https://github.com/dm77/barcodescanner 2023-06-23 18:58:42 +02:00
Benoit Marty
69680a9856 Import source from https://github.com/2dxgujun/Kpan 2023-06-23 18:23:14 +02:00
Benoit Marty
e9b9434671 Remove unused dep. 2023-06-23 18:01:36 +02:00
Benoit Marty
ff09ba1208 Import source from https://github.com/cmelchior/realmfieldnameshelper 2023-06-23 17:58:51 +02:00
Benoit Marty
cd292488b6 Fix warning 2023-06-23 17:51:57 +02:00
Benoit Marty
1dd3c1589e Remove unused dep. 2023-06-23 17:48:06 +02:00
Benoit Marty
3da1497d27 Import source from https://github.com/natario1/Autocomplete 2023-06-23 17:46:12 +02:00
Benoit Marty
f304e40d57 Import source from https://github.com/amulyakhare/TextDrawable 2023-06-23 17:35:14 +02:00
waclaw66
93d3c73306 Translated using Weblate (Czech)
Currently translated at 100.0% (2640 of 2640 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/cs/
2023-06-22 23:07:54 +00:00
valere
6ef9557698 add changelog 2023-06-22 16:57:48 +02:00
valere
08ae1105ff Bump rust sdk version to 0.3.10 2023-06-22 16:56:15 +02:00
Weblate
16f5d48120 Merge branch 'origin/develop' into Weblate. 2023-06-21 13:24:03 +00:00
David Langley
a065cd338c Merge pull request #8440 from vector-im/jonny/feat/rich-text-mentions
[Rich text editor] Add mentions and slash commands
2023-06-21 11:26:13 +01:00
David Langley
cfae6e9e51 Remove TODO causing failed lint check. 2023-06-21 09:49:44 +01:00
David Langley
e988308dc6 Add space after mention inserstion. 2023-06-21 09:30:45 +01:00
Martin Berg Alstad
ff0873f5e8 Translated using Weblate (Norwegian Bokmål (nb))
Currently translated at 4.0% (4 of 100 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/nb/
2023-06-20 22:18:15 +00:00
Makkkkus
3170d07f9b Translated using Weblate (Norwegian Nynorsk)
Currently translated at 19.0% (503 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/nn/
2023-06-20 22:18:15 +00:00
waclaw66
90e752472f Translated using Weblate (Czech)
Currently translated at 100.0% (2640 of 2640 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/cs/
2023-06-20 18:12:56 +00:00
th ad
eeec549bd0 Translated using Weblate (Slovenian)
Currently translated at 2.2% (60 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sl/
2023-06-19 16:06:24 +00:00
waclaw66
107f51da0d Translated using Weblate (Czech)
Currently translated at 100.0% (2640 of 2640 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/cs/
2023-06-19 16:06:23 +00:00
jonnyandrew
9d239bf94d Use proper API to insert mention from timeline user 2023-06-19 13:41:08 +01:00
th ad
3c645ef1bb Translated using Weblate (Slovenian)
Currently translated at 2.2% (59 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sl/
2023-06-18 22:14:41 +00:00
th ad
f5ac1f120a Translated using Weblate (Slovenian)
Currently translated at 2.1% (57 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sl/
2023-06-18 00:12:30 +00:00
Priit Jõerüüt
e8e8e7c5bc Translated using Weblate (Estonian)
Currently translated at 100.0% (2640 of 2640 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/et/
2023-06-17 08:08:22 +00:00
rofyobilte
7d4af8d059 Translated using Weblate (Portuguese (Brazil))
Currently translated at 98.5% (2597 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/pt_BR/
2023-06-17 06:16:49 +00:00
Weblate
c1887aaa9f Merge branch 'origin/develop' into Weblate. 2023-06-16 12:50:26 +00:00
random
38ba1cbbe9 Translated using Weblate (Italian)
Currently translated at 100.0% (2636 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/it/
2023-06-16 12:50:26 +00:00
Benoit Marty
cd5737276c Translated using Weblate (Portuguese (Brazil))
Currently translated at 98.0% (2584 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/pt_BR/
2023-06-16 12:50:19 +00:00
Benoit Marty
4af2f700f7 Merge pull request #8541 from abaker/fix_fallback_key_sharing_strategy
Fix fallbackKeySharingStrategy
2023-06-16 13:05:30 +02:00
Yoan Pintas
710d21f6a4 Implement MSC3987: Push actions clean-up (#8530) 2023-06-16 09:13:13 +00:00
Someone
7497cf6729 Translated using Weblate (Vietnamese)
Currently translated at 87.2% (2300 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/vi/
2023-06-15 17:52:46 +00:00
Alex Baker
572bdb6dfe Fix fallbackKeySharingStrategy
Signed-off-by: Alex Baker <alex@beeper.com>
2023-06-14 16:29:22 -05:00
Weblate
5e60c97566 Merge branch 'origin/develop' into Weblate. 2023-06-13 12:08:05 +00:00
Valere
ce80d7ff2f Merge pull request #8507 from vector-im/feature/bca/clean_room_shield_update
Clean room shield update logic
2023-06-13 12:27:28 +02:00
Weblate
b0558a300e Merge branch 'origin/develop' into Weblate. 2023-06-12 11:11:45 +00:00
random
257072330f Translated using Weblate (Italian)
Currently translated at 100.0% (2636 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/it/
2023-06-12 11:11:40 +00:00
valere
1d651db82b Add change log 2023-06-12 11:39:55 +02:00
valere
6fe0002bd3 Clean room shield update logic 2023-06-12 11:39:55 +02:00
Benoit Marty
f5764372c2 Merge pull request #8519 from vector-im/feature/bma/pauseDependabot
Only upgrade our libraries to limit the number of open PRs by Dependabot
2023-06-12 10:41:15 +02:00
Oleg
bbc1ed9e62 Translated using Weblate (Russian)
Currently translated at 91.0% (91 of 100 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/ru/
2023-06-11 18:01:42 +00:00
Oleg
d30c6018e4 Translated using Weblate (Russian)
Currently translated at 99.6% (2628 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/ru/
2023-06-11 18:01:41 +00:00
David Langley
cb64175c2b Fix line length and typo. 2023-06-09 19:43:26 +01:00
David Langley
3b887fdf4e Test room alias links and fix bug found with PillDisplayHander not handling them 2023-06-09 18:12:52 +01:00
David Langley
36b97b1647 Merge branch 'main' of github.com:vector-im/element-android into jonny/feat/rich-text-mentions 2023-06-09 16:05:46 +01:00
David Langley
cfa0f95799 Add PillDisplayHandler tests for custom domains. 2023-06-09 16:02:09 +01:00
David Langley
f3db4a857a always use getText().insert for adding pills 2023-06-09 14:58:17 +01:00
Benoit Marty
ba3e7f63ff Only upgrade our libraries to limit the number of open PRs by Dependabot (#8518) 2023-06-09 15:40:53 +02:00
Weblate
8909c6027d Merge branch 'origin/develop' into Weblate. 2023-06-09 12:32:58 +00:00
Benoit Marty
48df1136ca Merge pull request #8471 from vector-im/bugfix/cjs/poll-finish-contents
Show correct details when a poll is ended.
2023-06-09 14:28:07 +02:00
Weblate
871f054486 Merge branch 'origin/develop' into Weblate. 2023-06-09 12:24:24 +00:00
David Langley
7d084f18a0 Merge pull request #8517 from vector-im/dla/feature/rte_paste_images
Update rich text editor library to support pasting of images
2023-06-09 13:22:05 +01:00
Someone
69ecdba175 Translated using Weblate (Vietnamese)
Currently translated at 85.9% (2266 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/vi/
2023-06-09 11:01:21 +00:00
David Langley
38330a7b67 Update RTE library to support pasting of images. 2023-06-09 09:29:01 +01:00
Someone
0e7ca50588 Translated using Weblate (Vietnamese)
Currently translated at 85.9% (2265 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/vi/
2023-06-09 07:23:19 +00:00
Someone
2a7b92d48f Translated using Weblate (Vietnamese)
Currently translated at 85.5% (2256 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/vi/
2023-06-09 07:12:26 +00:00
Someone
0ca5caee85 Translated using Weblate (Vietnamese)
Currently translated at 85.5% (2255 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/vi/
2023-06-09 07:12:16 +00:00
Someone
4903c24661 Translated using Weblate (Vietnamese)
Currently translated at 85.5% (2254 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/vi/
2023-06-09 07:12:09 +00:00
Someone
5e00d474d9 Translated using Weblate (Vietnamese)
Currently translated at 85.5% (2254 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/vi/
2023-06-09 07:11:53 +00:00
Someone
33ef138d4b Translated using Weblate (Vietnamese)
Currently translated at 85.4% (2253 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/vi/
2023-06-09 07:11:49 +00:00
Someone
b840ff1d25 Translated using Weblate (Vietnamese)
Currently translated at 84.5% (2230 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/vi/
2023-06-09 07:04:51 +00:00
waclaw66
e6bf8a981d Translated using Weblate (Czech)
Currently translated at 100.0% (2640 of 2640 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/cs/
2023-06-09 06:30:50 +00:00
Someone
836fc71ebc Translated using Weblate (Vietnamese)
Currently translated at 84.5% (2229 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/vi/
2023-06-09 06:00:18 +00:00
Weblate
4d291a4f43 Merge branch 'origin/develop' into Weblate. 2023-06-08 22:24:35 +00:00
Benoit Marty
0f18cdb7d2 Merge pull request #8512 from vector-im/feature/bca/fix_deactivation_test
Deactivation test broken by latest synapse
2023-06-08 16:42:32 +02:00
Paul Marc
a311b21d7c Translated using Weblate (Arabic)
Currently translated at 39.2% (1036 of 2640 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/ar/
2023-06-08 14:07:29 +00:00
valere
6b2331dcbf Deactivation test broken by latest synapse 2023-06-08 14:18:34 +02:00
Linerly
2d21d3f6ce Translated using Weblate (Indonesian)
Currently translated at 100.0% (100 of 100 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/id/
2023-06-08 05:46:47 +00:00
raspin0
45d75ecc6d Translated using Weblate (Polish)
Currently translated at 100.0% (100 of 100 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/pl/
2023-06-06 19:55:05 +00:00
Weblate
db993fc3d6 Merge branch 'origin/develop' into Weblate. 2023-06-06 16:02:18 +00:00
Besnik Bleta
ec9c3fa6f7 Translated using Weblate (Albanian)
Currently translated at 100.0% (100 of 100 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/sq/
2023-06-06 16:02:16 +00:00
waclaw66
6e300872ac Translated using Weblate (Czech)
Currently translated at 100.0% (100 of 100 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/cs/
2023-06-06 16:02:14 +00:00
Someone
8cd716b87e Translated using Weblate (Vietnamese)
Currently translated at 84.4% (2225 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/vi/
2023-06-06 16:02:12 +00:00
Someone
961ea9a8e0 Translated using Weblate (Vietnamese)
Currently translated at 56.0% (56 of 100 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/vi/
2023-06-06 16:02:10 +00:00
Peter Chen
ebb05484a5 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (100 of 100 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/zh_Hant/
2023-06-06 16:02:09 +00:00
Danial Behzadi
fabde93481 Translated using Weblate (Persian)
Currently translated at 100.0% (100 of 100 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/fa/
2023-06-06 16:02:08 +00:00
random
b5f1941ae4 Translated using Weblate (Italian)
Currently translated at 100.0% (100 of 100 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/it/
2023-06-06 16:02:06 +00:00
Priit Jõerüüt
bb5a65cb60 Translated using Weblate (Estonian)
Currently translated at 100.0% (100 of 100 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/et/
2023-06-06 16:02:05 +00:00
Ihor Hordiichuk
93a93c5295 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (100 of 100 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/uk/
2023-06-06 16:02:04 +00:00
LinAGKar
acdaec42c3 Translated using Weblate (Swedish)
Currently translated at 100.0% (100 of 100 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/sv/
2023-06-06 16:02:03 +00:00
Jozef Gaal
e35ec86930 Translated using Weblate (Slovak)
Currently translated at 100.0% (100 of 100 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/sk/
2023-06-06 16:02:02 +00:00
Glandos
65175106da Translated using Weblate (French)
Currently translated at 100.0% (100 of 100 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/fr/
2023-06-06 16:02:00 +00:00
Vri
551d559be1 Translated using Weblate (German)
Currently translated at 100.0% (100 of 100 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/de/
2023-06-06 16:01:59 +00:00
phardyle
a8d8176d97 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (2636 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hant/
2023-06-06 16:01:58 +00:00
Jeff Huang
f7dd492adc Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (2636 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hant/
2023-06-06 16:01:58 +00:00
phardyle
8c63e872b9 Translated using Weblate (Chinese (Simplified))
Currently translated at 98.4% (2594 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hans/
2023-06-06 16:01:57 +00:00
LinAGKar
e4bff75557 Translated using Weblate (Swedish)
Currently translated at 100.0% (2636 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sv/
2023-06-06 16:01:56 +00:00
random
cc08bfd500 Translated using Weblate (Italian)
Currently translated at 100.0% (2636 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/it/
2023-06-06 16:01:56 +00:00
Linerly
06d30c3df2 Translated using Weblate (Indonesian)
Currently translated at 100.0% (2636 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/id/
2023-06-06 16:01:56 +00:00
Vri
a70fba9f6a Translated using Weblate (German)
Currently translated at 100.0% (2636 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/de/
2023-06-06 16:01:55 +00:00
Yoan Pintas
07e06957ef Prompt the user when the invited MatrixId is not recognized (#8483) 2023-06-05 20:02:11 +00:00
dependabot[bot]
824f3802b2 Bump io.realm:realm-gradle-plugin from 10.15.1 to 10.16.0 (#8499)
Bumps [io.realm:realm-gradle-plugin](https://github.com/realm/realm-java) from 10.15.1 to 10.16.0.
- [Changelog](https://github.com/realm/realm-java/blob/main/CHANGELOG.md)
- [Commits](https://github.com/realm/realm-java/compare/v10.15.1...v10.16.0)

---
updated-dependencies:
- dependency-name: io.realm:realm-gradle-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-05 08:27:17 +00:00
Weblate
97eb2330c6 Merge branch 'origin/develop' into Weblate. 2023-06-03 11:07:32 +00:00
Ihor Hordiichuk
47da9c4534 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (2636 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/
2023-06-03 11:07:31 +00:00
Besnik Bleta
6c353d96a5 Translated using Weblate (Albanian)
Currently translated at 99.4% (2621 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sq/
2023-06-03 11:07:31 +00:00
Jozef Gaal
840ca30d8a Translated using Weblate (Slovak)
Currently translated at 100.0% (2636 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sk/
2023-06-03 11:07:30 +00:00
raspin0
9007fafdf2 Translated using Weblate (Polish)
Currently translated at 100.0% (2636 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/pl/
2023-06-03 11:07:30 +00:00
Glandos
4965be9961 Translated using Weblate (French)
Currently translated at 100.0% (2636 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fr/
2023-06-03 11:07:30 +00:00
Danial Behzadi
29d1d5e4b7 Translated using Weblate (Persian)
Currently translated at 100.0% (2636 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fa/
2023-06-03 11:07:30 +00:00
Priit Jõerüüt
bb703f3935 Translated using Weblate (Estonian)
Currently translated at 100.0% (2636 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/et/
2023-06-03 11:07:29 +00:00
waclaw66
5a74572209 Translated using Weblate (Czech)
Currently translated at 100.0% (2636 of 2636 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/cs/
2023-06-03 11:07:29 +00:00
Valere
3c08fb637a version++ 2023-06-02 18:05:49 +02:00
Valere
9f797e49e9 Merge branch 'release/1.6.2' into main 2023-06-02 18:02:45 +02:00
Valere
8157ec7746 Merge branch 'release/1.6.2' into develop 2023-06-02 18:02:44 +02:00
Valere
632f316f8e Adding fastlane file for version 1.6.2 2023-06-02 18:02:01 +02:00
Valere
1e4f47bc52 Changelog for version 1.6.2 2023-06-02 18:01:49 +02:00
Valere
56ea316a22 Merge pull request #8488 from vector-im/feature/bca/bump_crypto_sdk_0.3.8
bump crypto sdk to 0.3.9
2023-06-02 15:32:45 +02:00
valere
91f507e6c4 revert sonarqube gradle plugin version 2023-06-02 14:27:57 +02:00
dependabot[bot]
7f8a19f194 Bump org.checkerframework:checker from 3.34.0 to 3.35.0 (#8497) 2023-06-02 09:59:16 +00:00
valere
ada8539898 Fix remove deprecated isReady() call 2023-06-02 11:28:53 +02:00
valere
688ae7d259 update change log 2023-06-02 11:28:53 +02:00
valere
be8f226948 bump to 0.3.9 2023-06-02 11:28:53 +02:00
valere
99b6c887d2 Add change log 2023-06-02 11:28:53 +02:00
valere
1eda087233 bump crypto sdk to 0.3.8 2023-06-02 11:28:53 +02:00
Weblate
2d68c06698 Merge branch 'origin/develop' into Weblate. 2023-06-02 09:07:33 +00:00
raspin0
0965050ec9 Translated using Weblate (Polish)
Currently translated at 100.0% (99 of 99 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/pl/
2023-06-02 09:07:30 +00:00
waclaw66
e976ddde34 Translated using Weblate (Czech)
Currently translated at 100.0% (2634 of 2634 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/cs/
2023-06-02 09:07:28 +00:00
Hugh Nimmo-Smith
61d4e468cb Support for stable MSC3882 (#8299) 2023-06-01 18:15:01 +02:00
Valere
2f1a7b76ad Merge pull request #8485 from vector-im/feature/bca/fix_anrs
Make cryptoDevice calls suspendable
2023-06-01 16:36:29 +02:00
Benoit Marty
f741c4e7d9 Merge pull request #8463 from vector-im/dla/feature/always_allow_signout
Always allow users sign out
2023-06-01 14:55:39 +02:00
dependabot[bot]
cb0fb63fe6 Bump org.sonarsource.scanner.gradle:sonarqube-gradle-plugin (#8490) 2023-06-01 11:21:27 +00:00
Weblate
b96140f668 Merge branch 'origin/develop' into Weblate. 2023-05-31 19:07:39 +00:00
Besnik Bleta
4371ba48cb Translated using Weblate (Albanian)
Currently translated at 100.0% (99 of 99 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/sq/
2023-05-31 19:07:36 +00:00
waclaw66
ae4c3b078b Translated using Weblate (Czech)
Currently translated at 100.0% (99 of 99 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/cs/
2023-05-31 19:07:34 +00:00
Jeff Huang
957e89bbfd Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (99 of 99 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/zh_Hant/
2023-05-31 19:07:32 +00:00
LinAGKar
f92f87ce08 Translated using Weblate (Swedish)
Currently translated at 100.0% (99 of 99 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/sv/
2023-05-31 19:07:30 +00:00
LinAGKar
3292a07d3a Translated using Weblate (Swedish)
Currently translated at 100.0% (2634 of 2634 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sv/
2023-05-31 19:07:28 +00:00
valere
7e6376bf90 remove log 2023-05-31 15:14:28 +02:00
valere
8c1938987b Code review 2023-05-31 12:18:27 +02:00
valere
dc969f502a ktlint 2023-05-31 10:55:56 +02:00
valere
2d335c1307 fix unit test 2023-05-31 10:42:46 +02:00
valere
b59068b463 missing suspend 2023-05-31 09:52:43 +02:00
valere
268cbb83cd Make cryptoDevice calls suspendable 2023-05-30 23:47:50 +02:00
dependabot[bot]
7e1659b1f9 Bump androidx.activity:activity-ktx from 1.7.1 to 1.7.2 (#8465) 2023-05-30 12:40:02 +00:00
Valere
83795344ed Merge pull request #8470 from vector-im/feature/bca/extract_common_crypto
Extract common crypto interface for all flavors
2023-05-30 09:09:30 +02:00
Weblate
d1fa9050ca Merge branch 'origin/develop' into Weblate. 2023-05-28 17:08:34 +00:00
raspin0
9409f47bcb Translated using Weblate (Polish)
Currently translated at 98.9% (98 of 99 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/pl/
2023-05-28 17:07:45 +00:00
Linerly
c53ec382e5 Translated using Weblate (Indonesian)
Currently translated at 100.0% (99 of 99 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/id/
2023-05-28 17:07:43 +00:00
Danial Behzadi
f5eb78612f Translated using Weblate (Persian)
Currently translated at 100.0% (99 of 99 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/fa/
2023-05-28 17:07:41 +00:00
random
ba15aa11f2 Translated using Weblate (Italian)
Currently translated at 100.0% (99 of 99 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/it/
2023-05-28 17:07:39 +00:00
Priit Jõerüüt
d7b621f9d8 Translated using Weblate (Estonian)
Currently translated at 100.0% (99 of 99 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/et/
2023-05-28 17:07:37 +00:00
Ihor Hordiichuk
09580af844 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (99 of 99 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/uk/
2023-05-28 17:07:35 +00:00
Jozef Gaal
d1f82ab2b9 Translated using Weblate (Slovak)
Currently translated at 100.0% (99 of 99 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/sk/
2023-05-28 17:07:33 +00:00
Glandos
9c9fecc97d Translated using Weblate (French)
Currently translated at 100.0% (99 of 99 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/fr/
2023-05-28 17:07:31 +00:00
Vri
0736c9ede5 Translated using Weblate (German)
Currently translated at 100.0% (99 of 99 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/de/
2023-05-28 17:07:29 +00:00
Priit Jõerüüt
ac705151e9 Translated using Weblate (Estonian)
Currently translated at 100.0% (2634 of 2634 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/et/
2023-05-28 17:07:27 +00:00
valere
b37eca4520 fix rust crypto still need CryptoMetadataEntity for global pref 2023-05-26 18:22:47 +02:00
Alex Maras
24b18847b5 Fix animated webp playback (#8120)
* fix: add webp as playable image type

* fix: make glide transformations optional to prevent rendering webp throwing exception

* fix: stop marking webp as playable by default

* fix: play animated Webp in attachment view

* feat: autoplay webp if autoplay is enabled

---------

Signed-off-by: Alex Maras <dev@alexmaras.com>
Co-authored-by: Jorge Martín <jorgem@element.io>
2023-05-26 17:03:24 +02:00
valere
ac916078bc fix test compilation 2023-05-26 16:04:25 +02:00
Weblate
41b803980c Merge branch 'origin/develop' into Weblate. 2023-05-26 13:07:36 +00:00
random
0316582537 Translated using Weblate (Italian)
Currently translated at 100.0% (98 of 98 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/it/
2023-05-26 13:07:34 +00:00
Jeff Huang
e7584d37bb Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (2634 of 2634 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hant/
2023-05-26 13:07:32 +00:00
Ihor Hordiichuk
36a2e6e11c Translated using Weblate (Ukrainian)
Currently translated at 100.0% (2634 of 2634 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/
2023-05-26 13:07:32 +00:00
Besnik Bleta
64c47a6e6c Translated using Weblate (Albanian)
Currently translated at 99.4% (2619 of 2634 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sq/
2023-05-26 13:07:32 +00:00
Jozef Gaal
c039d62e5e Translated using Weblate (Slovak)
Currently translated at 100.0% (2634 of 2634 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sk/
2023-05-26 13:07:31 +00:00
raspin0
8ecd03d584 Translated using Weblate (Polish)
Currently translated at 100.0% (2634 of 2634 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/pl/
2023-05-26 13:07:31 +00:00
random
72956bda64 Translated using Weblate (Italian)
Currently translated at 100.0% (2634 of 2634 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/it/
2023-05-26 13:07:30 +00:00
Linerly
1fd2f78f4d Translated using Weblate (Indonesian)
Currently translated at 100.0% (2634 of 2634 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/id/
2023-05-26 13:07:30 +00:00
Glandos
ac235fa1db Translated using Weblate (French)
Currently translated at 100.0% (2634 of 2634 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fr/
2023-05-26 13:07:30 +00:00
Danial Behzadi
13bdd10a69 Translated using Weblate (Persian)
Currently translated at 100.0% (2634 of 2634 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fa/
2023-05-26 13:07:29 +00:00
Vri
882fb58a7d Translated using Weblate (German)
Currently translated at 100.0% (2634 of 2634 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/de/
2023-05-26 13:07:29 +00:00
waclaw66
9481221140 Translated using Weblate (Czech)
Currently translated at 100.0% (2634 of 2634 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/cs/
2023-05-26 13:07:29 +00:00
Chris Smith
37429c277b Show correct details when a poll is ended.
Previously, the "end poll" timeline item always showed the title
and options from the start event, regardless of whether any edits
had been made.

Now we show the latest edit, if available, falling back to the
original otherwise.
2023-05-26 12:06:41 +01:00
valere
a2ef95584f Add changelog 2023-05-26 10:17:48 +02:00
valere
3bf5c0cc1b Extract common crypto interface for all flavors 2023-05-26 09:50:15 +02:00
Benoit Marty
8f69e411d7 version++ 2023-05-25 11:22:07 +02:00
Benoit Marty
e961a8ccb5 Merge tag 'v1.6.1' into develop
tag
2023-05-25 11:20:39 +02:00
Benoit Marty
b9cc1b6dab Merge branch 'release/1.6.1' into main 2023-05-25 11:20:18 +02:00
Benoit Marty
93e2d7d176 Adding fastlane file for version 1.6.1 2023-05-25 11:18:34 +02:00
Benoit Marty
f261a903f0 Changelog for version 1.6.1 2023-05-25 11:18:08 +02:00
Benoit Marty
82748591f9 Setting version for the release 1.6.1 2023-05-25 11:05:07 +02:00
Benoit Marty
997c9dd917 Ensure signout service is always use even if users want to ignore sigout error from the server. The SDK is doing more cleanup. 2023-05-25 10:38:08 +02:00
Benoit Marty
cff9fbd008 Merge pull request #8439 from vector-im/yostyle/fix_crash_on_start_verification
Allow stateloss on verification dialogfragment
2023-05-25 09:36:40 +02:00
Weblate
43692c1da8 Merge branch 'origin/develop' into Weblate. 2023-05-24 20:08:03 +00:00
raspin0
287bff473d Translated using Weblate (Polish)
Currently translated at 100.0% (98 of 98 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/pl/
2023-05-24 20:08:01 +00:00
Besnik Bleta
d26d7f124b Translated using Weblate (Albanian)
Currently translated at 100.0% (98 of 98 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/sq/
2023-05-24 20:07:59 +00:00
Linerly
390377480c Translated using Weblate (Indonesian)
Currently translated at 100.0% (98 of 98 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/id/
2023-05-24 20:07:57 +00:00
waclaw66
7cff46d271 Translated using Weblate (Czech)
Currently translated at 100.0% (98 of 98 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/cs/
2023-05-24 20:07:55 +00:00
Peter Chen
1058f4b91d Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (98 of 98 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/zh_Hant/
2023-05-24 20:07:53 +00:00
Danial Behzadi
8eee238220 Translated using Weblate (Persian)
Currently translated at 100.0% (98 of 98 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/fa/
2023-05-24 20:07:51 +00:00
Priit Jõerüüt
b1b784de9f Translated using Weblate (Estonian)
Currently translated at 100.0% (98 of 98 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/et/
2023-05-24 20:07:49 +00:00
Ihor Hordiichuk
8447e06b21 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (98 of 98 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/uk/
2023-05-24 20:07:47 +00:00
LinAGKar
580f979c05 Translated using Weblate (Swedish)
Currently translated at 100.0% (98 of 98 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/sv/
2023-05-24 20:07:45 +00:00
Jozef Gaal
cffd6e80d0 Translated using Weblate (Slovak)
Currently translated at 100.0% (98 of 98 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/sk/
2023-05-24 20:07:43 +00:00
Glandos
d6302d3b9b Translated using Weblate (French)
Currently translated at 100.0% (98 of 98 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/fr/
2023-05-24 20:07:41 +00:00
Vri
d78d07b42a Translated using Weblate (German)
Currently translated at 100.0% (98 of 98 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/de/
2023-05-24 20:07:39 +00:00
Jeff Huang
7e748f28e8 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (2631 of 2631 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hant/
2023-05-24 20:07:37 +00:00
ang yong en
900828f57d Translated using Weblate (Chinese (Simplified))
Currently translated at 97.8% (2574 of 2631 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hans/
2023-05-24 20:07:36 +00:00
phardyle
d5794441d6 Translated using Weblate (Chinese (Simplified))
Currently translated at 97.8% (2574 of 2631 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hans/
2023-05-24 20:07:36 +00:00
Ihor Hordiichuk
09c70c99fa Translated using Weblate (Ukrainian)
Currently translated at 100.0% (2631 of 2631 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/
2023-05-24 20:07:36 +00:00
LinAGKar
0391f77623 Translated using Weblate (Swedish)
Currently translated at 100.0% (2631 of 2631 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sv/
2023-05-24 20:07:35 +00:00
Besnik Bleta
3848982c07 Translated using Weblate (Albanian)
Currently translated at 99.3% (2615 of 2631 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sq/
2023-05-24 20:07:35 +00:00
Jozef Gaal
d409a33f92 Translated using Weblate (Slovak)
Currently translated at 100.0% (2631 of 2631 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sk/
2023-05-24 20:07:34 +00:00
Daimar Stein
671f846f53 Translated using Weblate (Portuguese (Brazil))
Currently translated at 98.2% (2584 of 2631 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/pt_BR/
2023-05-24 20:07:34 +00:00
Bruno
17a3ea3148 Translated using Weblate (Portuguese (Brazil))
Currently translated at 98.2% (2584 of 2631 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/pt_BR/
2023-05-24 20:07:34 +00:00
raspin0
baccb84efb Translated using Weblate (Polish)
Currently translated at 100.0% (2631 of 2631 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/pl/
2023-05-24 20:07:33 +00:00
Linerly
36db0ac8d6 Translated using Weblate (Indonesian)
Currently translated at 100.0% (2631 of 2631 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/id/
2023-05-24 20:07:33 +00:00
Glandos
1996df2f93 Translated using Weblate (French)
Currently translated at 100.0% (2631 of 2631 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fr/
2023-05-24 20:07:32 +00:00
Tuomas Hietala
8fc5d73f75 Translated using Weblate (Finnish)
Currently translated at 84.0% (2212 of 2631 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fi/
2023-05-24 20:07:32 +00:00
Danial Behzadi
541690605f Translated using Weblate (Persian)
Currently translated at 100.0% (2631 of 2631 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fa/
2023-05-24 20:07:28 +00:00
Priit Jõerüüt
19ba773df9 Translated using Weblate (Estonian)
Currently translated at 100.0% (2631 of 2631 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/et/
2023-05-24 20:07:27 +00:00
Vri
72b2b591e3 Translated using Weblate (German)
Currently translated at 100.0% (2631 of 2631 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/de/
2023-05-24 20:07:27 +00:00
waclaw66
0edea016b1 Translated using Weblate (Czech)
Currently translated at 100.0% (2631 of 2631 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/cs/
2023-05-24 20:07:26 +00:00
Zet
bf244f6805 Translated using Weblate (Arabic)
Currently translated at 39.3% (1034 of 2631 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/ar/
2023-05-24 20:07:26 +00:00
dependabot[bot]
d5d5c9009b Bump io.element.android:wysiwyg from 1.2.2 to 2.2.1 (#8464)
* Bump io.element.android:wysiwyg from 1.2.2 to 2.2.1

Bumps [io.element.android:wysiwyg](https://github.com/matrix-org/matrix-wysiwyg) from 1.2.2 to 2.2.1.
- [Changelog](https://github.com/matrix-org/matrix-rich-text-editor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/matrix-org/matrix-wysiwyg/compare/1.2.2...2.2.1)

---
updated-dependencies:
- dependency-name: io.element.android:wysiwyg
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* Fix compilation

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: jonnyandrew <jonnya@element.io>
2023-05-24 10:14:22 +00:00
Valere
e4e4c2940b Merge pull request #8441 from vector-im/feature/bca/more_migration_logs
Add more migration logs
2023-05-24 10:11:08 +02:00
Valere
6da05a3804 Merge pull request #8462 from vector-im/feature/bca/fix_8445
Special text for re-verification after update
2023-05-24 10:10:52 +02:00
Valere
9f3255dd78 Merge pull request #8458 from vector-im/feature/bca/remove_legacy_per_device_verif
Remove legacy manually verify specific other device
2023-05-24 01:09:29 +02:00
valere
bb59a758cf code review 2023-05-24 00:06:36 +02:00
Valere
591b08f1ff Merge pull request #8461 from vector-im/feature/bca/fix_several_anr
Fix several app non responsive issues
2023-05-23 18:32:13 +02:00
David Langley
cee6ec5939 Always allow users sign out
- Updates the dialog with a more helpful error message for the user, letting them know what happens if they logout without informing the homeserver.
2023-05-23 16:51:26 +01:00
Valere
df1641995e Merge pull request #8457 from vector-im/feature/bca/fix_bad_device_list
fix always returning live devices for current user
2023-05-23 14:58:10 +02:00
valere
27f9be5eda Special text for re-verification after update 2023-05-23 13:08:14 +02:00
valere
19dc812719 add changelog 2023-05-23 11:01:08 +02:00
Jorge Martin Espinosa
bb09bee641 Merge pull request #8459 from vector-im/dependabot/gradle/com.likethesalad.android-stem-plugin-2.4.1
Bump com.likethesalad.android:stem-plugin from 2.4.0 to 2.4.1
2023-05-23 10:39:55 +02:00
valere
2ea6cdba6f Fix app non responsive 2023-05-23 08:30:58 +02:00
valere
b98d6ca55b Add changelog 2023-05-23 08:08:02 +02:00
dependabot[bot]
ccf77eb05a Bump com.likethesalad.android:stem-plugin from 2.4.0 to 2.4.1
Bumps com.likethesalad.android:stem-plugin from 2.4.0 to 2.4.1.

---
updated-dependencies:
- dependency-name: com.likethesalad.android:stem-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-22 23:59:34 +00:00
valere
94956a2ec6 Add change log 2023-05-22 22:37:37 +02:00
valere
517af968e6 Remove legacy manually verify specific other device 2023-05-22 22:26:26 +02:00
valere
705b17e7f1 fix always returning live devices for current user 2023-05-22 19:26:05 +02:00
Weblate
7ccbaf9ec8 Merge branch 'origin/develop' into Weblate. 2023-05-20 10:34:12 +00:00
someone1611
0e9b62a43a Translated using Weblate (Vietnamese)
Currently translated at 83.0% (2182 of 2628 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/vi/
2023-05-20 10:34:11 +00:00
Jeff Huang
3e8eeac533 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (2628 of 2628 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hant/
2023-05-20 10:34:06 +00:00
Ihor Hordiichuk
d5c98414a4 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (2628 of 2628 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/
2023-05-20 10:34:06 +00:00
Besnik Bleta
16f8f01cdb Translated using Weblate (Albanian)
Currently translated at 99.3% (2612 of 2628 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sq/
2023-05-20 10:34:05 +00:00
Jozef Gaal
6412c2a7ce Translated using Weblate (Slovak)
Currently translated at 100.0% (2628 of 2628 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sk/
2023-05-20 10:34:05 +00:00
raspin0
d79df5a0cb Translated using Weblate (Polish)
Currently translated at 100.0% (2628 of 2628 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/pl/
2023-05-20 10:34:05 +00:00
random
872fef6d22 Translated using Weblate (Italian)
Currently translated at 100.0% (2628 of 2628 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/it/
2023-05-20 10:34:05 +00:00
Linerly
fe37d63149 Translated using Weblate (Indonesian)
Currently translated at 100.0% (2628 of 2628 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/id/
2023-05-20 10:34:04 +00:00
Glandos
c98598eed1 Translated using Weblate (French)
Currently translated at 100.0% (2628 of 2628 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fr/
2023-05-20 10:34:04 +00:00
Danial Behzadi
a3bbe0bd8c Translated using Weblate (Persian)
Currently translated at 100.0% (2628 of 2628 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fa/
2023-05-20 10:34:04 +00:00
Priit Jõerüüt
a7130f63ea Translated using Weblate (Estonian)
Currently translated at 100.0% (2628 of 2628 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/et/
2023-05-20 10:34:04 +00:00
Vri
1659675d3b Translated using Weblate (German)
Currently translated at 100.0% (2628 of 2628 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/de/
2023-05-20 10:34:03 +00:00
waclaw66
6752c69c22 Translated using Weblate (Czech)
Currently translated at 100.0% (2628 of 2628 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/cs/
2023-05-20 10:34:03 +00:00
jonnyandrew
3157a35b74 Add autocomplete to plain text composer 2023-05-18 13:09:35 +01:00
jonnyandrew
24614bbbae Add changelog 2023-05-18 13:09:34 +01:00
jonnyandrew
29d8845792 Add slash commands to rich text editor 2023-05-18 13:09:34 +01:00
jonnyandrew
2d1dcd34c0 Add mentions to rich text editor 2023-05-18 13:09:26 +01:00
Benoit Marty
aecdd475d8 Update the release script to release the flavor rustCrypto - small revert 2023-05-17 16:37:08 +02:00
Benoit Marty
66aa4226b5 version++ 2023-05-17 14:55:30 +02:00
Benoit Marty
4ca67022e6 Merge tag 'v1.6.0' into develop
v1.6.0
2023-05-17 14:54:24 +02:00
valere
6e27ffc3cf Add more migration logs 2023-05-17 12:41:11 +02:00
yostyle
d6028b75c9 Add changelog 2023-05-17 11:17:54 +02:00
yostyle
dadad3501b Allow stateloss on verification dialogfragment 2023-05-17 11:10:42 +02:00
281 changed files with 8548 additions and 1505 deletions

View File

@@ -1,7 +1,7 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
@@ -13,7 +13,7 @@ updates:
reviewers:
- "vector-im/element-android-reviewers"
ignore:
- dependency-name: "*github-script*"
- dependency-name: "*"
# Updates for Gradle dependencies used in the app
- package-ecosystem: gradle
directory: "/"
@@ -22,5 +22,6 @@ updates:
open-pull-requests-limit: 200
reviewers:
- "vector-im/element-android-reviewers"
ignore:
- dependency-name: com.google.zxing:core
allow:
- dependency-name: "io.element.android:wysiwyg"
- dependency-name: "org.matrix.rustcomponents:crypto-android"

View File

@@ -15,3 +15,11 @@ jobs:
project: Issue triage
column: Incoming
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
triage-new-issues:
runs-on: ubuntu-latest
steps:
- uses: actions/add-to-project@main
with:
project-url: https://github.com/orgs/vector-im/projects/91
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}

View File

@@ -1,3 +1,76 @@
Changes in Element v1.6.5 (2023-07-25)
======================================
Bugfixes 🐛
----------
- Fix several crashes observed when the device cannot reach the homeserver ([#8578](https://github.com/vector-im/element-android/issues/8578))
Other changes
-------------
- Update MSC3912 implementation: Redaction of related events ([#8481](https://github.com/vector-im/element-android/issues/8481))
- Include some source code in our project to remove our dependency to artifact hosted by bintray (Jcenter). ([#8556](https://github.com/vector-im/element-android/issues/8556))
Changes in Element v1.6.3 (2023-06-27)
======================================
Features ✨
----------
- **Element Android is now using the Crypto Rust SDK**. Migration of user's data should be done at first launch after application upgrade. ([#8390](https://github.com/vector-im/element-android/issues/8390))
- [Rich text editor] Add mentions and slash commands ([#8440](https://github.com/vector-im/element-android/issues/8440))
Bugfixes 🐛
----------
- Update rich text editor library to support pasting of images. ([#8270](https://github.com/vector-im/element-android/issues/8270))
- Fix | Got asked twice about verification #8353 (and other verification banners problems) ([#8353](https://github.com/vector-im/element-android/issues/8353))
- Prompt the user when the invited MatrixId is not recognized ([#8468](https://github.com/vector-im/element-android/issues/8468))
- The correct title and options are now displayed When a poll that was edited is ended. ([#8471](https://github.com/vector-im/element-android/issues/8471))
- In some conditions the room shield is not refreshed correctly ([#8507](https://github.com/vector-im/element-android/issues/8507))
- Fix crypto config fallback key sharing strategy ([#8541](https://github.com/vector-im/element-android/issues/8541))
Other changes
-------------
- MSC3987 implementation: the 'dont_notify' action for a push_rule is now deprecated and replaced by an empty action list. ([#8503](https://github.com/vector-im/element-android/issues/8503))
- Update crypto rust sdk version to 0.3.10 ([#8554](https://github.com/vector-im/element-android/issues/8554))
Changes in Element v1.6.2 (2023-06-02)
======================================
Features ✨
----------
- **Element Android is now using the Crypto Rust SDK**. Migration of user's data should be done at first launch after application upgrade. ([#8390](https://github.com/vector-im/element-android/issues/8390))
- Marks WebP files as Animated and allows them to play ([#8120](https://github.com/vector-im/element-android/issues/8120))
- Updates to protocol used for Sign in with QR code ([#8299](https://github.com/vector-im/element-android/issues/8299))
- Updated rust crypto SDK to version 0.3.9 ([#8488](https://github.com/vector-im/element-android/issues/8488))
Bugfixes 🐛
----------
- Fix: Allow users to sign out even if the sign out request fails. ([#4855](https://github.com/vector-im/element-android/issues/4855))
- fix: Make some crypto calls suspendable to avoid reported ANR ([#8482](https://github.com/vector-im/element-android/issues/8482))
Other changes
-------------
- Refactoring: Extract a new interface for common access to crypto store between kotlin and rust crypto ([#8470](https://github.com/vector-im/element-android/issues/8470))
Changes in Element v1.6.1 (2023-05-25)
======================================
Corrective release for 1.6.0
Bugfixes 🐛
----------
- Allow stateloss on verification dialogfragment ([#8439](https://github.com/vector-im/element-android/issues/8439))
- Fix: Update verification popup text when a re-verification is needed after rust migration (read only sessions) ([#8445](https://github.com/vector-im/element-android/issues/8445))
- Fix several performance issues causing app non responsive issues. ([#8454](https://github.com/vector-im/element-android/issues/8454))
- Fix: The device list screen from the member profile page was always showing the current user devices (rust crypto). ([#8457](https://github.com/vector-im/element-android/issues/8457))
Other changes
-------------
- Remove UI option to manually verify a specific device of another user (deprecated behaviour) ([#8458](https://github.com/vector-im/element-android/issues/8458))
Changes in Element v1.6.0 (2023-05-17)
======================================

View File

@@ -28,7 +28,7 @@ buildscript {
classpath 'com.google.gms:google-services:4.3.15'
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:4.0.0.2929'
classpath 'com.google.android.gms:oss-licenses-plugin:0.10.6'
classpath "com.likethesalad.android:stem-plugin:2.4.0"
classpath "com.likethesalad.android:stem-plugin:2.4.1"
classpath 'org.owasp:dependency-check-gradle:8.2.1'
classpath "org.jetbrains.dokka:dokka-gradle-plugin:1.8.10"
classpath "org.jetbrains.kotlinx:kotlinx-knit:0.4.0"
@@ -112,16 +112,6 @@ allprojects {
groups.google.group.each { includeGroup it }
}
}
//noinspection JcenterRepositoryObsolete
// Do not use `jcenter`, it prevents Dependabot from working properly
maven {
url 'https://jcenter.bintray.com'
content {
groups.jcenter.regex.each { includeGroupByRegex it }
groups.jcenter.group.each { includeGroup it }
}
}
maven {
url 'https://s01.oss.sonatype.org/content/repositories/snapshots'
content {
@@ -129,7 +119,6 @@ allprojects {
groups.mavenSnapshots.group.each { includeGroup it }
}
}
}
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {

View File

@@ -47,7 +47,7 @@ ext.libs = [
'coroutinesTest' : "org.jetbrains.kotlinx:kotlinx-coroutines-test:$kotlinCoroutines"
],
androidx : [
'activity' : "androidx.activity:activity-ktx:1.7.1",
'activity' : "androidx.activity:activity-ktx:1.7.2",
'appCompat' : "androidx.appcompat:appcompat:1.6.1",
'biometric' : "androidx.biometric:biometric:1.1.0",
'core' : "androidx.core:core-ktx:1.10.1",
@@ -101,7 +101,7 @@ ext.libs = [
],
element : [
'opusencoder' : "io.element.android:opusencoder:1.1.0",
'wysiwyg' : "io.element.android:wysiwyg:1.2.2"
'wysiwyg' : "io.element.android:wysiwyg:2.2.2"
],
squareup : [
'moshi' : "com.squareup.moshi:moshi:$moshi",
@@ -172,6 +172,7 @@ ext.libs = [
'kluent' : "org.amshove.kluent:kluent-android:1.73",
'timberJunitRule' : "net.lachlanmckee:timber-junit-rule:1.0.1",
'junit' : "junit:junit:4.13.2",
'robolectric' : "org.robolectric:robolectric:4.9",
]
]

View File

@@ -115,6 +115,7 @@ ext.groups = [
'com.linkedin.dexmaker',
'com.mapbox.mapboxsdk',
'com.nulab-inc',
'com.otaliastudios',
'com.otaliastudios.opengl',
'com.parse.bolts',
'com.pinterest',
@@ -189,6 +190,7 @@ ext.groups = [
'org.codehaus.groovy',
'org.codehaus.mojo',
'org.codehaus.woodstox',
'org.conscrypt',
'org.eclipse.ee4j',
'org.ec4j.core',
'org.freemarker',
@@ -221,6 +223,7 @@ ext.groups = [
'org.ow2.asm',
'org.ow2.asm',
'org.reactivestreams',
'org.robolectric',
'org.slf4j',
'org.sonatype.oss',
'org.testng',
@@ -232,18 +235,4 @@ ext.groups = [
'xml-apis',
]
],
jcenter : [
regex: [
],
group: [
'com.amulyakhare',
'com.otaliastudios',
'com.yqritc',
// https://github.com/cmelchior/realmfieldnameshelper/issues/42
'dk.ilios',
'im.dlg',
'me.dm7.barcodescanner',
'me.gujun.android',
]
]
]

View File

@@ -0,0 +1,2 @@
Hlavní změny v této verzi: Element Android nyní používá Crypto Rust SDK.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Hlavní změny v této verzi: Element Android nyní používá Crypto Rust SDK.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Hlavní změny v této verzi: Element Android nyní používá Crypto Rust SDK.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Die wichtigsten Änderungen in dieser Version: Element Android nutzt nun das Crypto-Rust-SDK.
Vollständiges Änderungsprotokoll: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Die wichtigsten Änderungen in dieser Version: Element Android nutzt nun das Crypto-Rust-SDK.
Vollständiges Änderungsprotokoll: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Die wichtigsten Änderungen in dieser Version: Element Android nutzt nun das Crypto-Rust-SDK.
Vollständiges Änderungsprotokoll: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Main changes in this version: Element Android is now using the Crypto Rust SDK.
Full changelog: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Main changes in this version: Element Android is now using the Crypto Rust SDK.
Full changelog: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Main changes in this version: Element Android is now using the Crypto Rust SDK.
Full changelog: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Main changes in this version: corrective release.
Full changelog: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Põhilised muutused selles versioonis: Element Android krüptoteekideks on nüüd Crypto Rust SDK.
Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Põhilised muutused selles versioonis: Element Android krüptoteekideks on nüüd Crypto Rust SDK.
Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Põhilised muutused selles versioonis: Element Android krüptoteekideks on nüüd Crypto Rust SDK.
Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
تغییرات عمده در این نگارش: المنت اندروید اکنون از SDK راست Crypto استفاده می‌کند.
گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
تغییرات عمده در این نگارش: المنت اندروید اکنون از SDK راست Crypto استفاده می‌کند.
گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
تغییرات عمده در این نگارش: المنت اندروید اکنون از SDK راست Crypto استفاده می‌کند.
گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Principaux changements pour cette version : Element Android utilise désormais le SDK cryptographique en Rust.
Intégralité des changements : https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Principaux changements pour cette version : Element Android utilise désormais le SDK cryptographique en Rust.
Intégralité des changements : https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Principaux changements pour cette version : Element Android utilise désormais le SDK cryptographique en Rust.
Intégralité des changements : https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1 @@
Խմբային մեսինջեր - գաղտնագրված շփում, խմբային չատեր և վիդեո զանգեր

View File

@@ -0,0 +1 @@
Element - Անվտանգ Մեսինջեր

View File

@@ -0,0 +1,2 @@
Perubahan utama dalam versi ini: Element Android sekarang menggunakan SDK Kripto Rust.
Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Perubahan utama dalam versi ini: Element Android sekarang menggunakan SDK Kripto Rust.
Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Perubahan utama dalam versi ini: Element Android sekarang menggunakan SDK Kripto Rust.
Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Modifiche principali in questa versione: Element Android ora utilizza l'SDK Rust Crypto.
Cronologia completa: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Modifiche principali in questa versione: Element Android ora utilizza l'SDK Rust Crypto.
Cronologia completa: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Modifiche principali in questa versione: Element Android ora utilizza l'SDK Rust Crypto.
Cronologia completa: https://github.com/vector-im/element-android/releases

View File

@@ -1 +1 @@
Sikker desentralisert chat & VoIP. Beskytt dataene dine fra tredjeparter.
Gruppe-meldingsapp - krypterte meldinger, gruppechat og videosamtaler

View File

@@ -1 +1 @@
Element (tidligere Riot.im)
Element - Sikker Meldingsapp

View File

@@ -0,0 +1,2 @@
Główne zmiany w tej wersji: Element Android teraz korzysta z Crypto Rust SDK.
Pełna lista zmian: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Główne zmiany w tej wersji: Element Android teraz korzysta z Crypto Rust SDK.
Pełna lista zmian: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Główne zmiany w tej wersji: Element Android teraz korzysta z Crypto Rust SDK.
Pełna lista zmian: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Главные изменения этой версии: Element для Android теперь использует Crypto Rust SDK.
Полный список изменений: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Hlavné zmeny v tejto verzii: Element Android teraz používa Crypto Rust SDK.
Úplný zoznam zmien: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Hlavné zmeny v tejto verzii: Element Android teraz používa Crypto Rust SDK.
Úplný zoznam zmien: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Hlavné zmeny v tejto verzii: Element Android teraz používa Crypto Rust SDK.
Úplný zoznam zmien: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Ndryshimet kryesore në këtë version: Element Android tani përdor Crypto Rust SDK.
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Ndryshimet kryesore në këtë version: Element Android tanimë përdor SDK Rust Fshehtëzimesh.
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Ndryshimet kryesore në këtë version: Element Android tanimë përdor SDK Rust për Kripto.
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Huvudsakliga ändringar i den här versionen: Element Android använder nu Rust-krypto-SDK:t
Full ändringslogg: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Huvudsakliga ändringar i den här versionen: Element Android använder nu Rust-krypto-SDK:t
Full ändringslogg: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Huvudsakliga ändringar i den här versionen: Element Android använder nu Rust-krypto-SDK:t
Full ändringslogg: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Основні зміни в цій версії: Element Android тепер використовує Crypto Rust SDK.
Перелік усіх змін: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Основні зміни в цій версії: Element Android тепер використовує Crypto Rust SDK.
Перелік усіх змін: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Основні зміни в цій версії: Element Android тепер використовує Crypto Rust SDK.
Перелік усіх змін: https://github.com/vector-im/element-android/releases

View File

@@ -1,2 +1,2 @@
Những thay đổi chính trong phiên bản này: Thêm hỗ trợ Android Auto. Sửa rất nhiều lỗi!
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.3.2
Thay đổi chính trong phiên bản này: Hỗ trợ Android Auto. Sửa rất nhiều lỗi!
Toàn bộ nhật ký sửa đổi: https://github.com/vector-im/element-android/releases/tag/v1.3.2

View File

@@ -1,2 +1,2 @@
Những thay đổi chính trong phiên bản này: Hiển thị (các) chính sách máy chủ xác thực trong phần cài đặt. Tạm thời bỏ hỗ trợ Android Auto.
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.3.3
Thay đổi chính trong phiên bản này: Hiển thị (các) chính sách máy chủ định danh trong phần cài đặt. Tạm thời bỏ hỗ trợ Android Auto.
Toàn bộ nhật ký sửa đổi: https://github.com/vector-im/element-android/releases/tag/v1.3.3

View File

@@ -1,2 +1,2 @@
Những thay đổi chính trong phiên bản này: Thêm hỗ trợ hiển th, cho phòng Tin nhắn Trực tiếp (lưu ý: hiển th bị vô hiệu hóa trên matrix.org. Hỗ trợ Android Auto trở lại.
Nhật ký thay đổi: https://github.com/vector-im/element-android/releases/tag/v1.3.4
Thay đổi chính trong phiên bản này: Hỗ trợ trạng thái, cho các phòng nhắn tin trực tiếp (ghi chú: trạng thái bị vô hiệu trên matrix.org). Hỗ trợ Android Auto trở lại.
Toàn bộ nhật ký sửa đổi: https://github.com/vector-im/element-android/releases/tag/v1.3.4

View File

@@ -0,0 +1,2 @@
Thay đổi chính trong phiên bản này: Hỗ trợ trạng thái, cho các phòng nhắn tin trực tiếp (ghi chú: trạng thái bị vô hiệu trên matrix.org). Hỗ trợ Android Auto trở lại.
Toàn bộ nhật ký sửa đổi: https://github.com/vector-im/element-android/releases/tag/v1.3.5

View File

@@ -0,0 +1,2 @@
Thay đổi chính trong phiên bản này: Hỗ trợ trạng thái, cho các phòng nhắn tin trực tiếp (ghi chú: trạng thái bị vô hiệu trên matrix.org). Hỗ trợ Android Auto trở lại.
Toàn bộ nhật ký sửa đổi: https://github.com/vector-im/element-android/releases/tag/v1.3.6

View File

@@ -0,0 +1,2 @@
Thay đổi chính trong phiên bản này: Sửa lỗi và cải thiện.
Toàn bộ nhật ký sửa đổi: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Thay đổi chính trong phiên bản này: Triển khai chế độ toàn màn hình mới cho trình soạn thảo văn bản phong phú và sửa lỗi.
Toàn bộ nhật ký sửa đổi: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Thay đổi chính trong phiên bản này: Triển khai chế độ toàn màn hình mới cho trình soạn thảo văn bản phong phú và sửa lỗi.
Toàn bộ nhật ký sửa đổi: https://github.com/vector-im/element-android/releases

View File

@@ -1,2 +1,2 @@
Thay đổi chính trong phiên bản này: Chức năng chủ đề được bật theo mặc định.
Toàn bộ nhật ký thay đổi: https://github.com/vector-im/element-android/releases
Toàn bộ nhật ký sửa đổi: https://github.com/vector-im/element-android/releases

View File

@@ -1,2 +1,2 @@
Thay đổi chính trong phiên bản này: Chức năng chủ đề được bật theo mặc định.
Toàn bộ nhật ký thay đổi: https://github.com/vector-im/element-android/releases
Toàn bộ nhật ký sửa đổi: https://github.com/vector-im/element-android/releases

View File

@@ -1,2 +1,2 @@
Thay đổi chính trong phiên bản này: Chức năng chủ đề được bật theo mặc định.
Toàn bộ nhật ký thay đổi: https://github.com/vector-im/element-android/releases
Toàn bộ nhật ký sửa đổi: https://github.com/vector-im/element-android/releases

View File

@@ -1,2 +1,2 @@
Thay đổi chính trong phiên bản này: Chức năng chủ đề được bật theo mặc định.
Toàn bộ nhật ký thay đổi: https://github.com/vector-im/element-android/releases
Toàn bộ nhật ký sửa đổi: https://github.com/vector-im/element-android/releases

View File

@@ -1,2 +1,2 @@
Thay đổi chính trong phiên bản này: Chức năng chủ đề được bật theo mặc định.
Toàn bộ nhật ký thay đổi: https://github.com/vector-im/element-android/releases
Toàn bộ nhật ký sửa đổi: https://github.com/vector-im/element-android/releases

View File

@@ -1,2 +1,2 @@
Thay đổi chính trong phiên bản này: Hầu hết là sửa lỗi.
Toàn bộ nhật ký thay đổi: https://github.com/vector-im/element-android/releases
Toàn bộ nhật ký sửa đổi: https://github.com/vector-im/element-android/releases

View File

@@ -1,2 +1,2 @@
Thay đổi chính trong phiên bản này: Hầu hết là cải thiện chức năng phát thanh.
Toàn bộ nhật ký thay đổi: https://github.com/vector-im/element-android/releases
Toàn bộ nhật ký sửa đổi: https://github.com/vector-im/element-android/releases

View File

@@ -1,2 +1,2 @@
Thay đổi chính trong phiên bản này: Hầu hết là sửa lỗi, cụ thể là sửa lỗi khiến cho tin nhắn không xuất hiện trên dòng thời gian.
Toàn bộ nhật ký thay đổi: https://github.com/vector-im/element-android/releases
Toàn bộ nhật ký sửa đổi: https://github.com/vector-im/element-android/releases

View File

@@ -1,2 +1,2 @@
Thay đổi chính trong phiên bản này: Hầu hết là sửa lỗi, cụ thể là sửa lỗi khiến cho tin nhắn không xuất hiện trên dòng thời gian.
Toàn bộ nhật ký thay đổi: https://github.com/vector-im/element-android/releases
Toàn bộ nhật ký sửa đổi: https://github.com/vector-im/element-android/releases

View File

@@ -1,2 +1,2 @@
Thay đổi chính trong phiên bản này: Chủ yếu là sửa lỗi.
Toàn bộ nhật ký thay đổi: https://github.com/vector-im/element-android/releases
Toàn bộ nhật ký sửa đổi: https://github.com/vector-im/element-android/releases

View File

@@ -1,2 +1,2 @@
Thay đổi chính trong phiên bản này: Chủ yếu là sửa lỗi.
Toàn bộ nhật ký thay đổi: https://github.com/vector-im/element-android/releases
Toàn bộ nhật ký sửa đổi: https://github.com/vector-im/element-android/releases

View File

@@ -1,2 +1,2 @@
Thay đổi chính trong phiên bản này: Liên kết cố định tới các phòng, spaces, người dùng và tin nhắn giờ được hiển thị hình viên thuốc. Chúng tôi cũng đã sửa một số vấn đề với những nhãn dãn (sticker) tùy chỉnh và thanh đánh dấu đã đọc bị kẹt ở quá khứ.
Toàn bộ nhật ký thay đổi: https://github.com/vector-im/element-android/releases
Toàn bộ nhật ký sửa đổi: https://github.com/vector-im/element-android/releases

View File

@@ -1,2 +1,2 @@
Thay đổi chính trong phiên bản này: Chủ yếu là sửa lỗi
Toàn bộ nhật ký thay đổi: https://github.com/vector-im/element-android/releases
Toàn bộ nhật ký sửa đổi: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Thay đổi chính trong phiên bản này: Element Android giờ dùng công cụ phát triển phần mềm Rust cho mã hóa
Toàn bộ nhật ký sửa đổi: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Thay đổi chính trong phiên bản này: Element Android giờ dùng công cụ phát triển phần mềm Rust cho mã hóa
Toàn bộ nhật ký sửa đổi: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Thay đổi chính trong phiên bản này: Element Android giờ dùng công cụ phát triển phần mềm Rust cho mã hóa
Toàn bộ nhật ký sửa đổi: https://github.com/vector-im/element-android/releases

View File

@@ -1,42 +1,42 @@
Element vừa là một ứng dụng nhắn tin bảo mật vừa là một ứng dụng cộng tác nhóm năng suất, lý tưởng cho các cuộc trò chuyện nhóm khi làm việc từ xa. Ứng dụng trò chuyện này sử dụng mã hóa đầu cuối để cung cấp tính năng hội thảo truyền hình, chia sẻ tệp và cuộc gọi thoại mạnh mẽ.
<b> Các tính năng của Element bao gồm: </b>
- Các công cụ giao tiếp trực tuyến tiên tiến
<b>Các tính năng của Element bao gồm:</b>
- Công cụ giao tiếp trực tuyến nâng cao
- Các tin nhắn được mã hóa hoàn toàn để cho phép liên lạc doanh nghiệp an toàn hơn, ngay cả đối với những người làm việc từ xa
- Trò chuyện phi tập trung dựa trên khung mã nguồn mở Matrix
- Chia sẻ tệp một cách an toàn với dữ liệu được mã hóa trong khi quản lý dự án
- Trò chuyện video với gọi thoại qua giao thức Internet (IP - VoIP) và chia sẻ màn hình
- Chia sẻ tệp bảo mật với dữ liệu được mã hóa trong khi quản lý dự án
- Trò chuyện video với gọi thoại qua giao thức Internet (VoIP) và chia sẻ màn hình
- Tích hợp dễ dàng với các công cụ cộng tác trực tuyến yêu thích của bạn, công cụ quản lý dự án, dịch vụ VoIP và các ứng dụng nhắn tin nhóm khác
Element hoàn toàn khác với các ứng dụng nhắn tin và cộng tác khác. Hoạt động trên Matrix, một mạng mở để nhắn tin bảo mật và giao tiếp phi tập trung. Đồng thời, cho phép tự lưu trữ để cung cấp cho người dùng quyền sở hữu và kiểm soát tối đa dữ liệu và tin nhắn của họ.
Element hoàn toàn khác với các ứng dụng nhắn tin và cộng tác khác. Hoạt động trên Matrix, một mạng mở để nhắn tin bảo mật và giao tiếp phi tập trung. Đồng thời, cho phép tự vận hành để cung cấp cho người dùng quyền sở hữu và kiểm soát tối đa dữ liệu và tin nhắn của họ.
<b> Nhắn tin mã hóa và riêng tư </b>
Element bảo vệ bạn khỏi các quảng cáo không mong muốn, khai thác dữ liệu và kiểm soát khu vực. Element cũng bảo mật tất cả dữ liệu của bạn, video 1-1 và giao tiếp thoại thông qua mã hóa đầu cuối và xác minh thiết bị có chữ ký chéo.
<b>Nhắn tin mã hóa và riêng tư</b>
Element bảo vệ bạn khỏi các quảng cáo không mong muốn, khai thác dữ liệu và kiểm soát khu vực. Element cũng bảo mật tất cả dữ liệu của bạn, truyền hình 1-1 và giao tiếp thoại thông qua mã hóa đầu cuối và xác thực chéo thiết bị.
Element cung cấp cho bạn quyền kiểm soát quyền riêng tư của mình đồng thời cho phép bạn giao tiếp an toàn với bất kỳ ai trên mạng Matrix hoặc các công cụ cộng tác kinh doanh khác bằng cách tích hợp với các ứng dụng như Slack.
Element cung cấp cho bạn quyền kiểm soát quyền riêng tư của mình đồng thời cho phép bạn giao tiếp bảo mật với bất kỳ ai trên mạng Matrix hoặc các công cụ cộng tác kinh doanh khác bằng cách tích hợp với các ứng dụng như Slack.
<b> Element có thể được tự lưu trữ </b>
Để cho phép kiểm soát nhiều hơn dữ liệu nhạy cảm và các cuộc trò chuyện của bạn, Element có thể được tự lưu trữ hoặc bạn có thể chọn bất kỳ máy chủ Matrix nào - tiêu chuẩn cho giao tiếp phi tập trung, mã nguồn mở. Element cung cấp cho bạn quyền riêng tư, tuân thủ bảo mật và tính linh hoạt trong tích hợp.
<b>Element có thể được tự vận hành</b>
Để cho phép kiểm soát nhiều hơn dữ liệu nhạy cảm và các cuộc trò chuyện của bạn, Element có thể được tự vận hành hoặc bạn có thể chọn bất kỳ máy chủ Matrix nào - tiêu chuẩn cho giao tiếp phi tập trung, mã nguồn mở. Element cung cấp cho bạn quyền riêng tư, tuân thủ bảo mật và tính linh hoạt trong tích hợp.
<b> Sở hữu dữ liệu của bạn </b>
Bạn quyết định nơi lưu giữ dữ liệu và tin nhắn của mình. Không có rủi ro khai thác dữ liệu hoặc truy cập từ bên thứ ba.
<b>Sở hữu dữ liệu của bạn</b>
Bạn quyết định nơi lưu trữ dữ liệu và tin nhắn của mình. Không có rủi ro khai thác dữ liệu hoặc truy cập từ bên thứ ba.
Element giúp bạn kiểm soát theo những cách khác nhau:
1. Tạo một tài khoản miễn phí trên máy chủ công cộng matrix.org do các nhà phát triển Matrix vận hành hoặc chọn từ hàng nghìn máy chủ công cộng do các tình nguyện viên lưu trữ
1. Tạo một tài khoản miễn phí trên máy chủ công cộng matrix.org do các nhà phát triển Matrix vận hành hoặc chọn từ hàng nghìn máy chủ công cộng do các tình nguyện viên vận hành
2. Tự lưu trữ tài khoản của bạn bằng cách chạy một máy chủ trên cơ sở hạ tầng CNTT của riêng bạn
3. Đăng ký tài khoản trên máy chủ tùy chỉnh bằng cách chỉ cần đăng ký nền tảng Element Matrix Services hosting
<b> Nhắn tin và cộng tác mở </b>
<b>Nhắn tin và cộng tác mở</b>
Bạn có thể trò chuyện với bất kỳ ai trên mạng Matrix, cho dù họ đang sử dụng Element, một ứng dụng Matrix khác hay ngay cả khi họ đang sử dụng một ứng dụng nhắn tin khác.
<b> Siêu bảo mật </b>
Mã hóa đầu-cuối thực (chỉ những người trong cuộc trò chuyện mới có thể giải mã tin nhắn) và xác minh thiết bị xác thực chéo.
<b>Siêu bảo mật</b>
Mã hóa đầu-cuối thực (chỉ những người trong cuộc trò chuyện mới có thể giải mã tin nhắn) và xác thực chéo thiết bị.
<b> Giao tiếp và tích hợp hoàn chỉnh </b>
Nhắn tin, cuộc gọi thoại và video, chia sẻ tệp, chia sẻ màn hình và một loạt các tích hợp, bot và widget. Xây dựng phòng, cộng đồng, giữ liên lạc và hoàn thành công việc.
<b>Giao tiếp và tích hợp hoàn chỉnh</b>
Nhắn tin, gọi thoại và truyền hình, chia sẻ tệp, chia sẻ màn hình và một loạt các tích hợp, bot và widget. Tạo phòng, cộng đồng, giữ liên lạc và hoàn thành công việc.
<b> Tiếp tục nơi bạn đã dừng lại </b>
<b>Tiếp tục nơi bạn đã dừng lạ </b>
Giữ liên lạc mọi lúc mọi nơi với lịch sử tin nhắn được đồng bộ hóa hoàn toàn trên tất cả các thiết bị của bạn và trên web tại https://app.element.io
<b> Mã nguồn mở </b>
Element Android là một dự án mã nguồn mở, được lưu trữ trên GitHub. Vui lòng báo cáo lỗi và / hoặc đóng góp phát triển tại https://github.com/vector-im/element-android
<b>Mã nguồn mở</b>
Element Android là một dự án mã nguồn mở, được lưu trữ trên GitHub. Vui lòng báo cáo lỗi và / hoặc đóng góp, phát triển tại https://github.com/vector-im/element-android

View File

@@ -0,0 +1,2 @@
此版本的主要變更現在起Element Android 使用 Crypto Rust SDK。
完整異動https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
此版本的主要變更現在起Element Android 使用 Crypto Rust SDK。
完整異動https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
此版本的主要變更現在起Element Android 使用 Crypto Rust SDK。
完整異動https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,32 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
android {
namespace "com.otaliastudios.autocomplete"
compileSdk versions.compileSdk
defaultConfig {
minSdk versions.minSdk
targetSdk versions.targetSdk
}
compileOptions {
sourceCompatibility versions.sourceCompat
targetCompatibility versions.targetCompat
}
kotlinOptions {
jvmTarget = "11"
}
}
dependencies {
implementation libs.androidx.recyclerview
}
afterEvaluate {
tasks.findAll { it.name.startsWith("lint") }.each {
it.enabled = false
}
}

View File

@@ -0,0 +1,434 @@
package com.otaliastudios.autocomplete;
import android.database.DataSetObserver;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Looper;
import android.text.Editable;
import android.text.Selection;
import android.text.SpanWatcher;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextWatcher;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.Window;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.PopupWindow;
import androidx.annotation.NonNull;
/**
* Entry point for adding Autocomplete behavior to a {@link EditText}.
*
* You can construct a {@code Autocomplete} using the builder provided by {@link Autocomplete#on(EditText)}.
* Building is enough, but you can hold a reference to this class to call its public methods.
*
* Requires:
* - {@link EditText}: this is both the anchor for the popup, and the source of text events that we listen to
* - {@link AutocompletePresenter}: this presents items in the popup window. See class for more info.
* - {@link AutocompleteCallback}: if specified, this listens to click events and visibility changes
* - {@link AutocompletePolicy}: if specified, this controls how and when to show the popup based on text events
* If not, this defaults to {@link SimplePolicy}: shows the popup when text.length() bigger than 0.
*/
public final class Autocomplete<T> implements TextWatcher, SpanWatcher {
private final static String TAG = Autocomplete.class.getSimpleName();
private final static boolean DEBUG = false;
private static void log(String log) {
if (DEBUG) Log.e(TAG, log);
}
/**
* Builder for building {@link Autocomplete}.
* The only mandatory item is a presenter, {@link #with(AutocompletePresenter)}.
*
* @param <T> the data model
*/
public final static class Builder<T> {
private EditText source;
private AutocompletePresenter<T> presenter;
private AutocompletePolicy policy;
private AutocompleteCallback<T> callback;
private Drawable backgroundDrawable;
private float elevationDp = 6;
private Builder(EditText source) {
this.source = source;
}
/**
* Registers the {@link AutocompletePresenter} to be used, responsible for showing
* items. See the class for info.
*
* @param presenter desired presenter
* @return this for chaining
*/
public Builder<T> with(AutocompletePresenter<T> presenter) {
this.presenter = presenter;
return this;
}
/**
* Registers the {@link AutocompleteCallback} to be used, responsible for listening to
* clicks provided by the presenter, and visibility changes.
*
* @param callback desired callback
* @return this for chaining
*/
public Builder<T> with(AutocompleteCallback<T> callback) {
this.callback = callback;
return this;
}
/**
* Registers the {@link AutocompletePolicy} to be used, responsible for showing / dismissing
* the popup when certain events happen (e.g. certain characters are typed).
*
* @param policy desired policy
* @return this for chaining
*/
public Builder<T> with(AutocompletePolicy policy) {
this.policy = policy;
return this;
}
/**
* Sets a background drawable for the popup.
*
* @param backgroundDrawable drawable
* @return this for chaining
*/
public Builder<T> with(Drawable backgroundDrawable) {
this.backgroundDrawable = backgroundDrawable;
return this;
}
/**
* Sets elevation for the popup. Defaults to 6 dp.
*
* @param elevationDp popup elevation, in DP
* @return this for chaning.
*/
public Builder<T> with(float elevationDp) {
this.elevationDp = elevationDp;
return this;
}
/**
* Builds an Autocomplete instance. This is enough for autocomplete to be set up,
* but you can hold a reference to the object and call its public methods.
*
* @return an Autocomplete instance, if you need it
*
* @throws RuntimeException if either EditText or the presenter are null
*/
public Autocomplete<T> build() {
if (source == null) throw new RuntimeException("Autocomplete needs a source!");
if (presenter == null) throw new RuntimeException("Autocomplete needs a presenter!");
if (policy == null) policy = new SimplePolicy();
return new Autocomplete<T>(this);
}
private void clear() {
source = null;
presenter = null;
callback = null;
policy = null;
backgroundDrawable = null;
elevationDp = 6;
}
}
/**
* Entry point for building autocomplete on a certain {@link EditText}.
* @param anchor the anchor for the popup, and the source of text events
* @param <T> your data model
* @return a Builder for set up
*/
public static <T> Builder<T> on(EditText anchor) {
return new Builder<T>(anchor);
}
private AutocompletePolicy policy;
private AutocompletePopup popup;
private AutocompletePresenter<T> presenter;
private AutocompleteCallback<T> callback;
private EditText source;
private boolean block;
private boolean disabled;
private boolean openBefore;
private String lastQuery = "null";
private Autocomplete(Builder<T> builder) {
policy = builder.policy;
presenter = builder.presenter;
callback = builder.callback;
source = builder.source;
// Set up popup
popup = new AutocompletePopup(source.getContext());
popup.setAnchorView(source);
popup.setGravity(Gravity.START);
popup.setModal(false);
popup.setBackgroundDrawable(builder.backgroundDrawable);
popup.setElevation(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, builder.elevationDp,
source.getContext().getResources().getDisplayMetrics()));
// popup dimensions
AutocompletePresenter.PopupDimensions dim = this.presenter.getPopupDimensions();
popup.setWidth(dim.width);
popup.setHeight(dim.height);
popup.setMaxWidth(dim.maxWidth);
popup.setMaxHeight(dim.maxHeight);
// Fire visibility events
popup.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
lastQuery = "null";
if (callback != null) callback.onPopupVisibilityChanged(false);
boolean saved = block;
block = true;
policy.onDismiss(source.getText());
block = saved;
presenter.hideView();
}
});
// Set up source
source.getText().setSpan(this, 0, source.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
source.addTextChangedListener(this);
// Set up presenter
presenter.registerClickProvider(new AutocompletePresenter.ClickProvider<T>() {
@Override
public void click(@NonNull T item) {
AutocompleteCallback<T> callback = Autocomplete.this.callback;
EditText edit = Autocomplete.this.source;
if (callback == null) return;
boolean saved = block;
block = true;
boolean dismiss = callback.onPopupItemClicked(edit.getText(), item);
if (dismiss) dismissPopup();
block = saved;
}
});
builder.clear();
}
/**
* Controls how the popup operates with an input method.
*
* If the popup is showing, calling this method will take effect only
* the next time the popup is shown.
*
* @param mode a {@link PopupWindow} input method mode
*/
public void setInputMethodMode(int mode) {
popup.setInputMethodMode(mode);
}
/**
* Sets the operating mode for the soft input area.
*
* @param mode The desired mode, see {@link WindowManager.LayoutParams#softInputMode}
*/
public void setSoftInputMode(int mode) {
popup.setSoftInputMode(mode);
}
/**
* Shows the popup with the given query.
* There is rarely need to call this externally: it is already triggered by events on the anchor.
* To control when this is called, provide a good implementation of {@link AutocompletePolicy}.
*
* @param query query text.
*/
public void showPopup(@NonNull CharSequence query) {
if (isPopupShowing() && lastQuery.equals(query.toString())) return;
lastQuery = query.toString();
log("showPopup: called with filter "+query);
if (!isPopupShowing()) {
log("showPopup: showing");
presenter.registerDataSetObserver(new Observer()); // Calling new to avoid leaking... maybe...
popup.setView(presenter.getView());
presenter.showView();
popup.show();
if (callback != null) callback.onPopupVisibilityChanged(true);
}
log("showPopup: popup should be showing... "+isPopupShowing());
presenter.onQuery(query);
}
/**
* Dismisses the popup, if showing.
* There is rarely need to call this externally: it is already triggered by events on the anchor.
* To control when this is called, provide a good implementation of {@link AutocompletePolicy}.
*/
public void dismissPopup() {
if (isPopupShowing()) {
popup.dismiss();
}
}
/**
* Returns true if the popup is showing.
* @return whether the popup is currently showing
*/
public boolean isPopupShowing() {
return this.popup.isShowing();
}
/**
* Switch to control the autocomplete behavior. When disabled, no popup is shown.
* This is useful if you want to do runtime edits to the anchor text, without triggering
* the popup.
*
* @param enabled whether to enable autocompletion
*/
public void setEnabled(boolean enabled) {
disabled = !enabled;
}
/**
* Sets the gravity for the popup. Basically only {@link Gravity#START} and {@link Gravity#END}
* do work.
*
* @param gravity gravity for the popup
*/
public void setGravity(int gravity) {
popup.setGravity(gravity);
}
/**
* Controls the vertical offset of the popup from the EditText anchor.
*
* @param offset offset in pixels.
*/
public void setOffsetFromAnchor(int offset) { popup.setVerticalOffset(offset); }
/**
* Controls whether the popup should listen to clicks outside its boundaries.
*
* @param outsideTouchable true to listen to outside clicks
*/
public void setOutsideTouchable(boolean outsideTouchable) { popup.setOutsideTouchable(outsideTouchable); }
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if (block || disabled) return;
openBefore = isPopupShowing();
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (block || disabled) return;
if (openBefore && !isPopupShowing()) {
return; // Copied from somewhere.
}
if (!(s instanceof Spannable)) {
source.setText(new SpannableString(s));
return;
}
Spannable sp = (Spannable) s;
int cursor = source.getSelectionEnd();
log("onTextChanged: cursor end position is "+cursor);
if (cursor == -1) { // No cursor present.
dismissPopup(); return;
}
if (cursor != source.getSelectionStart()) {
// Not sure about this. We should have no problems dealing with multi selections,
// we just take the end...
// dismissPopup(); return;
}
boolean b = block;
block = true; // policy might add spans or other stuff.
if (isPopupShowing() && policy.shouldDismissPopup(sp, cursor)) {
log("onTextChanged: dismissing");
dismissPopup();
} else if (isPopupShowing() || policy.shouldShowPopup(sp, cursor)) {
// LOG.now("onTextChanged: updating with filter "+policy.getQuery(sp));
showPopup(policy.getQuery(sp));
}
block = b;
}
@Override
public void afterTextChanged(Editable s) {}
@Override
public void onSpanAdded(Spannable text, Object what, int start, int end) {}
@Override
public void onSpanRemoved(Spannable text, Object what, int start, int end) {}
@Override
public void onSpanChanged(Spannable text, Object what, int ostart, int oend, int nstart, int nend) {
if (disabled || block) return;
if (what == Selection.SELECTION_END) {
// Selection end changed from ostart to nstart. Trigger a check.
log("onSpanChanged: selection end moved from "+ostart+" to "+nstart);
log("onSpanChanged: block is "+block);
boolean b = block;
block = true;
if (!isPopupShowing() && policy.shouldShowPopup(text, nstart)) {
showPopup(policy.getQuery(text));
}
block = b;
}
}
private class Observer extends DataSetObserver implements Runnable {
private Handler ui = new Handler(Looper.getMainLooper());
@Override
public void onChanged() {
// ??? Not sure this is needed...
ui.post(this);
}
@Override
public void run() {
if (isPopupShowing()) {
// Call show again to revisit width and height.
popup.show();
}
}
}
/**
* A very simple {@link AutocompletePolicy} implementation.
* Popup is shown when text length is bigger than 0, and hidden when text is empty.
* The query string is the whole text.
*/
public static class SimplePolicy implements AutocompletePolicy {
@Override
public boolean shouldShowPopup(@NonNull Spannable text, int cursorPos) {
return text.length() > 0;
}
@Override
public boolean shouldDismissPopup(@NonNull Spannable text, int cursorPos) {
return text.length() == 0;
}
@NonNull
@Override
public CharSequence getQuery(@NonNull Spannable text) {
return text;
}
@Override
public void onDismiss(@NonNull Spannable text) {}
}
}

View File

@@ -0,0 +1,29 @@
package com.otaliastudios.autocomplete;
import android.text.Editable;
import androidx.annotation.NonNull;
/**
* Optional callback to be passed to {@link Autocomplete.Builder}.
*/
public interface AutocompleteCallback<T> {
/**
* Called when an item inside your list is clicked.
* This works if your presenter has dispatched a click event.
* At this point you can edit the text, e.g. {@code editable.append(item.toString())}.
*
* @param editable editable text that you can work on
* @param item item that was clicked
* @return true if the action is valid and the popup can be dismissed
*/
boolean onPopupItemClicked(@NonNull Editable editable, @NonNull T item);
/**
* Called when popup visibility state changes.
*
* @param shown true if the popup was just shown, false if it was just hidden
*/
void onPopupVisibilityChanged(boolean shown);
}

View File

@@ -0,0 +1,64 @@
package com.otaliastudios.autocomplete;
import android.text.Spannable;
import androidx.annotation.NonNull;
/**
* This interface controls when to show or hide the popup window, and, in the first case,
* what text should be passed to the popup {@link AutocompletePresenter}.
*
* @see Autocomplete.SimplePolicy for the simplest possible implementation
*/
public interface AutocompletePolicy {
/**
* Called to understand whether the popup should be shown. Some naive examples:
* - Show when there's text: {@code return text.length() > 0}
* - Show when last char is @: {@code return text.getCharAt(text.length()-1) == '@'}
*
* @param text current text, along with its Spans
* @param cursorPos the position of the cursor
* @return true if popup should be shown
*/
boolean shouldShowPopup(@NonNull Spannable text, int cursorPos);
/**
* Called to understand whether a currently shown popup should be closed, maybe
* because text is invalid. A reasonable implementation is
* {@code return !shouldShowPopup(text, cursorPos)}.
*
* However this is defined so you can add or clear spans.
*
* @param text current text, along with its Spans
* @param cursorPos the position of the cursor
* @return true if popup should be hidden
*/
boolean shouldDismissPopup(@NonNull Spannable text, int cursorPos);
/**
* Called to understand which query should be passed to {@link AutocompletePresenter}
* for a showing popup. If this is called, {@link #shouldShowPopup(Spannable, int)} just returned
* true, or {@link #shouldDismissPopup(Spannable, int)} just returned false.
*
* This is useful to understand which part of the text should be passed to presenters.
* For example, user might have typed '@john' to select a username, but you just want to
* search for 'john'.
*
* For more complex cases, you can add inclusive Spans in {@link #shouldShowPopup(Spannable, int)},
* and get the span position here.
*
* @param text current text, along with its Spans
* @return the query for presenter
*/
@NonNull
CharSequence getQuery(@NonNull Spannable text);
/**
* Called when popup is dismissed. This can be used, for instance, to clear custom Spans
* from the text.
*
* @param text text at the moment of dismissing
*/
void onDismiss(@NonNull Spannable text);
}

View File

@@ -0,0 +1,521 @@
package com.otaliastudios.autocomplete;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.PopupWindow;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StyleRes;
import androidx.core.view.ViewCompat;
import androidx.core.widget.PopupWindowCompat;
/**
* A simplified version of andriod.widget.ListPopupWindow, which is the class used by
* AutocompleteTextView.
*
* Other than being simplified, this deals with Views rather than ListViews, so the content
* can be whatever. Lots of logic (clicks, selections etc.) has been removed because we manage that
* in {@link AutocompletePresenter}.
*
*/
class AutocompletePopup {
private Context mContext;
private ViewGroup mView;
private int mHeight = ViewGroup.LayoutParams.WRAP_CONTENT;
private int mWidth = ViewGroup.LayoutParams.WRAP_CONTENT;
private int mMaxHeight = Integer.MAX_VALUE;
private int mMaxWidth = Integer.MAX_VALUE;
private int mUserMaxHeight = Integer.MAX_VALUE;
private int mUserMaxWidth = Integer.MAX_VALUE;
private int mHorizontalOffset = 0;
private int mVerticalOffset = 0;
private boolean mVerticalOffsetSet;
private int mGravity = Gravity.NO_GRAVITY;
private boolean mAlwaysVisible = false;
private boolean mOutsideTouchable = true;
private View mAnchorView;
private final Rect mTempRect = new Rect();
private boolean mModal;
private PopupWindow mPopup;
/**
* Create a new, empty popup window capable of displaying items from a ListAdapter.
* Backgrounds should be set using {@link #setBackgroundDrawable(Drawable)}.
*
* @param context Context used for contained views.
*/
AutocompletePopup(@NonNull Context context) {
super();
mContext = context;
mPopup = new PopupWindow(context);
mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
}
/**
* Set whether this window should be modal when shown.
*
* <p>If a popup window is modal, it will receive all touch and key input.
* If the user touches outside the popup window's content area the popup window
* will be dismissed.
* @param modal {@code true} if the popup window should be modal, {@code false} otherwise.
*/
@SuppressWarnings("SameParameterValue")
void setModal(boolean modal) {
mModal = modal;
mPopup.setFocusable(modal);
}
/**
* Returns whether the popup window will be modal when shown.
* @return {@code true} if the popup window will be modal, {@code false} otherwise.
*/
@SuppressWarnings("unused")
boolean isModal() {
return mModal;
}
void setElevation(float elevationPx) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) mPopup.setElevation(elevationPx);
}
/**
* Sets whether the drop-down should remain visible under certain conditions.
*
* The drop-down will occupy the entire screen below {@link #getAnchorView} regardless
* of the size or content of the list. {@link #getBackground()} will fill any space
* that is not used by the list.
* @param dropDownAlwaysVisible Whether to keep the drop-down visible.
*
*/
@SuppressWarnings("unused")
void setDropDownAlwaysVisible(boolean dropDownAlwaysVisible) {
mAlwaysVisible = dropDownAlwaysVisible;
}
/**
* @return Whether the drop-down is visible under special conditions.
*/
@SuppressWarnings("unused")
boolean isDropDownAlwaysVisible() {
return mAlwaysVisible;
}
void setOutsideTouchable(boolean outsideTouchable) {
mOutsideTouchable = outsideTouchable;
}
@SuppressWarnings("WeakerAccess")
boolean isOutsideTouchable() {
return mOutsideTouchable && !mAlwaysVisible;
}
/**
* Sets the operating mode for the soft input area.
* @param mode The desired mode, see
* {@link android.view.WindowManager.LayoutParams#softInputMode}
* for the full list
* @see android.view.WindowManager.LayoutParams#softInputMode
* @see #getSoftInputMode()
*/
void setSoftInputMode(int mode) {
mPopup.setSoftInputMode(mode);
}
/**
* Returns the current value in {@link #setSoftInputMode(int)}.
* @see #setSoftInputMode(int)
* @see android.view.WindowManager.LayoutParams#softInputMode
*/
@SuppressWarnings({"WeakerAccess", "unused"})
int getSoftInputMode() {
return mPopup.getSoftInputMode();
}
/**
* @return The background drawable for the popup window.
*/
@SuppressWarnings({"WeakerAccess", "unused"})
@Nullable
Drawable getBackground() {
return mPopup.getBackground();
}
/**
* Sets a drawable to be the background for the popup window.
* @param d A drawable to set as the background.
*/
void setBackgroundDrawable(@Nullable Drawable d) {
mPopup.setBackgroundDrawable(d);
}
/**
* Set an animation style to use when the popup window is shown or dismissed.
* @param animationStyle Animation style to use.
*/
@SuppressWarnings("unused")
void setAnimationStyle(@StyleRes int animationStyle) {
mPopup.setAnimationStyle(animationStyle);
}
/**
* Returns the animation style that will be used when the popup window is
* shown or dismissed.
* @return Animation style that will be used.
*/
@SuppressWarnings("unused")
@StyleRes
int getAnimationStyle() {
return mPopup.getAnimationStyle();
}
/**
* Returns the view that will be used to anchor this popup.
* @return The popup's anchor view
*/
@SuppressWarnings("WeakerAccess")
View getAnchorView() {
return mAnchorView;
}
/**
* Sets the popup's anchor view. This popup will always be positioned relative to
* the anchor view when shown.
* @param anchor The view to use as an anchor.
*/
void setAnchorView(@NonNull View anchor) {
mAnchorView = anchor;
}
/**
* Set the horizontal offset of this popup from its anchor view in pixels.
* @param offset The horizontal offset of the popup from its anchor.
*/
@SuppressWarnings("unused")
void setHorizontalOffset(int offset) {
mHorizontalOffset = offset;
}
/**
* Set the vertical offset of this popup from its anchor view in pixels.
* @param offset The vertical offset of the popup from its anchor.
*/
void setVerticalOffset(int offset) {
mVerticalOffset = offset;
mVerticalOffsetSet = true;
}
/**
* Set the gravity of the dropdown list. This is commonly used to
* set gravity to START or END for alignment with the anchor.
* @param gravity Gravity value to use
*/
void setGravity(int gravity) {
mGravity = gravity;
}
/**
* @return The width of the popup window in pixels.
*/
@SuppressWarnings("unused")
int getWidth() {
return mWidth;
}
/**
* Sets the width of the popup window in pixels. Can also be MATCH_PARENT
* or WRAP_CONTENT.
* @param width Width of the popup window.
*/
void setWidth(int width) {
mWidth = width;
}
/**
* Sets the width of the popup window by the size of its content. The final width may be
* larger to accommodate styled window dressing.
* @param width Desired width of content in pixels.
*/
@SuppressWarnings("unused")
void setContentWidth(int width) {
Drawable popupBackground = mPopup.getBackground();
if (popupBackground != null) {
popupBackground.getPadding(mTempRect);
width += mTempRect.left + mTempRect.right;
}
setWidth(width);
}
void setMaxWidth(int width) {
if (width > 0) {
mUserMaxWidth = width;
}
}
/**
* @return The height of the popup window in pixels.
*/
@SuppressWarnings("unused")
int getHeight() {
return mHeight;
}
/**
* Sets the height of the popup window in pixels. Can also be MATCH_PARENT.
* @param height Height of the popup window.
*/
void setHeight(int height) {
mHeight = height;
}
/**
* Sets the height of the popup window by the size of its content. The final height may be
* larger to accommodate styled window dressing.
* @param height Desired height of content in pixels.
*/
@SuppressWarnings("unused")
void setContentHeight(int height) {
Drawable popupBackground = mPopup.getBackground();
if (popupBackground != null) {
popupBackground.getPadding(mTempRect);
height += mTempRect.top + mTempRect.bottom;
}
setHeight(height);
}
void setMaxHeight(int height) {
if (height > 0) {
mUserMaxHeight = height;
}
}
void setOnDismissListener(PopupWindow.OnDismissListener listener) {
mPopup.setOnDismissListener(listener);
}
/**
* Show the popup list. If the list is already showing, this method
* will recalculate the popup's size and position.
*/
void show() {
if (!ViewCompat.isAttachedToWindow(getAnchorView())) return;
int height = buildDropDown();
final boolean noInputMethod = isInputMethodNotNeeded();
int mDropDownWindowLayoutType = WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
PopupWindowCompat.setWindowLayoutType(mPopup, mDropDownWindowLayoutType);
if (mPopup.isShowing()) {
// First pass for this special case, don't know why.
if (mHeight == ViewGroup.LayoutParams.MATCH_PARENT) {
int tempWidth = mWidth == ViewGroup.LayoutParams.MATCH_PARENT ? ViewGroup.LayoutParams.MATCH_PARENT : 0;
if (noInputMethod) {
mPopup.setWidth(tempWidth);
mPopup.setHeight(0);
} else {
mPopup.setWidth(tempWidth);
mPopup.setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
}
}
// The call to PopupWindow's update method below can accept -1
// for any value you do not want to update.
// Width.
int widthSpec;
if (mWidth == ViewGroup.LayoutParams.MATCH_PARENT) {
widthSpec = -1;
} else if (mWidth == ViewGroup.LayoutParams.WRAP_CONTENT) {
widthSpec = getAnchorView().getWidth();
} else {
widthSpec = mWidth;
}
widthSpec = Math.min(widthSpec, mMaxWidth);
widthSpec = (widthSpec < 0) ? - 1 : widthSpec;
// Height.
int heightSpec;
if (mHeight == ViewGroup.LayoutParams.MATCH_PARENT) {
heightSpec = noInputMethod ? height : ViewGroup.LayoutParams.MATCH_PARENT;
} else if (mHeight == ViewGroup.LayoutParams.WRAP_CONTENT) {
heightSpec = height;
} else {
heightSpec = mHeight;
}
heightSpec = Math.min(heightSpec, mMaxHeight);
heightSpec = (heightSpec < 0) ? - 1 : heightSpec;
// Update.
mPopup.setOutsideTouchable(isOutsideTouchable());
if (heightSpec == 0) {
dismiss();
} else {
mPopup.update(getAnchorView(), mHorizontalOffset, mVerticalOffset, widthSpec, heightSpec);
}
} else {
int widthSpec;
if (mWidth == ViewGroup.LayoutParams.MATCH_PARENT) {
widthSpec = ViewGroup.LayoutParams.MATCH_PARENT;
} else if (mWidth == ViewGroup.LayoutParams.WRAP_CONTENT) {
widthSpec = getAnchorView().getWidth();
} else {
widthSpec = mWidth;
}
widthSpec = Math.min(widthSpec, mMaxWidth);
int heightSpec;
if (mHeight == ViewGroup.LayoutParams.MATCH_PARENT) {
heightSpec = ViewGroup.LayoutParams.MATCH_PARENT;
} else if (mHeight == ViewGroup.LayoutParams.WRAP_CONTENT) {
heightSpec = height;
} else {
heightSpec = mHeight;
}
heightSpec = Math.min(heightSpec, mMaxHeight);
// Set width and height.
mPopup.setWidth(widthSpec);
mPopup.setHeight(heightSpec);
mPopup.setClippingEnabled(true);
// use outside touchable to dismiss drop down when touching outside of it, so
// only set this if the dropdown is not always visible
mPopup.setOutsideTouchable(isOutsideTouchable());
PopupWindowCompat.showAsDropDown(mPopup, getAnchorView(), mHorizontalOffset, mVerticalOffset, mGravity);
}
}
/**
* Dismiss the popup window.
*/
void dismiss() {
mPopup.dismiss();
mPopup.setContentView(null);
mView = null;
}
/**
* Control how the popup operates with an input method: one of
* INPUT_METHOD_FROM_FOCUSABLE, INPUT_METHOD_NEEDED,
* or INPUT_METHOD_NOT_NEEDED.
*
* <p>If the popup is showing, calling this method will take effect only
* the next time the popup is shown or through a manual call to the {@link #show()}
* method.</p>
*
* @see #show()
*/
void setInputMethodMode(int mode) {
mPopup.setInputMethodMode(mode);
}
/**
* @return {@code true} if the popup is currently showing, {@code false} otherwise.
*/
boolean isShowing() {
return mPopup.isShowing();
}
/**
* @return {@code true} if this popup is configured to assume the user does not need
* to interact with the IME while it is showing, {@code false} otherwise.
*/
@SuppressWarnings("WeakerAccess")
boolean isInputMethodNotNeeded() {
return mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED;
}
void setView(ViewGroup view) {
mView = view;
mView.setFocusable(true);
mView.setFocusableInTouchMode(true);
ViewGroup dropDownView = mView;
mPopup.setContentView(dropDownView);
ViewGroup.LayoutParams params = mView.getLayoutParams();
if (params != null) {
if (params.height > 0) setHeight(params.height);
if (params.width > 0) setWidth(params.width);
}
}
/**
* <p>Builds the popup window's content and returns the height the popup
* should have. Returns -1 when the content already exists.</p>
*
* @return the content's wrap content height or -1 if content already exists
*/
private int buildDropDown() {
int otherHeights = 0;
// getMaxAvailableHeight() subtracts the padding, so we put it back
// to get the available height for the whole window.
final int paddingVert;
final int paddingHoriz;
final Drawable background = mPopup.getBackground();
if (background != null) {
background.getPadding(mTempRect);
paddingVert = mTempRect.top + mTempRect.bottom;
paddingHoriz = mTempRect.left + mTempRect.right;
// If we don't have an explicit vertical offset, determine one from
// the window background so that content will line up.
if (!mVerticalOffsetSet) {
mVerticalOffset = -mTempRect.top;
}
} else {
mTempRect.setEmpty();
paddingVert = 0;
paddingHoriz = 0;
}
// Redefine dimensions taking into account maxWidth and maxHeight.
final boolean ignoreBottomDecorations = mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED;
final int maxContentHeight = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ?
mPopup.getMaxAvailableHeight(getAnchorView(), mVerticalOffset, ignoreBottomDecorations) :
mPopup.getMaxAvailableHeight(getAnchorView(), mVerticalOffset);
final int maxContentWidth = mContext.getResources().getDisplayMetrics().widthPixels - paddingHoriz;
mMaxHeight = Math.min(maxContentHeight + paddingVert, mUserMaxHeight);
mMaxWidth = Math.min(maxContentWidth + paddingHoriz, mUserMaxWidth);
// if (mHeight > 0) mHeight = Math.min(mHeight, maxContentHeight);
// if (mWidth > 0) mWidth = Math.min(mWidth, maxContentWidth);
if (mAlwaysVisible || mHeight == ViewGroup.LayoutParams.MATCH_PARENT) {
return mMaxHeight;
}
final int childWidthSpec;
switch (mWidth) {
case ViewGroup.LayoutParams.WRAP_CONTENT:
childWidthSpec = View.MeasureSpec.makeMeasureSpec(maxContentWidth, View.MeasureSpec.AT_MOST); break;
case ViewGroup.LayoutParams.MATCH_PARENT:
childWidthSpec = View.MeasureSpec.makeMeasureSpec(maxContentWidth, View.MeasureSpec.EXACTLY); break;
default:
//noinspection Range
childWidthSpec = View.MeasureSpec.makeMeasureSpec(mWidth, View.MeasureSpec.EXACTLY); break;
}
// Add padding only if the list has items in it, that way we don't show
// the popup if it is not needed. For this reason, we measure as wrap_content.
mView.measure(childWidthSpec, View.MeasureSpec.makeMeasureSpec(maxContentHeight, View.MeasureSpec.AT_MOST));
final int viewHeight = mView.getMeasuredHeight();
if (viewHeight > 0) {
otherHeights += paddingVert + mView.getPaddingTop() + mView.getPaddingBottom();
}
return Math.min(viewHeight + otherHeights, mMaxHeight);
}
}

View File

@@ -0,0 +1,129 @@
package com.otaliastudios.autocomplete;
import android.content.Context;
import android.database.DataSetObserver;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* Base class for presenting items inside a popup. This is abstract and must be implemented.
*
* Most important methods are {@link #getView()} and {@link #onQuery(CharSequence)}.
*/
public abstract class AutocompletePresenter<T> {
private Context context;
private boolean isShowing;
@SuppressWarnings("WeakerAccess")
public AutocompletePresenter(@NonNull Context context) {
this.context = context;
}
/**
* At this point the presenter is passed the {@link ClickProvider}.
* The contract is that {@link ClickProvider#click(Object)} must be called when a list item
* is clicked. This ensure that the autocomplete callback will receive the event.
*
* @param provider a click provider for this presenter.
*/
protected void registerClickProvider(ClickProvider<T> provider) {
}
/**
* Useful if you wish to change width/height based on content height.
* The contract is to call {@link DataSetObserver#onChanged()} when your view has
* changes.
*
* This is called after {@link #getView()}.
*
* @param observer the observer.
*/
protected void registerDataSetObserver(@NonNull DataSetObserver observer) {}
/**
* Called each time the popup is shown. You are meant to inflate the view here.
* You can get a LayoutInflater using {@link #getContext()}.
*
* @return a ViewGroup for the popup
*/
@NonNull
protected abstract ViewGroup getView();
/**
* Provide the {@link PopupDimensions} for this popup. Called just once.
* You can use fixed dimensions or {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} and
* {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT}.
*
* @return a PopupDimensions object
*/
// Called at first to understand which dimensions to use for the popup.
@NonNull
protected PopupDimensions getPopupDimensions() {
return new PopupDimensions();
}
/**
* Perform firther initialization here. Called after {@link #getView()},
* each time the popup is shown.
*/
protected abstract void onViewShown();
/**
* Called to update the view to filter results with the query.
* It is called any time the popup is shown, and any time the text changes and query is updated.
*
* @param query query from the edit text, to filter our results
*/
protected abstract void onQuery(@Nullable CharSequence query);
/**
* Called when the popup is hidden, to release resources.
*/
protected abstract void onViewHidden();
/**
* @return this presenter context
*/
@NonNull
protected final Context getContext() {
return context;
}
/**
* @return whether we are showing currently
*/
@SuppressWarnings("unused")
protected final boolean isShowing() {
return isShowing;
}
final void showView() {
isShowing = true;
onViewShown();
}
final void hideView() {
isShowing = false;
onViewHidden();
}
public interface ClickProvider<T> {
void click(@NonNull T item);
}
/**
* Provides width, height, maxWidth and maxHeight for the popup.
* @see #getPopupDimensions()
*/
@SuppressWarnings("WeakerAccess")
public static class PopupDimensions {
public int width = ViewGroup.LayoutParams.WRAP_CONTENT;
public int height = ViewGroup.LayoutParams.WRAP_CONTENT;
public int maxWidth = Integer.MAX_VALUE;
public int maxHeight = Integer.MAX_VALUE;
}
}

View File

@@ -0,0 +1,184 @@
package com.otaliastudios.autocomplete;
import android.text.Spannable;
import android.text.Spanned;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* A special {@link AutocompletePolicy} for cases when you want to trigger the popup when a
* certain character is shown.
*
* For instance, this might be the case for hashtags ('#') or usernames ('@') or whatever you wish.
* Passing this to {@link Autocomplete.Builder} ensures the following behavior (assuming '@'):
* - text "@john" : presenter will be passed the query "john"
* - text "You should see this @j" : presenter will be passed the query "j"
* - text "You should see this @john @m" : presenter will be passed the query "m"
*/
public class CharPolicy implements AutocompletePolicy {
private final static String TAG = CharPolicy.class.getSimpleName();
private final static boolean DEBUG = false;
private static void log(@NonNull String log) {
if (DEBUG) Log.e(TAG, log);
}
private final char CH;
private final int[] INT = new int[2];
private boolean needSpaceBefore = true;
/**
* Constructs a char policy for the given character.
*
* @param trigger the triggering character.
*/
public CharPolicy(char trigger) {
CH = trigger;
}
/**
* Constructs a char policy for the given character.
* You can choose whether a whitespace is needed before 'trigger'.
*
* @param trigger the triggering character.
* @param needSpaceBefore whether we need a space before trigger
*/
@SuppressWarnings("unused")
public CharPolicy(char trigger, boolean needSpaceBefore) {
CH = trigger;
this.needSpaceBefore = needSpaceBefore;
}
/**
* Can be overriden to understand which characters are valid. The default implementation
* returns true for any character except whitespaces.
*
* @param ch the character
* @return whether it's valid part of a query
*/
@SuppressWarnings("WeakerAccess")
protected boolean isValidChar(char ch) {
return !Character.isWhitespace(ch);
}
@Nullable
private int[] checkText(@NonNull Spannable text, int cursorPos) {
final int spanEnd = cursorPos;
char last = 'x';
cursorPos -= 1; // If the cursor is at the end, we will have cursorPos = length. Go back by 1.
while (cursorPos >= 0 && last != CH) {
char ch = text.charAt(cursorPos);
log("checkText: char is "+ch);
if (isValidChar(ch)) {
// We are going back
log("checkText: char is valid");
cursorPos -= 1;
last = ch;
} else {
// We got a whitespace before getting a CH. This is invalid.
log("checkText: char is not valid, returning NULL");
return null;
}
}
cursorPos += 1; // + 1 because we end BEHIND the valid selection
// Start checking.
if (cursorPos == 0 && last != CH) {
// We got to the start of the string, and no CH was encountered. Nothing to do.
log("checkText: got to start but no CH, returning NULL");
return null;
}
// Additional checks for cursorPos - 1
if (cursorPos > 0 && needSpaceBefore) {
char ch = text.charAt(cursorPos-1);
if (!Character.isWhitespace(ch)) {
log("checkText: char before is not whitespace, returning NULL");
return null;
}
}
// All seems OK.
final int spanStart = cursorPos + 1; // + 1 because we want to exclude CH from the query
INT[0] = spanStart;
INT[1] = spanEnd;
log("checkText: found! cursorPos="+cursorPos);
log("checkText: found! spanStart="+spanStart);
log("checkText: found! spanEnd="+spanEnd);
return INT;
}
@Override
public boolean shouldShowPopup(@NonNull Spannable text, int cursorPos) {
// Returning true if, right before cursorPos, we have a word starting with @.
log("shouldShowPopup: text is "+text);
log("shouldShowPopup: cursorPos is "+cursorPos);
int[] show = checkText(text, cursorPos);
if (show != null) {
text.setSpan(new QuerySpan(), show[0], show[1], Spanned.SPAN_INCLUSIVE_INCLUSIVE);
return true;
}
log("shouldShowPopup: returning false");
return false;
}
@Override
public boolean shouldDismissPopup(@NonNull Spannable text, int cursorPos) {
log("shouldDismissPopup: text is "+text);
log("shouldDismissPopup: cursorPos is "+cursorPos);
boolean dismiss = checkText(text, cursorPos) == null;
log("shouldDismissPopup: returning "+dismiss);
return dismiss;
}
@NonNull
@Override
public CharSequence getQuery(@NonNull Spannable text) {
QuerySpan[] span = text.getSpans(0, text.length(), QuerySpan.class);
if (span == null || span.length == 0) {
// Should never happen.
log("getQuery: there's no span!");
return "";
}
log("getQuery: found spans: "+span.length);
QuerySpan sp = span[0];
log("getQuery: span start is "+text.getSpanStart(sp));
log("getQuery: span end is "+text.getSpanEnd(sp));
CharSequence seq = text.subSequence(text.getSpanStart(sp), text.getSpanEnd(sp));
log("getQuery: returning "+seq);
return seq;
}
@Override
public void onDismiss(@NonNull Spannable text) {
// Remove any span added by shouldShow. Should be useless, but anyway.
QuerySpan[] span = text.getSpans(0, text.length(), QuerySpan.class);
for (QuerySpan s : span) {
text.removeSpan(s);
}
}
private static class QuerySpan {}
/**
* Returns the current query out of the given Spannable.
* @param text the anchor text
* @return an int[] with query start and query end positions
*/
@Nullable
public static int[] getQueryRange(@NonNull Spannable text) {
QuerySpan[] span = text.getSpans(0, text.length(), QuerySpan.class);
if (span == null || span.length == 0) return null;
if (span.length > 1) {
// Won't happen
log("getQueryRange: ERR: MORE THAN ONE QuerySpan.");
}
QuerySpan sp = span[0];
return new int[]{text.getSpanStart(sp), text.getSpanEnd(sp)};
}
}

View File

@@ -0,0 +1,152 @@
package com.otaliastudios.autocomplete;
import android.content.Context;
import android.database.DataSetObserver;
import android.view.ViewGroup;
import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
/**
* Simple {@link AutocompletePresenter} implementation that hosts a {@link RecyclerView}.
* Supports {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} natively.
* The only contract is to
*
* - provide a {@link RecyclerView.Adapter} in {@link #instantiateAdapter()}
* - call {@link #dispatchClick(Object)} when an object is clicked
* - update your data during {@link #onQuery(CharSequence)}
*
* @param <T> your model object (the object displayed by the list)
*/
public abstract class RecyclerViewPresenter<T> extends AutocompletePresenter<T> {
private RecyclerView recycler;
private ClickProvider<T> clicks;
private Observer observer;
public RecyclerViewPresenter(@NonNull Context context) {
super(context);
}
@Override
protected final void registerClickProvider(@NonNull ClickProvider<T> provider) {
this.clicks = provider;
}
@Override
protected final void registerDataSetObserver(@NonNull DataSetObserver observer) {
this.observer = new Observer(observer);
}
@NonNull
@Override
protected ViewGroup getView() {
recycler = new RecyclerView(getContext());
RecyclerView.Adapter adapter = instantiateAdapter();
recycler.setAdapter(adapter);
recycler.setLayoutManager(instantiateLayoutManager());
if (observer != null) {
adapter.registerAdapterDataObserver(observer);
observer = null;
}
return recycler;
}
@Override
protected void onViewShown() {}
@CallSuper
@Override
protected void onViewHidden() {
recycler = null;
observer = null;
}
@SuppressWarnings("unused")
@Nullable
protected final RecyclerView getRecyclerView() {
return recycler;
}
/**
* Dispatch click event to {@link AutocompleteCallback}.
* Should be called when items are clicked.
*
* @param item the clicked item.
*/
protected final void dispatchClick(@NonNull T item) {
if (clicks != null) clicks.click(item);
}
/**
* Request that the popup should recompute its dimensions based on a recent change in
* the view being displayed.
*
* This is already managed internally for {@link RecyclerView} events.
* Only use it for changes in other views that you have added to the popup,
* and only if one of the dimensions for the popup is WRAP_CONTENT .
*/
@SuppressWarnings("unused")
protected final void dispatchLayoutChange() {
if (observer != null) observer.onChanged();
}
/**
* Provide an adapter for the recycler.
* This should be a fresh instance every time this is called.
*
* @return a new adapter.
*/
@NonNull
protected abstract RecyclerView.Adapter instantiateAdapter();
/**
* Provides a layout manager for the recycler.
* This should be a fresh instance every time this is called.
* Defaults to a vertical LinearLayoutManager, which is guaranteed to work well.
*
* @return a new layout manager.
*/
@SuppressWarnings("WeakerAccess")
@NonNull
protected RecyclerView.LayoutManager instantiateLayoutManager() {
return new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
}
private final static class Observer extends RecyclerView.AdapterDataObserver {
private DataSetObserver root;
Observer(@NonNull DataSetObserver root) {
this.root = root;
}
@Override
public void onChanged() {
root.onChanged();
}
@Override
public void onItemRangeChanged(int positionStart, int itemCount) {
root.onChanged();
}
@Override
public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
root.onChanged();
}
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
root.onChanged();
}
@Override
public void onItemRangeRemoved(int positionStart, int itemCount) {
root.onChanged();
}
}
}

View File

@@ -0,0 +1,26 @@
apply plugin: 'com.android.library'
android {
namespace "me.dm7.barcodescanner.core"
compileSdk versions.compileSdk
defaultConfig {
minSdk versions.minSdk
targetSdk versions.targetSdk
}
compileOptions {
sourceCompatibility versions.sourceCompat
targetCompatibility versions.targetCompat
}
}
dependencies {
implementation 'androidx.annotation:annotation-jvm:1.6.0'
}
afterEvaluate {
tasks.findAll { it.name.startsWith("lint") }.each {
it.enabled = false
}
}

View File

@@ -0,0 +1,339 @@
package me.dm7.barcodescanner.core;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Rect;
import android.hardware.Camera;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import androidx.annotation.ColorInt;
public abstract class BarcodeScannerView extends FrameLayout implements Camera.PreviewCallback {
private CameraWrapper mCameraWrapper;
private CameraPreview mPreview;
private IViewFinder mViewFinderView;
private Rect mFramingRectInPreview;
private CameraHandlerThread mCameraHandlerThread;
private Boolean mFlashState;
private boolean mAutofocusState = true;
private boolean mShouldScaleToFill = true;
private boolean mIsLaserEnabled = true;
@ColorInt private int mLaserColor = getResources().getColor(R.color.viewfinder_laser);
@ColorInt private int mBorderColor = getResources().getColor(R.color.viewfinder_border);
private int mMaskColor = getResources().getColor(R.color.viewfinder_mask);
private int mBorderWidth = getResources().getInteger(R.integer.viewfinder_border_width);
private int mBorderLength = getResources().getInteger(R.integer.viewfinder_border_length);
private boolean mRoundedCorner = false;
private int mCornerRadius = 0;
private boolean mSquaredFinder = false;
private float mBorderAlpha = 1.0f;
private int mViewFinderOffset = 0;
private float mAspectTolerance = 0.1f;
public BarcodeScannerView(Context context) {
super(context);
init();
}
public BarcodeScannerView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
TypedArray a = context.getTheme().obtainStyledAttributes(
attributeSet,
R.styleable.BarcodeScannerView,
0, 0);
try {
setShouldScaleToFill(a.getBoolean(R.styleable.BarcodeScannerView_shouldScaleToFill, true));
mIsLaserEnabled = a.getBoolean(R.styleable.BarcodeScannerView_laserEnabled, mIsLaserEnabled);
mLaserColor = a.getColor(R.styleable.BarcodeScannerView_laserColor, mLaserColor);
mBorderColor = a.getColor(R.styleable.BarcodeScannerView_borderColor, mBorderColor);
mMaskColor = a.getColor(R.styleable.BarcodeScannerView_maskColor, mMaskColor);
mBorderWidth = a.getDimensionPixelSize(R.styleable.BarcodeScannerView_borderWidth, mBorderWidth);
mBorderLength = a.getDimensionPixelSize(R.styleable.BarcodeScannerView_borderLength, mBorderLength);
mRoundedCorner = a.getBoolean(R.styleable.BarcodeScannerView_roundedCorner, mRoundedCorner);
mCornerRadius = a.getDimensionPixelSize(R.styleable.BarcodeScannerView_cornerRadius, mCornerRadius);
mSquaredFinder = a.getBoolean(R.styleable.BarcodeScannerView_squaredFinder, mSquaredFinder);
mBorderAlpha = a.getFloat(R.styleable.BarcodeScannerView_borderAlpha, mBorderAlpha);
mViewFinderOffset = a.getDimensionPixelSize(R.styleable.BarcodeScannerView_finderOffset, mViewFinderOffset);
} finally {
a.recycle();
}
init();
}
private void init() {
mViewFinderView = createViewFinderView(getContext());
}
public final void setupLayout(CameraWrapper cameraWrapper) {
removeAllViews();
mPreview = new CameraPreview(getContext(), cameraWrapper, this);
mPreview.setAspectTolerance(mAspectTolerance);
mPreview.setShouldScaleToFill(mShouldScaleToFill);
if (!mShouldScaleToFill) {
RelativeLayout relativeLayout = new RelativeLayout(getContext());
relativeLayout.setGravity(Gravity.CENTER);
relativeLayout.setBackgroundColor(Color.BLACK);
relativeLayout.addView(mPreview);
addView(relativeLayout);
} else {
addView(mPreview);
}
if (mViewFinderView instanceof View) {
addView((View) mViewFinderView);
} else {
throw new IllegalArgumentException("IViewFinder object returned by " +
"'createViewFinderView()' should be instance of android.view.View");
}
}
/**
* <p>Method that creates view that represents visual appearance of a barcode scanner</p>
* <p>Override it to provide your own view for visual appearance of a barcode scanner</p>
*
* @param context {@link Context}
* @return {@link android.view.View} that implements {@link ViewFinderView}
*/
protected IViewFinder createViewFinderView(Context context) {
ViewFinderView viewFinderView = new ViewFinderView(context);
viewFinderView.setBorderColor(mBorderColor);
viewFinderView.setLaserColor(mLaserColor);
viewFinderView.setLaserEnabled(mIsLaserEnabled);
viewFinderView.setBorderStrokeWidth(mBorderWidth);
viewFinderView.setBorderLineLength(mBorderLength);
viewFinderView.setMaskColor(mMaskColor);
viewFinderView.setBorderCornerRounded(mRoundedCorner);
viewFinderView.setBorderCornerRadius(mCornerRadius);
viewFinderView.setSquareViewFinder(mSquaredFinder);
viewFinderView.setViewFinderOffset(mViewFinderOffset);
return viewFinderView;
}
public void setLaserColor(int laserColor) {
mLaserColor = laserColor;
mViewFinderView.setLaserColor(mLaserColor);
mViewFinderView.setupViewFinder();
}
public void setMaskColor(int maskColor) {
mMaskColor = maskColor;
mViewFinderView.setMaskColor(mMaskColor);
mViewFinderView.setupViewFinder();
}
public void setBorderColor(int borderColor) {
mBorderColor = borderColor;
mViewFinderView.setBorderColor(mBorderColor);
mViewFinderView.setupViewFinder();
}
public void setBorderStrokeWidth(int borderStrokeWidth) {
mBorderWidth = borderStrokeWidth;
mViewFinderView.setBorderStrokeWidth(mBorderWidth);
mViewFinderView.setupViewFinder();
}
public void setBorderLineLength(int borderLineLength) {
mBorderLength = borderLineLength;
mViewFinderView.setBorderLineLength(mBorderLength);
mViewFinderView.setupViewFinder();
}
public void setLaserEnabled(boolean isLaserEnabled) {
mIsLaserEnabled = isLaserEnabled;
mViewFinderView.setLaserEnabled(mIsLaserEnabled);
mViewFinderView.setupViewFinder();
}
public void setIsBorderCornerRounded(boolean isBorderCornerRounded) {
mRoundedCorner = isBorderCornerRounded;
mViewFinderView.setBorderCornerRounded(mRoundedCorner);
mViewFinderView.setupViewFinder();
}
public void setBorderCornerRadius(int borderCornerRadius) {
mCornerRadius = borderCornerRadius;
mViewFinderView.setBorderCornerRadius(mCornerRadius);
mViewFinderView.setupViewFinder();
}
public void setSquareViewFinder(boolean isSquareViewFinder) {
mSquaredFinder = isSquareViewFinder;
mViewFinderView.setSquareViewFinder(mSquaredFinder);
mViewFinderView.setupViewFinder();
}
public void setBorderAlpha(float borderAlpha) {
mBorderAlpha = borderAlpha;
mViewFinderView.setBorderAlpha(mBorderAlpha);
mViewFinderView.setupViewFinder();
}
public void startCamera(int cameraId) {
if(mCameraHandlerThread == null) {
mCameraHandlerThread = new CameraHandlerThread(this);
}
mCameraHandlerThread.startCamera(cameraId);
}
public void setupCameraPreview(CameraWrapper cameraWrapper) {
mCameraWrapper = cameraWrapper;
if(mCameraWrapper != null) {
setupLayout(mCameraWrapper);
mViewFinderView.setupViewFinder();
if(mFlashState != null) {
setFlash(mFlashState);
}
setAutoFocus(mAutofocusState);
}
}
public void startCamera() {
startCamera(CameraUtils.getDefaultCameraId());
}
public void stopCamera() {
if(mCameraWrapper != null) {
mPreview.stopCameraPreview();
mPreview.setCamera(null, null);
mCameraWrapper.mCamera.release();
mCameraWrapper = null;
}
if(mCameraHandlerThread != null) {
mCameraHandlerThread.quit();
mCameraHandlerThread = null;
}
}
public void stopCameraPreview() {
if(mPreview != null) {
mPreview.stopCameraPreview();
}
}
protected void resumeCameraPreview() {
if(mPreview != null) {
mPreview.showCameraPreview();
}
}
public synchronized Rect getFramingRectInPreview(int previewWidth, int previewHeight) {
if (mFramingRectInPreview == null) {
Rect framingRect = mViewFinderView.getFramingRect();
int viewFinderViewWidth = mViewFinderView.getWidth();
int viewFinderViewHeight = mViewFinderView.getHeight();
if (framingRect == null || viewFinderViewWidth == 0 || viewFinderViewHeight == 0) {
return null;
}
Rect rect = new Rect(framingRect);
if(previewWidth < viewFinderViewWidth) {
rect.left = rect.left * previewWidth / viewFinderViewWidth;
rect.right = rect.right * previewWidth / viewFinderViewWidth;
}
if(previewHeight < viewFinderViewHeight) {
rect.top = rect.top * previewHeight / viewFinderViewHeight;
rect.bottom = rect.bottom * previewHeight / viewFinderViewHeight;
}
mFramingRectInPreview = rect;
}
return mFramingRectInPreview;
}
public void setFlash(boolean flag) {
mFlashState = flag;
if(mCameraWrapper != null && CameraUtils.isFlashSupported(mCameraWrapper.mCamera)) {
Camera.Parameters parameters = mCameraWrapper.mCamera.getParameters();
if(flag) {
if(parameters.getFlashMode().equals(Camera.Parameters.FLASH_MODE_TORCH)) {
return;
}
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
} else {
if(parameters.getFlashMode().equals(Camera.Parameters.FLASH_MODE_OFF)) {
return;
}
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
}
mCameraWrapper.mCamera.setParameters(parameters);
}
}
public boolean getFlash() {
if(mCameraWrapper != null && CameraUtils.isFlashSupported(mCameraWrapper.mCamera)) {
Camera.Parameters parameters = mCameraWrapper.mCamera.getParameters();
if(parameters.getFlashMode().equals(Camera.Parameters.FLASH_MODE_TORCH)) {
return true;
} else {
return false;
}
}
return false;
}
public void toggleFlash() {
if(mCameraWrapper != null && CameraUtils.isFlashSupported(mCameraWrapper.mCamera)) {
Camera.Parameters parameters = mCameraWrapper.mCamera.getParameters();
if(parameters.getFlashMode().equals(Camera.Parameters.FLASH_MODE_TORCH)) {
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
} else {
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
}
mCameraWrapper.mCamera.setParameters(parameters);
}
}
public void setAutoFocus(boolean state) {
mAutofocusState = state;
if(mPreview != null) {
mPreview.setAutoFocus(state);
}
}
public void setShouldScaleToFill(boolean shouldScaleToFill) {
mShouldScaleToFill = shouldScaleToFill;
}
public void setAspectTolerance(float aspectTolerance) {
mAspectTolerance = aspectTolerance;
}
public byte[] getRotatedData(byte[] data, Camera camera) {
Camera.Parameters parameters = camera.getParameters();
Camera.Size size = parameters.getPreviewSize();
int width = size.width;
int height = size.height;
int rotationCount = getRotationCount();
if(rotationCount == 1 || rotationCount == 3) {
for (int i = 0; i < rotationCount; i++) {
byte[] rotatedData = new byte[data.length];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++)
rotatedData[x * height + height - y - 1] = data[x + y * width];
}
data = rotatedData;
int tmp = width;
width = height;
height = tmp;
}
}
return data;
}
public int getRotationCount() {
int displayOrientation = mPreview.getDisplayOrientation();
return displayOrientation / 90;
}
}

View File

@@ -0,0 +1,37 @@
package me.dm7.barcodescanner.core;
import android.hardware.Camera;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
// This code is mostly based on the top answer here: http://stackoverflow.com/questions/18149964/best-use-of-handlerthread-over-other-similar-classes
public class CameraHandlerThread extends HandlerThread {
private static final String LOG_TAG = "CameraHandlerThread";
private BarcodeScannerView mScannerView;
public CameraHandlerThread(BarcodeScannerView scannerView) {
super("CameraHandlerThread");
mScannerView = scannerView;
start();
}
public void startCamera(final int cameraId) {
Handler localHandler = new Handler(getLooper());
localHandler.post(new Runnable() {
@Override
public void run() {
final Camera camera = CameraUtils.getCameraInstance(cameraId);
Handler mainHandler = new Handler(Looper.getMainLooper());
mainHandler.post(new Runnable() {
@Override
public void run() {
mScannerView.setupCameraPreview(CameraWrapper.getWrapper(camera, cameraId));
}
});
}
});
}
}

View File

@@ -0,0 +1,312 @@
package me.dm7.barcodescanner.core;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Point;
import android.hardware.Camera;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import java.util.List;
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = "CameraPreview";
private CameraWrapper mCameraWrapper;
private Handler mAutoFocusHandler;
private boolean mPreviewing = true;
private boolean mAutoFocus = true;
private boolean mSurfaceCreated = false;
private boolean mShouldScaleToFill = true;
private Camera.PreviewCallback mPreviewCallback;
private float mAspectTolerance = 0.1f;
public CameraPreview(Context context, CameraWrapper cameraWrapper, Camera.PreviewCallback previewCallback) {
super(context);
init(cameraWrapper, previewCallback);
}
public CameraPreview(Context context, AttributeSet attrs, CameraWrapper cameraWrapper, Camera.PreviewCallback previewCallback) {
super(context, attrs);
init(cameraWrapper, previewCallback);
}
public void init(CameraWrapper cameraWrapper, Camera.PreviewCallback previewCallback) {
setCamera(cameraWrapper, previewCallback);
mAutoFocusHandler = new Handler();
getHolder().addCallback(this);
getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void setCamera(CameraWrapper cameraWrapper, Camera.PreviewCallback previewCallback) {
mCameraWrapper = cameraWrapper;
mPreviewCallback = previewCallback;
}
public void setShouldScaleToFill(boolean scaleToFill) {
mShouldScaleToFill = scaleToFill;
}
public void setAspectTolerance(float aspectTolerance) {
mAspectTolerance = aspectTolerance;
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
mSurfaceCreated = true;
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
if(surfaceHolder.getSurface() == null) {
return;
}
stopCameraPreview();
showCameraPreview();
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
mSurfaceCreated = false;
stopCameraPreview();
}
public void showCameraPreview() {
if(mCameraWrapper != null) {
try {
getHolder().addCallback(this);
mPreviewing = true;
setupCameraParameters();
mCameraWrapper.mCamera.setPreviewDisplay(getHolder());
mCameraWrapper.mCamera.setDisplayOrientation(getDisplayOrientation());
mCameraWrapper.mCamera.setOneShotPreviewCallback(mPreviewCallback);
mCameraWrapper.mCamera.startPreview();
if(mAutoFocus) {
if (mSurfaceCreated) { // check if surface created before using autofocus
safeAutoFocus();
} else {
scheduleAutoFocus(); // wait 1 sec and then do check again
}
}
} catch (Exception e) {
Log.e(TAG, e.toString(), e);
}
}
}
public void safeAutoFocus() {
try {
mCameraWrapper.mCamera.autoFocus(autoFocusCB);
} catch (RuntimeException re) {
// Horrible hack to deal with autofocus errors on Sony devices
// See https://github.com/dm77/barcodescanner/issues/7 for example
scheduleAutoFocus(); // wait 1 sec and then do check again
}
}
public void stopCameraPreview() {
if(mCameraWrapper != null) {
try {
mPreviewing = false;
getHolder().removeCallback(this);
mCameraWrapper.mCamera.cancelAutoFocus();
mCameraWrapper.mCamera.setOneShotPreviewCallback(null);
mCameraWrapper.mCamera.stopPreview();
} catch(Exception e) {
Log.e(TAG, e.toString(), e);
}
}
}
public void setupCameraParameters() {
Camera.Size optimalSize = getOptimalPreviewSize();
Camera.Parameters parameters = mCameraWrapper.mCamera.getParameters();
parameters.setPreviewSize(optimalSize.width, optimalSize.height);
mCameraWrapper.mCamera.setParameters(parameters);
adjustViewSize(optimalSize);
}
private void adjustViewSize(Camera.Size cameraSize) {
Point previewSize = convertSizeToLandscapeOrientation(new Point(getWidth(), getHeight()));
float cameraRatio = ((float) cameraSize.width) / cameraSize.height;
float screenRatio = ((float) previewSize.x) / previewSize.y;
if (screenRatio > cameraRatio) {
setViewSize((int) (previewSize.y * cameraRatio), previewSize.y);
} else {
setViewSize(previewSize.x, (int) (previewSize.x / cameraRatio));
}
}
@SuppressWarnings("SuspiciousNameCombination")
private Point convertSizeToLandscapeOrientation(Point size) {
if (getDisplayOrientation() % 180 == 0) {
return size;
} else {
return new Point(size.y, size.x);
}
}
@SuppressWarnings("SuspiciousNameCombination")
private void setViewSize(int width, int height) {
ViewGroup.LayoutParams layoutParams = getLayoutParams();
int tmpWidth;
int tmpHeight;
if (getDisplayOrientation() % 180 == 0) {
tmpWidth = width;
tmpHeight = height;
} else {
tmpWidth = height;
tmpHeight = width;
}
if (mShouldScaleToFill) {
int parentWidth = ((View) getParent()).getWidth();
int parentHeight = ((View) getParent()).getHeight();
float ratioWidth = (float) parentWidth / (float) tmpWidth;
float ratioHeight = (float) parentHeight / (float) tmpHeight;
float compensation;
if (ratioWidth > ratioHeight) {
compensation = ratioWidth;
} else {
compensation = ratioHeight;
}
tmpWidth = Math.round(tmpWidth * compensation);
tmpHeight = Math.round(tmpHeight * compensation);
}
layoutParams.width = tmpWidth;
layoutParams.height = tmpHeight;
setLayoutParams(layoutParams);
}
public int getDisplayOrientation() {
if (mCameraWrapper == null) {
//If we don't have a camera set there is no orientation so return dummy value
return 0;
}
Camera.CameraInfo info = new Camera.CameraInfo();
if(mCameraWrapper.mCameraId == -1) {
Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, info);
} else {
Camera.getCameraInfo(mCameraWrapper.mCameraId, info);
}
WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int rotation = display.getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0: degrees = 0; break;
case Surface.ROTATION_90: degrees = 90; break;
case Surface.ROTATION_180: degrees = 180; break;
case Surface.ROTATION_270: degrees = 270; break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
return result;
}
private Camera.Size getOptimalPreviewSize() {
if(mCameraWrapper == null) {
return null;
}
List<Camera.Size> sizes = mCameraWrapper.mCamera.getParameters().getSupportedPreviewSizes();
int w = getWidth();
int h = getHeight();
if (DisplayUtils.getScreenOrientation(getContext()) == Configuration.ORIENTATION_PORTRAIT) {
int portraitWidth = h;
h = w;
w = portraitWidth;
}
double targetRatio = (double) w / h;
if (sizes == null) return null;
Camera.Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
// Try to find an size match aspect ratio and size
for (Camera.Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > mAspectTolerance) continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
// Cannot find the one match the aspect ratio, ignore the requirement
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Camera.Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
public void setAutoFocus(boolean state) {
if(mCameraWrapper != null && mPreviewing) {
if(state == mAutoFocus) {
return;
}
mAutoFocus = state;
if(mAutoFocus) {
if (mSurfaceCreated) { // check if surface created before using autofocus
Log.v(TAG, "Starting autofocus");
safeAutoFocus();
} else {
scheduleAutoFocus(); // wait 1 sec and then do check again
}
} else {
Log.v(TAG, "Cancelling autofocus");
mCameraWrapper.mCamera.cancelAutoFocus();
}
}
}
private Runnable doAutoFocus = new Runnable() {
public void run() {
if(mCameraWrapper != null && mPreviewing && mAutoFocus && mSurfaceCreated) {
safeAutoFocus();
}
}
};
// Mimic continuous auto-focusing
Camera.AutoFocusCallback autoFocusCB = new Camera.AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
scheduleAutoFocus();
}
};
private void scheduleAutoFocus() {
mAutoFocusHandler.postDelayed(doAutoFocus, 1000);
}
}

View File

@@ -0,0 +1,63 @@
package me.dm7.barcodescanner.core;
import android.hardware.Camera;
import java.util.List;
public class CameraUtils {
/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance() {
return getCameraInstance(getDefaultCameraId());
}
/** Favor back-facing camera by default. If none exists, fallback to whatever camera is available **/
public static int getDefaultCameraId() {
int numberOfCameras = Camera.getNumberOfCameras();
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
int defaultCameraId = -1;
for (int i = 0; i < numberOfCameras; i++) {
defaultCameraId = i;
Camera.getCameraInfo(i, cameraInfo);
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
return i;
}
}
return defaultCameraId;
}
/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(int cameraId) {
Camera c = null;
try {
if(cameraId == -1) {
c = Camera.open(); // attempt to get a Camera instance
} else {
c = Camera.open(cameraId); // attempt to get a Camera instance
}
}
catch (Exception e) {
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
public static boolean isFlashSupported(Camera camera) {
/* Credits: Top answer at http://stackoverflow.com/a/19599365/868173 */
if (camera != null) {
Camera.Parameters parameters = camera.getParameters();
if (parameters.getFlashMode() == null) {
return false;
}
List<String> supportedFlashModes = parameters.getSupportedFlashModes();
if (supportedFlashModes == null || supportedFlashModes.isEmpty() || supportedFlashModes.size() == 1 && supportedFlashModes.get(0).equals(Camera.Parameters.FLASH_MODE_OFF)) {
return false;
}
} else {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,23 @@
package me.dm7.barcodescanner.core;
import android.hardware.Camera;
import androidx.annotation.NonNull;
public class CameraWrapper {
public final Camera mCamera;
public final int mCameraId;
private CameraWrapper(@NonNull Camera camera, int cameraId) {
this.mCamera = camera;
this.mCameraId = cameraId;
}
public static CameraWrapper getWrapper(Camera camera, int cameraId) {
if (camera == null) {
return null;
} else {
return new CameraWrapper(camera, cameraId);
}
}
}

View File

@@ -0,0 +1,41 @@
package me.dm7.barcodescanner.core;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Point;
import android.view.Display;
import android.view.WindowManager;
public class DisplayUtils {
public static Point getScreenResolution(Context context) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point screenResolution = new Point();
if (android.os.Build.VERSION.SDK_INT >= 13) {
display.getSize(screenResolution);
} else {
screenResolution.set(display.getWidth(), display.getHeight());
}
return screenResolution;
}
public static int getScreenOrientation(Context context)
{
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int orientation = Configuration.ORIENTATION_UNDEFINED;
if(display.getWidth()==display.getHeight()){
orientation = Configuration.ORIENTATION_SQUARE;
} else{
if(display.getWidth() < display.getHeight()){
orientation = Configuration.ORIENTATION_PORTRAIT;
}else {
orientation = Configuration.ORIENTATION_LANDSCAPE;
}
}
return orientation;
}
}

View File

@@ -0,0 +1,53 @@
package me.dm7.barcodescanner.core;
import android.graphics.Rect;
public interface IViewFinder {
void setLaserColor(int laserColor);
void setMaskColor(int maskColor);
void setBorderColor(int borderColor);
void setBorderStrokeWidth(int borderStrokeWidth);
void setBorderLineLength(int borderLineLength);
void setLaserEnabled(boolean isLaserEnabled);
void setBorderCornerRounded(boolean isBorderCornersRounded);
void setBorderAlpha(float alpha);
void setBorderCornerRadius(int borderCornersRadius);
void setViewFinderOffset(int offset);
void setSquareViewFinder(boolean isSquareViewFinder);
/**
* Method that executes when Camera preview is starting.
* It is recommended to update framing rect here and invalidate view after that. <br/>
* For example see: {@link ViewFinderView#setupViewFinder()}
*/
void setupViewFinder();
/**
* Provides {@link Rect} that identifies area where barcode scanner can detect visual codes
* <p>Note: This rect is a area representation in absolute pixel values. <br/>
* For example: <br/>
* If View's size is 1024x800 so framing rect might be 500x400</p>
*
* @return {@link Rect} that identifies barcode scanner area
*/
Rect getFramingRect();
/**
* Width of a {@link android.view.View} that implements this interface
* <p>Note: this is already implemented in {@link android.view.View},
* so you don't need to override method and provide your implementation</p>
*
* @return width of a view
*/
int getWidth();
/**
* Height of a {@link android.view.View} that implements this interface
* <p>Note: this is already implemented in {@link android.view.View},
* so you don't need to override method and provide your implementation</p>
*
* @return height of a view
*/
int getHeight();
}

View File

@@ -0,0 +1,259 @@
package me.dm7.barcodescanner.core;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.CornerPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
public class ViewFinderView extends View implements IViewFinder {
private static final String TAG = "ViewFinderView";
private Rect mFramingRect;
private static final float PORTRAIT_WIDTH_RATIO = 6f/8;
private static final float PORTRAIT_WIDTH_HEIGHT_RATIO = 0.75f;
private static final float LANDSCAPE_HEIGHT_RATIO = 5f/8;
private static final float LANDSCAPE_WIDTH_HEIGHT_RATIO = 1.4f;
private static final int MIN_DIMENSION_DIFF = 50;
private static final float DEFAULT_SQUARE_DIMENSION_RATIO = 5f / 8;
private static final int[] SCANNER_ALPHA = {0, 64, 128, 192, 255, 192, 128, 64};
private int scannerAlpha;
private static final int POINT_SIZE = 10;
private static final long ANIMATION_DELAY = 80l;
private final int mDefaultLaserColor = getResources().getColor(R.color.viewfinder_laser);
private final int mDefaultMaskColor = getResources().getColor(R.color.viewfinder_mask);
private final int mDefaultBorderColor = getResources().getColor(R.color.viewfinder_border);
private final int mDefaultBorderStrokeWidth = getResources().getInteger(R.integer.viewfinder_border_width);
private final int mDefaultBorderLineLength = getResources().getInteger(R.integer.viewfinder_border_length);
protected Paint mLaserPaint;
protected Paint mFinderMaskPaint;
protected Paint mBorderPaint;
protected int mBorderLineLength;
protected boolean mSquareViewFinder;
private boolean mIsLaserEnabled;
private float mBordersAlpha;
private int mViewFinderOffset = 0;
public ViewFinderView(Context context) {
super(context);
init();
}
public ViewFinderView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
init();
}
private void init() {
//set up laser paint
mLaserPaint = new Paint();
mLaserPaint.setColor(mDefaultLaserColor);
mLaserPaint.setStyle(Paint.Style.FILL);
//finder mask paint
mFinderMaskPaint = new Paint();
mFinderMaskPaint.setColor(mDefaultMaskColor);
//border paint
mBorderPaint = new Paint();
mBorderPaint.setColor(mDefaultBorderColor);
mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setStrokeWidth(mDefaultBorderStrokeWidth);
mBorderPaint.setAntiAlias(true);
mBorderLineLength = mDefaultBorderLineLength;
}
@Override
public void setLaserColor(int laserColor) {
mLaserPaint.setColor(laserColor);
}
@Override
public void setMaskColor(int maskColor) {
mFinderMaskPaint.setColor(maskColor);
}
@Override
public void setBorderColor(int borderColor) {
mBorderPaint.setColor(borderColor);
}
@Override
public void setBorderStrokeWidth(int borderStrokeWidth) {
mBorderPaint.setStrokeWidth(borderStrokeWidth);
}
@Override
public void setBorderLineLength(int borderLineLength) {
mBorderLineLength = borderLineLength;
}
@Override
public void setLaserEnabled(boolean isLaserEnabled) { mIsLaserEnabled = isLaserEnabled; }
@Override
public void setBorderCornerRounded(boolean isBorderCornersRounded) {
if (isBorderCornersRounded) {
mBorderPaint.setStrokeJoin(Paint.Join.ROUND);
} else {
mBorderPaint.setStrokeJoin(Paint.Join.BEVEL);
}
}
@Override
public void setBorderAlpha(float alpha) {
int colorAlpha = (int) (255 * alpha);
mBordersAlpha = alpha;
mBorderPaint.setAlpha(colorAlpha);
}
@Override
public void setBorderCornerRadius(int borderCornersRadius) {
mBorderPaint.setPathEffect(new CornerPathEffect(borderCornersRadius));
}
@Override
public void setViewFinderOffset(int offset) {
mViewFinderOffset = offset;
}
// TODO: Need a better way to configure this. Revisit when working on 2.0
@Override
public void setSquareViewFinder(boolean set) {
mSquareViewFinder = set;
}
public void setupViewFinder() {
updateFramingRect();
invalidate();
}
public Rect getFramingRect() {
return mFramingRect;
}
@Override
public void onDraw(Canvas canvas) {
if(getFramingRect() == null) {
return;
}
drawViewFinderMask(canvas);
drawViewFinderBorder(canvas);
if (mIsLaserEnabled) {
drawLaser(canvas);
}
}
public void drawViewFinderMask(Canvas canvas) {
int width = canvas.getWidth();
int height = canvas.getHeight();
Rect framingRect = getFramingRect();
canvas.drawRect(0, 0, width, framingRect.top, mFinderMaskPaint);
canvas.drawRect(0, framingRect.top, framingRect.left, framingRect.bottom + 1, mFinderMaskPaint);
canvas.drawRect(framingRect.right + 1, framingRect.top, width, framingRect.bottom + 1, mFinderMaskPaint);
canvas.drawRect(0, framingRect.bottom + 1, width, height, mFinderMaskPaint);
}
public void drawViewFinderBorder(Canvas canvas) {
Rect framingRect = getFramingRect();
// Top-left corner
Path path = new Path();
path.moveTo(framingRect.left, framingRect.top + mBorderLineLength);
path.lineTo(framingRect.left, framingRect.top);
path.lineTo(framingRect.left + mBorderLineLength, framingRect.top);
canvas.drawPath(path, mBorderPaint);
// Top-right corner
path.moveTo(framingRect.right, framingRect.top + mBorderLineLength);
path.lineTo(framingRect.right, framingRect.top);
path.lineTo(framingRect.right - mBorderLineLength, framingRect.top);
canvas.drawPath(path, mBorderPaint);
// Bottom-right corner
path.moveTo(framingRect.right, framingRect.bottom - mBorderLineLength);
path.lineTo(framingRect.right, framingRect.bottom);
path.lineTo(framingRect.right - mBorderLineLength, framingRect.bottom);
canvas.drawPath(path, mBorderPaint);
// Bottom-left corner
path.moveTo(framingRect.left, framingRect.bottom - mBorderLineLength);
path.lineTo(framingRect.left, framingRect.bottom);
path.lineTo(framingRect.left + mBorderLineLength, framingRect.bottom);
canvas.drawPath(path, mBorderPaint);
}
public void drawLaser(Canvas canvas) {
Rect framingRect = getFramingRect();
// Draw a red "laser scanner" line through the middle to show decoding is active
mLaserPaint.setAlpha(SCANNER_ALPHA[scannerAlpha]);
scannerAlpha = (scannerAlpha + 1) % SCANNER_ALPHA.length;
int middle = framingRect.height() / 2 + framingRect.top;
canvas.drawRect(framingRect.left + 2, middle - 1, framingRect.right - 1, middle + 2, mLaserPaint);
postInvalidateDelayed(ANIMATION_DELAY,
framingRect.left - POINT_SIZE,
framingRect.top - POINT_SIZE,
framingRect.right + POINT_SIZE,
framingRect.bottom + POINT_SIZE);
}
@Override
protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld) {
updateFramingRect();
}
public synchronized void updateFramingRect() {
Point viewResolution = new Point(getWidth(), getHeight());
int width;
int height;
int orientation = DisplayUtils.getScreenOrientation(getContext());
if(mSquareViewFinder) {
if(orientation != Configuration.ORIENTATION_PORTRAIT) {
height = (int) (getHeight() * DEFAULT_SQUARE_DIMENSION_RATIO);
width = height;
} else {
width = (int) (getWidth() * DEFAULT_SQUARE_DIMENSION_RATIO);
height = width;
}
} else {
if(orientation != Configuration.ORIENTATION_PORTRAIT) {
height = (int) (getHeight() * LANDSCAPE_HEIGHT_RATIO);
width = (int) (LANDSCAPE_WIDTH_HEIGHT_RATIO * height);
} else {
width = (int) (getWidth() * PORTRAIT_WIDTH_RATIO);
height = (int) (PORTRAIT_WIDTH_HEIGHT_RATIO * width);
}
}
if(width > getWidth()) {
width = getWidth() - MIN_DIMENSION_DIFF;
}
if(height > getHeight()) {
height = getHeight() - MIN_DIMENSION_DIFF;
}
int leftOffset = (viewResolution.x - width) / 2;
int topOffset = (viewResolution.y - height) / 2;
mFramingRect = new Rect(leftOffset + mViewFinderOffset, topOffset + mViewFinderOffset, leftOffset + width - mViewFinderOffset, topOffset + height - mViewFinderOffset);
}
}

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="viewfinder_border_width">4</integer>
<integer name="viewfinder_border_length">60</integer>
</resources>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="viewfinder_border_width">5</integer>
<integer name="viewfinder_border_length">80</integer>
</resources>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="viewfinder_border_width">6</integer>
<integer name="viewfinder_border_length">100</integer>
</resources>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="BarcodeScannerView">
<attr name="shouldScaleToFill" format="boolean" />
<attr name="laserEnabled" format="boolean" />
<attr name="laserColor" format="color" />
<attr name="borderColor" format="color" />
<attr name="maskColor" format="color" />
<attr name="borderWidth" format="dimension" />
<attr name="borderLength" format="dimension" />
<attr name="roundedCorner" format="boolean" />
<attr name="cornerRadius" format="dimension" />
<attr name="squaredFinder" format="boolean" />
<attr name="borderAlpha" format="float" />
<attr name="finderOffset" format="dimension" />
</declare-styleable>
</resources>

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