432 Commits

Author SHA1 Message Date
Balazs Toldi
8a9102bc8a Check the user token when opening the app 2024-01-04 11:03:29 +01:00
Balazs Toldi
40a9091b7d Scaled and Controversial sort types 2024-01-03 14:28:28 +01:00
Balazs Toldi
af7148ce58 Removed IzzyOnDroid badge 2024-01-02 18:38:26 +01:00
Balazs Toldi
ff0bacff1d Fix "share on local instance" option for post pages 2024-01-02 18:37:24 +01:00
Balazs Toldi
083bde8149 Merge remote-tracking branch 'origin/master' 2023-11-10 22:16:14 +01:00
Balazs Toldi
ff3ccca3eb Minor fix to comment filters 2023-11-10 11:01:35 +01:00
Fjuro
b4569d56e6 Translated using Weblate (Czech)
Currently translated at 100.0% (1311 of 1311 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/cs/
2023-11-10 09:42:39 +00:00
Balazs Toldi
0b1171c5b2 Fix reddit link handling
This Eternity should not attempt to open Reddit links as it's for Lemmy, not Reddit. Instead, they should be handled as regular links. If a reddit app is installed (e.g. Infinity) it should use that app instead.

Closes #213
2023-11-10 10:31:48 +01:00
Balazs Toldi
48776d28bb Show a bin icon on deleted posts 2023-11-10 10:19:48 +01:00
SomeTr
88f932ad5a Translated using Weblate (Ukrainian)
Currently translated at 99.5% (1305 of 1311 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/uk/
2023-11-10 06:50:09 +00:00
SomeTr
8bb8bf3b31 Translated using Weblate (Ukrainian)
Currently translated at 99.5% (1304 of 1310 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/uk/
2023-11-10 06:50:09 +00:00
Fjuro
23a40f27c7 Translated using Weblate (Czech)
Currently translated at 100.0% (1310 of 1310 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/cs/
2023-11-10 06:50:09 +00:00
SomeTr
0a30fdfb27 Translated using Weblate (Ukrainian)
Currently translated at 99.5% (1302 of 1308 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/uk/
2023-11-10 06:50:09 +00:00
SomeTr
f6c95b27b4 Translated using Weblate (Ukrainian)
Currently translated at 99.1% (1297 of 1308 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/uk/
2023-11-10 06:50:08 +00:00
Bazsalanszky
384543824d Translated using Weblate (English)
Currently translated at 100.0% (1308 of 1308 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/en/
2023-11-10 06:50:08 +00:00
Codeberg Translate
de2a6351c7 Update translation files
Updated by "Remove blank strings" hook in Weblate.

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/
2023-11-10 06:50:08 +00:00
Balazs Toldi
25495b737a Merge remote-tracking branch 'origin/master' 2023-11-10 07:50:01 +01:00
Balazs Toldi
e5ffaf3d97 Fix cross posting
Closes #222
2023-11-10 07:49:52 +01:00
Bazsalanszky
48d41103b6 Update .gitea/issue_template/feature_request.md 2023-11-10 06:43:40 +00:00
Bazsalanszky
04a60211c6 Add .gitea/issue_template/feature_request.md 2023-11-10 06:39:47 +00:00
Balazs Toldi
55f4689984 Auto-complete feature for the login page
This commit adds an auto-complete feature to select the users instance. It fetches all the instances from lemmyverse.net so everyone can find their instance :)

Closes #38
2023-11-09 20:17:55 +01:00
Balazs Toldi
9f02969dd2 Add u/HostileEnemy to credits page
Seriously? Why wasn't this there in the first release?!
2023-11-09 19:19:31 +01:00
Balazs Toldi
fd833a65c5 Fix text issues on post detail activity post without preview page 2023-11-09 19:10:12 +01:00
Balazs Toldi
16dfc65c64 Fixing issues with reading info for kbin magazines
This commit fixes the issue where the information for Kbin/Mbin magazines weren't displayed properly on community pages. The problem was related to magazines having a different actor id (/m/ instead of /c/)

Closes #182
2023-11-08 13:19:28 +01:00
Balazs Toldi
67115e0dd6 Fixing weblate 2023-11-07 16:48:37 +01:00
Balazs Toldi
5f6b966160 Merge remote-tracking branch 'weblate/master'
# Conflicts:
#	app/src/main/res/values-de/strings.xml
#	app/src/main/res/values-tr-rTR/strings.xml
2023-11-07 16:41:44 +01:00
Sergio Varela
4a200d7343 Translated using Weblate (Spanish)
Currently translated at 89.7% (1128 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/es/
2023-11-07 13:20:17 +00:00
Balazs Toldi
aa75fb5592 Fix crash when opening a comment from a user tab
This seems more of a workaround than a fix.
2023-11-07 14:20:09 +01:00
Embark9962
5618e2e88b Translated using Weblate (German)
Currently translated at 100.0% (1257 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/de/
2023-11-06 15:13:38 +00:00
Balazs Toldi
03ee3899d7 Do not load inline images in data-saving mode 2023-11-05 16:49:11 +01:00
Balazs Toldi
6b09f0379c Fix crash related to the "swipe between posts" options
There was a null pointer execution because it did not check for a null value.
2023-11-05 16:19:51 +01:00
Bazsalanszky
fe565d2ef3 Merge pull request 'Updates from upstream' (#218) from infinity-update into master
Reviewed-on: https://codeberg.org/Bazsalanszky/Eternity/pulls/218
2023-11-05 14:19:56 +00:00
Balazs Toldi
14e568e642 Fix translation related compilation errors 2023-11-05 15:09:09 +01:00
Balazs Toldi
ec3b89a056 Fix crashes originating form merging updates from upstream 2023-11-05 14:38:05 +01:00
Balazs Toldi
343484aff2 Eternity (placeholder?) "branding" on splash screen 2023-11-05 12:22:54 +01:00
artnay
ec7ef689c9 Translated using Weblate (Finnish)
Currently translated at 50.7% (638 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/fi/
2023-11-02 17:13:38 +00:00
SomeTr
312a768351 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (1257 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/uk/
2023-11-02 17:13:38 +00:00
SomeTr
c4992aac74 Translated using Weblate (Portuguese)
Currently translated at 98.8% (1242 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/pt/
2023-11-02 17:13:38 +00:00
SomeTr
df37db5fed Translated using Weblate (Hindi)
Currently translated at 70.1% (882 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/hi/
2023-11-02 17:13:37 +00:00
SomeTr
d699e3a434 Translated using Weblate (Romanian)
Currently translated at 99.7% (1254 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/ro/
2023-10-31 18:10:35 +00:00
Bazsalanszky
c111ee35b4 Translated using Weblate (Hungarian)
Currently translated at 85.4% (1074 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/hu/
2023-10-31 18:10:35 +00:00
SomeTr
766c2dc2c5 Translated using Weblate (Spanish)
Currently translated at 89.6% (1127 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/es/
2023-10-31 18:10:35 +00:00
SomeTr
ec484cd51d Translated using Weblate (Vietnamese)
Currently translated at 88.0% (1107 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/vi/
2023-10-31 18:10:35 +00:00
0que
494545500f Translated using Weblate (Russian)
Currently translated at 99.5% (1251 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/ru/
2023-10-31 18:10:35 +00:00
SomeTr
db9c7a77e5 Translated using Weblate (Italian)
Currently translated at 91.2% (1147 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/it/
2023-10-31 18:10:35 +00:00
SomeTr
5a2954b432 Translated using Weblate (Hungarian)
Currently translated at 81.3% (1023 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/hu/
2023-10-31 18:10:34 +00:00
SomeTr
751c2bd421 Translated using Weblate (Chinese (Simplified))
Currently translated at 88.7% (1115 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/zh_Hans/
2023-10-31 18:10:34 +00:00
SomeTr
3940f9b402 Translated using Weblate (Vietnamese)
Currently translated at 88.0% (1107 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/vi/
2023-10-31 18:10:34 +00:00
SomeTr
dd72afc115 Translated using Weblate (Turkish)
Currently translated at 89.8% (1130 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/tr/
2023-10-31 18:10:34 +00:00
SomeTr
7c87bf19d2 Translated using Weblate (Romanian)
Currently translated at 99.7% (1254 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/ro/
2023-10-31 18:10:34 +00:00
SomeTr
3d5d26f6ec Translated using Weblate (Portuguese (Brazil))
Currently translated at 98.1% (1234 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/pt_BR/
2023-10-31 18:10:34 +00:00
SomeTr
12eec8cc6b Translated using Weblate (Polish)
Currently translated at 88.3% (1110 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/pl/
2023-10-31 18:10:34 +00:00
SomeTr
1d17b4be9e Translated using Weblate (Dutch)
Currently translated at 81.6% (1026 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/nl/
2023-10-31 18:10:34 +00:00
SomeTr
4896aad901 Translated using Weblate (Japanese)
Currently translated at 78.3% (985 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/ja/
2023-10-31 18:10:34 +00:00
SomeTr
46b6ab82d5 Translated using Weblate (Italian)
Currently translated at 91.3% (1148 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/it/
2023-10-31 18:10:34 +00:00
SomeTr
523db3c659 Translated using Weblate (Hungarian)
Currently translated at 81.4% (1024 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/hu/
2023-10-31 18:10:34 +00:00
SomeTr
4614ee0ae2 Translated using Weblate (Croatian)
Currently translated at 71.7% (902 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/hr/
2023-10-31 18:10:34 +00:00
SomeTr
a874b9b455 Translated using Weblate (Hindi)
Currently translated at 70.0% (880 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/hi/
2023-10-31 18:10:34 +00:00
SomeTr
998e4dd802 Translated using Weblate (Spanish)
Currently translated at 89.5% (1126 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/es/
2023-10-31 18:10:34 +00:00
SomeTr
cca17e0e81 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (1257 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/uk/
2023-10-31 18:10:34 +00:00
artnay
f9deaccb5a Translated using Weblate (Finnish)
Currently translated at 50.6% (637 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/fi/
2023-10-31 18:10:34 +00:00
Fjuro
04a9679429 Translated using Weblate (Czech)
Currently translated at 100.0% (1257 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/cs/
2023-10-31 18:10:34 +00:00
SomeTr
caffec6b2a Translated using Weblate (Ukrainian)
Currently translated at 100.0% (1257 of 1257 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/uk/
2023-10-31 18:10:34 +00:00
SomeTr
17c98e85ac Translated using Weblate (Ukrainian)
Currently translated at 100.0% (1255 of 1255 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/uk/
2023-10-31 18:10:34 +00:00
SomeTr
2c46ac079c Translated using Weblate (Croatian)
Currently translated at 71.9% (903 of 1255 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/hr/
2023-10-31 18:10:34 +00:00
SomeTr
95b4325f3e Translated using Weblate (Hindi)
Currently translated at 70.1% (881 of 1255 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/hi/
2023-10-31 18:10:34 +00:00
SomeTr
673d717ef1 Translated using Weblate (Spanish)
Currently translated at 89.8% (1127 of 1255 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/es/
2023-10-31 18:10:34 +00:00
Fjuro
8c9460c6c0 Translated using Weblate (Czech)
Currently translated at 100.0% (1255 of 1255 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/cs/
2023-10-31 18:10:34 +00:00
scharnkn
b1d1f7ec72 Translated using Weblate (German)
Currently translated at 100.0% (1254 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/de/
2023-10-31 18:10:34 +00:00
dieserniko
7d394d5a13 Translated using Weblate (German)
Currently translated at 100.0% (1254 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/de/
2023-10-31 18:10:34 +00:00
SomeTr
e07ffc69ed Translated using Weblate (Turkish)
Currently translated at 90.2% (1132 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/tr/
2023-10-31 18:10:34 +00:00
SomeTr
80f7d1e331 Translated using Weblate (Polish)
Currently translated at 88.5% (1110 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/pl/
2023-10-31 18:10:34 +00:00
SomeTr
f06775de4b Translated using Weblate (Japanese)
Currently translated at 78.7% (987 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/ja/
2023-10-31 18:10:34 +00:00
SomeTr
2184d73e3e Translated using Weblate (Spanish)
Currently translated at 89.8% (1127 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/es/
2023-10-31 18:10:34 +00:00
SomeTr
0ff2e70867 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (1254 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/uk/
2023-10-31 18:10:34 +00:00
alextecplayz
e7e83946eb Translated using Weblate (Romanian)
Currently translated at 100.0% (1254 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/ro/
2023-10-31 18:10:34 +00:00
Frederik Zorn
2de2614d6f Translated using Weblate (German)
Currently translated at 100.0% (1254 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/de/
2023-10-31 18:10:34 +00:00
Eryk Michalak
67349a134d Translated using Weblate (Polish)
Currently translated at 88.5% (1111 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/pl/
2023-10-31 18:10:34 +00:00
artnay
25caea0b72 Translated using Weblate (Finnish)
Currently translated at 50.3% (632 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/fi/
2023-10-31 18:10:34 +00:00
scharnkn
5522884bb2 Translated using Weblate (German)
Currently translated at 99.8% (1252 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/de/
2023-10-31 18:10:34 +00:00
functional-tim
9de9ba19e7 Translated using Weblate (German)
Currently translated at 99.8% (1252 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/de/
2023-10-31 18:10:34 +00:00
Hartmut Goebel
05f1f929e1 Translated using Weblate (German)
Currently translated at 99.8% (1252 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/de/
2023-10-31 18:10:34 +00:00
scharnkn
ab6573b3cf Translated using Weblate (German)
Currently translated at 99.3% (1246 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/de/
2023-10-31 18:10:33 +00:00
Hartmut Goebel
7ba12262ca Translated using Weblate (German)
Currently translated at 99.3% (1246 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/de/
2023-10-31 18:10:33 +00:00
artnay
82f5be2568 Translated using Weblate (Finnish)
Currently translated at 48.5% (609 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/fi/
2023-10-31 18:10:33 +00:00
artnay
e33b4a3ec6 Added translation using Weblate (Finnish) 2023-10-31 18:10:33 +00:00
edxkl
40f28071d6 Translated using Weblate (Portuguese (Brazil))
Currently translated at 98.4% (1234 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/pt_BR/
2023-10-31 18:10:33 +00:00
tubbadu
2783bcd1e4 Translated using Weblate (Italian)
Currently translated at 91.5% (1148 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/it/
2023-10-31 18:10:33 +00:00
evmexa-prog
3e9db084b0 Translated using Weblate (Russian)
Currently translated at 99.5% (1248 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/ru/
2023-10-31 18:10:33 +00:00
alextecplayz
a648993f78 Translated using Weblate (Romanian)
Currently translated at 91.8% (1152 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/ro/
2023-10-31 18:10:33 +00:00
edxkl
75416b8b1b Translated using Weblate (Portuguese (Brazil))
Currently translated at 98.3% (1233 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/pt_BR/
2023-10-31 18:10:33 +00:00
JnkLtt
6f273d5e58 Translated using Weblate (German)
Currently translated at 98.6% (1237 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/de/
2023-10-31 18:10:33 +00:00
functional-tim
8654512584 Translated using Weblate (German)
Currently translated at 98.6% (1237 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/de/
2023-10-31 18:10:33 +00:00
scharnkn
46b2e0b816 Translated using Weblate (German)
Currently translated at 98.6% (1237 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/de/
2023-10-31 18:10:33 +00:00
genoxidedev1
d708ef5300 Translated using Weblate (German)
Currently translated at 98.6% (1237 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/de/
2023-10-31 18:10:33 +00:00
botorfj
9c8c667c41 Translated using Weblate (Turkish)
Currently translated at 90.3% (1133 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/tr/
2023-10-31 18:10:33 +00:00
SomeTr
ff270e6895 Translated using Weblate (Ukrainian)
Currently translated at 99.9% (1253 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/uk/
2023-10-31 18:10:33 +00:00
0que
7869bd3b2b Translated using Weblate (Russian)
Currently translated at 99.4% (1247 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/ru/
2023-10-31 18:10:33 +00:00
American_Jesus
36d932e9fe Translated using Weblate (Portuguese)
Currently translated at 99.0% (1242 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/pt/
2023-10-31 18:10:33 +00:00
edxkl
5b2f3eb9b4 Translated using Weblate (Portuguese (Brazil))
Currently translated at 98.1% (1231 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/pt_BR/
2023-10-31 18:10:33 +00:00
julroy67
ddb1d6746b Translated using Weblate (French)
Currently translated at 100.0% (1254 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/fr/
2023-10-31 18:10:33 +00:00
Fjuro
f2440e0e2e Translated using Weblate (Czech)
Currently translated at 100.0% (1254 of 1254 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/cs/
2023-10-31 18:10:33 +00:00
Balazs Toldi
af6245eed7 Added a 'Get it on Fdroid' badge to the readme
Hurray! Eternity is on F-droid now!!

Signed-off-by: Balazs Toldi <balazs@toldi.eu>
2023-10-31 19:10:20 +01:00
Balazs Toldi
4397e09016 Merge changes from Infinity
This commit merges the changes that were made in the upstream infinity repo
2023-10-27 15:10:00 +02:00
Bazsalanszky
262d9f02ba Merge pull request 'Reproducible build fix' (#208) from reproducible-build-tests into master
Reviewed-on: https://codeberg.org/Bazsalanszky/Eternity/pulls/208
2023-10-26 06:12:17 +00:00
Bazsalanszky
45b0399766 Merge branch 'master' into reproducible-build-tests 2023-10-26 06:11:47 +00:00
Balazs Toldi
3bee0deb11 Reproducible build fix 2023-10-26 08:05:23 +02:00
Bazsalanszky
27a7b96ffb Merge pull request 'Fix typo in translation section' (#207) from inovvia/Eternity:FixReadMeTypo into master
Reviewed-on: https://codeberg.org/Bazsalanszky/Eternity/pulls/207
Reviewed-by: Bazsalanszky <bazsalanszky@noreply.codeberg.org>
2023-10-25 07:02:41 +00:00
John Matthew Marquez
11a845e21c Fix typo in translation section 2023-10-25 14:59:41 +08:00
Balazs Toldi
6d6a79bcb6 Fix python script in the build process 2023-10-24 21:23:23 +02:00
Balazs Toldi
6ff46f928a Bump version 2023-10-24 20:37:17 +02:00
Balazs Toldi
81e1c73c65 Fix the updating part of the community saving
In a previous commit, I've added a code snippet that made an update query for each fetched summary that is already in the internal database. However, it did not take in to account that the same community can be related to different accounts. This commit fixes this issue by adding an additional filter to the update db query.
2023-10-24 18:58:41 +02:00
Balazs Toldi
554dfff4ad Always add the access token to the retrofit holder
This hopefully eliminates any login related issues on Lemmy 0.19
2023-10-24 18:51:32 +02:00
Balazs Toldi
741ec08386 Minor fix to updating subscribed communities
Previously, the app did not update any changes to a community after subscribing to it. Now the internal db is updated each time the list of subscribers is refreshed.
2023-10-22 18:40:01 +02:00
Balazs Toldi
f8a21fa3ba Add credits to the new icon 2023-10-22 18:26:46 +02:00
Balazs Toldi
fd6bc82214 Make icon toggleable
This commit adds an option to choose between the original and the new icon
2023-10-22 09:51:30 +02:00
Balazs Toldi
0ae8826732 Add the new icon 2023-10-22 09:03:44 +02:00
Balazs Toldi
5311edc404 Add new icon to README and fastlane 2023-10-20 11:38:20 +02:00
Balazs Toldi
d8dc8c39b2 Update README and fastlane description 2023-10-20 11:35:05 +02:00
Balazs Toldi
c43ced8b00 Merge Reproducible Builds
This commit makes release builds reproducible. This will help folks update the app from F-Droid when it's released there.
2023-10-20 09:31:53 +02:00
Balazs Toldi
908f294130 Fix issue with marking as read when swiping
This commit fixes the issue where the 'swiping between posts' and 'mark post as read' options are enable. Previously, it only marked the first post as read, and not the ones that were swiped to. Now, all posts are marked read in these scenarios.
Signed-off-by: Balazs Toldi <balazs@toldi.eu>
2023-10-19 08:18:14 +02:00
Balazs Toldi
95408f8125 Fix link for translation
Signed-off-by: Balazs Toldi <balazs@toldi.eu>
2023-10-16 18:58:49 +02:00
Balazs Toldi
6d5ba059f8 Fixing issue with swiping to see new posts.
This commit fixes the issue with Fetching new posts when swiping on the post detail page.
2023-10-13 18:21:37 +02:00
Balazs Toldi
ecdd9da9c8 Fix issue where display name makes impossible to load saved things
This commit fixes an issue where the display name of a user makes it
impossible to load saved things. The problem is that the display name
was used in the url to load the saved things instead of the username.

Closes #179

Signed-off-by: Balazs Toldi <balazs@toldi.eu>
2023-10-12 09:16:56 +02:00
Balazs Toldi
1c17e6b7d2 Fix some issues with the "goto User" and "goto Community" options
This commit allows the user to input the communities with their "!" prefix. Similarly, it also allows the "@" prefix for users when trying to navigate to them with their corresponding "go to" options.

Also fixes issues with these options in the Community and User pages.
2023-10-12 08:26:50 +02:00
Balazs Toldi
9f60eca225 Fix crash when trying to open the community lists in some cases.
In some cases the app crashed when trying to select a community. This commit attempts to fix this issue
2023-10-12 08:08:02 +02:00
Balazs Toldi
9deba8b10e Fixing some sort type issues
This commit fixes issues where the sort type/time isn't loaded properly and the app resets back to NEW on the frontpage and Hot on Community pages.

Heads up: You might need to change the sort type in your settings if you see any issues.
2023-10-12 08:06:06 +02:00
Balazs Toldi
05948d74f4 Fix authentication when opening the app 2023-10-11 14:00:07 +02:00
Balazs Toldi
1007be50f8 Fix autherntiction on first logging in to Lemmy 0.19 2023-10-11 13:56:14 +02:00
Balazs Toldi
28617cf9a8 Compatibility for Lemmy 0.19
Closes #197
2023-10-06 12:56:33 +02:00
Bazsalanszky
5d2d43eebc Merge pull request 'Add preview to RedGIFs posts' (#187) from tinsukE/Eternity:regifs-preview into master
Reviewed-on: https://codeberg.org/Bazsalanszky/Eternity/pulls/187
Reviewed-by: Bazsalanszky <bazsalanszky@noreply.codeberg.org>
2023-10-06 06:15:34 +00:00
Bazsalanszky
f2b2525823 Merge pull request 'Fix parsing posts and userdata: admin flag removed in recent versions of Lemmy' (#190) from otaconix/Eternity:fix-for-missing-admin-flag into master
Reviewed-on: https://codeberg.org/Bazsalanszky/Eternity/pulls/190
Reviewed-by: Bazsalanszky <bazsalanszky@noreply.codeberg.org>
2023-10-06 06:01:11 +00:00
Balazs Toldi
29547f4750 Show instance for user listings
Closes #166
2023-09-12 09:02:27 +02:00
Balazs Toldi
af63bba54a Show instance for community listings 2023-09-12 08:43:56 +02:00
Stefan Zwanenburg
caf4f177d2 Fix parsing posts and userdata: admin flag removed in recent versions of Lemmy
See: https://github.com/LemmyNet/lemmy/pull/3403

For now, I guess we can try parsing the flag if it's present, and fall
back on assuming the associated user is *not* an admin.
2023-09-11 11:46:08 +02:00
Angelo Suzuki
1e67b34440 Add previews to RedGIFs posts
- Setup Glide with OkHttp in the custom application
- Add PostEnricher framework, that allows to add more data to fetched Posts. This was used to fetch the RedGIFs preview from their API.
2023-09-07 13:03:08 +02:00
Angelo Suzuki
67afcd7e88 Cleanup RedGIFs API usage
- Add User-Agent and authentication transparently
- Provide RedgifsAPI instance
2023-09-07 13:02:59 +02:00
Bazsalanszky
9406f29562 Merge pull request 'Use an OkHttpClient with User-Agent when initializing BigImageViewer' (#185) from tinsukE/Eternity:glide_user_agent into master
Reviewed-on: https://codeberg.org/Bazsalanszky/Eternity/pulls/185
Reviewed-by: Bazsalanszky <bazsalanszky@noreply.codeberg.org>
2023-09-07 08:48:52 +00:00
Angelo Suzuki
b626c5fb73 Use an OkHttpClient with User-Agent when initializing BigImageViewer.
If not passed, BigImageViewer overrides the Glide OkHttp downloader upon initialization with an empty one:
https://github.com/Piasy/BigImageViewer/blob/067f8eb/GlideImageLoader/src/main/java/com/github/piasy/biv/loader/glide/GlideProgressSupport.java#L76

In that case, Glide creates a default User-Agent:
cbdc1e78b4/library/src/main/java/com/bumptech/glide/load/model/LazyHeaders.java (L103-L106)

Example User-Agent: Dalvik/2.1.0 (Linux; U; Android 11; sdk_gphone_x86 Build/RSR1.201013.001)

https://files.catbox.moe is filtering out that User-Agent. Using the App one fixes it.
2023-09-05 11:42:38 +02:00
Balazs Toldi
0393ff6e77 Fix link text colour on the InstanceInfoActivity 2023-09-03 10:31:07 +02:00
Balazs Toldi
30ecc17d55 Fixing crash on opening community selector on post creation page 2023-09-03 10:21:43 +02:00
Bazsalanszky
7c5f184cc8 Updated Readme.md 2023-08-30 10:13:23 +02:00
Balazs Toldi
d5fff14cb0 Fix flashing screen on the MainActivity when changing the anonymous instance 2023-08-25 22:23:20 +02:00
Balazs Toldi
5cdda037b2 Change artifact name on tagged builds 2023-08-25 17:41:24 +02:00
Balazs Toldi
0942f7c5ec Bump version 2023-08-25 17:34:14 +02:00
Balazs Toldi
efe90d0030 Changed default media download location to the "Eternity" folder 2023-08-25 17:23:56 +02:00
Balazs Toldi
2d45f337d7 Somewhat better phone images 2023-08-25 17:15:50 +02:00
Balazs Toldi
70cf6f3340 Fix bug with unsubscribing from communities 2023-08-25 17:14:23 +02:00
Balazs Toldi
6542859892 Fix IndexOutOfBoundsException in CommentsRecyclerViewAdapter 2023-08-25 09:36:37 +02:00
Balazs Toldi
143bc5e1b6 Fix issues with resolving Links
This commit changes how resolving links work. It will not use the resolve object function now for local instance links, as they would fail almost every time.

It also opens toasts in the application context instead of the activity context. This might prevent some crashes
2023-08-25 09:02:39 +02:00
Balazs Toldi
6e51ea6ee7 Fix crashes and issues with searching in communities 2023-08-25 08:35:05 +02:00
Balazs Toldi
d7c4e3d5bc Truncate long names in the navigation header 2023-08-24 23:11:34 +02:00
Balazs Toldi
1ed86c138e Removed automatically added dependency 2023-08-24 23:10:46 +02:00
Balazs Toldi
2d83545865 Fix theming on multiple elements
Fixed theming on:
- Post content on PostImage and PostLink activities
- Report content forms

Closes #163
2023-08-24 20:09:52 +02:00
Balazs Toldi
3594f10fdd Fix issues with subscription listing after marking communities as favorite
Previously, when marking a community as favorite made some communities disappear on the subscription list
2023-08-24 19:53:48 +02:00
Balazs Toldi
a903ac9dbd Attempt to fix crash when deleted comment add necessary placeholder 2023-08-23 23:23:10 +02:00
Balazs Toldi
ed90a278a6 Fix crashes related to sort types
Closes #153 and #113
2023-08-23 22:53:41 +02:00
Balazs Toldi
6221b33a3d Fix user name on collapsed comments
Closes #161
2023-08-23 22:35:51 +02:00
Balazs Toldi
2561ba8bd0 Fix post layouts 2023-08-23 21:39:08 +02:00
Balazs Toldi
9859608764 Merge remote-tracking branch 'weblate/master'
# Conflicts:
#	app/src/main/res/values/strings.xml
2023-08-23 21:24:20 +02:00
SomeTr
b40077f83f Translated using Weblate (Ukrainian)
Currently translated at 99.7% (1249 of 1252 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/uk/
2023-08-23 19:19:38 +00:00
Bazsalanszky
76dc0ff083 Translated using Weblate (Hungarian)
Currently translated at 81.7% (1024 of 1252 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/hu/
2023-08-23 19:19:38 +00:00
Bazsalanszky
6a2d59ed48 Translated using Weblate (English)
Currently translated at 100.0% (1252 of 1252 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/en/
2023-08-23 19:19:38 +00:00
Balazs Toldi
a09d6f85f8 Add option to share links on local instance 2023-08-23 21:14:53 +02:00
SomeTr
2f3d39ed31 Translated using Weblate (Ukrainian)
Currently translated at 99.6% (1248 of 1252 strings)

Translation: Eternity/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/uk/
2023-08-23 09:21:45 +00:00
American_Jesus
83e0fc039f Translated using Weblate (Portuguese)
Currently translated at 99.1% (1235 of 1245 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/pt/
2023-08-23 09:21:45 +00:00
julroy67
d4ca682882 Translated using Weblate (French)
Currently translated at 94.5% (1177 of 1245 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/fr/
2023-08-23 09:21:45 +00:00
dieserniko
e2b75a3928 Translated using Weblate (German)
Currently translated at 98.2% (1223 of 1245 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/de/
2023-08-23 09:21:45 +00:00
Balazs Toldi
d9f9fb51db Fix instance info activity card background colours 2023-08-23 11:21:19 +02:00
Balazs Toldi
a8b2091e69 Bump version 2023-08-22 22:18:03 +02:00
Balazs Toldi
f14ebe9a0d Added option to show displayname and hide the instance for comment author names 2023-08-22 22:10:39 +02:00
Balazs Toldi
4010e02438 Fix instance info navigation bar colour 2023-08-22 21:53:08 +02:00
Balazs Toldi
5cbe6152c9 Fix nightly 2023-08-22 21:50:48 +02:00
Balazs Toldi
c7233e05c4 Instance Info page 2023-08-22 21:49:12 +02:00
Bazsalanszky
9d4657dea8 Merge pull request 'Set nightfox as default themes' (#147) from American_Jesus/Infinity-For-Lemmy:feature/default-themes-nightfox into master
Reviewed-on: https://codeberg.org/Bazsalanszky/Eternity/pulls/147
Reviewed-by: Bazsalanszky <bazsalanszky@noreply.codeberg.org>
2023-08-21 18:42:44 +00:00
Bazsalanszky
7c3ddfda5c Merge pull request 'Add new themes Dayfox,Nightfox,Carbonfox' (#146) from American_Jesus/Infinity-For-Lemmy:feature/nightfox-themes into master
Reviewed-on: https://codeberg.org/Bazsalanszky/Eternity/pulls/146
Reviewed-by: Bazsalanszky <bazsalanszky@noreply.codeberg.org>
2023-08-21 18:32:53 +00:00
SomeTr
77f37a5698 Translated using Weblate (Ukrainian)
Currently translated at 99.8% (1243 of 1245 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/uk/
2023-08-21 11:56:44 +00:00
dieserniko
c45528a7f3 Translated using Weblate (German)
Currently translated at 98.3% (1224 of 1245 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/de/
2023-08-21 11:56:44 +00:00
Bazsalanszky
0dcc441bae Change app name 2023-08-21 11:01:08 +02:00
Bazsalanszky
8c05b6e1ea Revert gradle related changes 2023-08-21 10:09:07 +02:00
Bazsalanszky
351033600f Merge remote-tracking branch 'origin/master' 2023-08-21 09:43:47 +02:00
Bazsalanszky
fb4289a812 Bump SDK in build pipeline 2023-08-21 09:43:39 +02:00
Generator
37eb16f6c4 Set nightfox default themes 2023-08-20 20:53:51 +01:00
SomeTr
77c5bcb038 Translated using Weblate (Ukrainian)
Currently translated at 99.5% (1239 of 1244 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/uk/
2023-08-20 19:32:00 +00:00
Balazs Toldi
3c65bfcf1b Better sidebar for community pages 2023-08-20 21:31:40 +02:00
Balazs Toldi
ce7c284c6b Add stats to community "about" tab 2023-08-20 14:51:57 +02:00
Balazs Toldi
267570d7b4 Re-added favorite community functionality
This commit re-adds the ability to mark communities as 'favorites'. This function only works locally as Lemmy does not have an API/functionality for this.
2023-08-20 14:26:03 +02:00
Balazs Toldi
c9e6a0bc2e Fix comment refreshing bug on single thread view
Closes #143
2023-08-20 10:56:41 +02:00
Balazs Toldi
1f8348bbfa Merge remote-tracking branch 'codeberg/master' 2023-08-20 10:33:16 +02:00
Balazs Toldi
d4fe5235e2 Fix opening Image view activity from embedded images 2023-08-20 10:33:10 +02:00
Balazs Toldi
76fee50cd5 Do not show statistics block while loading 2023-08-20 10:24:09 +02:00
SomeTr
e2956e3f1c Translated using Weblate (Ukrainian)
Currently translated at 99.1% (1230 of 1241 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/uk/
2023-08-19 20:25:36 +00:00
American_Jesus
21b0b36359 Translated using Weblate (Portuguese)
Currently translated at 98.3% (1221 of 1241 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/pt/
2023-08-19 20:25:36 +00:00
Fjuro
a55820a11d Translated using Weblate (Czech)
Currently translated at 100.0% (1241 of 1241 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/cs/
2023-08-19 20:25:36 +00:00
Balazs Toldi
3322b5b4e8 Add option to disable statistics block and post/comment score
As per users requested, I've added two options to the interface section:
1. Disable statistics (under users and community pages): Disables the statistics block on user/community pages
2. Disable post and comment scores: Disables the post and comment scores show on users pages
2023-08-19 22:25:26 +02:00
Balazs Toldi
0384914c16 Readded instance switcher to navbar for anonymous accounts 2023-08-19 16:57:08 +02:00
Balazs Toldi
0550219d58 Fix Streamable videos 2023-08-19 16:46:46 +02:00
Balazs Toldi
deaa4e596d Fix switch account toast when opening a notification
Closes #100
2023-08-19 16:36:22 +02:00
Balazs Toldi
bf1036c919 Fix crash when exiting ot of profile page while loading 2023-08-19 15:35:18 +02:00
Balazs Toldi
116deebf87 Use application context for MarkdownUtils 2023-08-18 23:35:33 +02:00
Balazs Toldi
0f3197d7e4 Use application context for Glide 2023-08-18 23:35:21 +02:00
Balazs Toldi
db9edc47c0 Merge changes 2023-08-18 22:14:47 +02:00
Balazs Toldi
2392d9fa29 Merge remote-tracking branch 'codeberg/master' 2023-08-18 21:51:38 +02:00
Balazs Toldi
3272f609a8 Potential fix for crash when closing a comment too fast 2023-08-18 21:51:30 +02:00
Balazs Toldi
d5092f50f6 Fix issue with sharing urls
Closes #139
2023-08-18 21:26:12 +02:00
Balazs Toldi
d216fc4640 Fix issue with comment editing
In some change the behavior for detecting the users comments broke making it impossible to edit or delete previously created comments. Closes #136
2023-08-18 21:14:29 +02:00
Balazs Toldi
f61c12a30b Fix some malformed links 2023-08-18 21:09:28 +02:00
Bazsalanszky
bbbd4ddcb0 Merge pull request 'Basic Private messages' (#119) from feature/privatemessages into master
Reviewed-on: https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/pulls/119
2023-08-18 13:57:19 +00:00
Balazs Toldi
495a1d025f Fix bug with inserting malformed image links 2023-08-18 15:39:56 +02:00
Generator
a245ebad09 add new themes Dayfox,Nightfox,Carbonfox 2023-08-18 14:39:52 +01:00
Balazs Toldi
0e31e40ef1 Send Private messages from ViewUserDetailActivity 2023-08-18 15:39:34 +02:00
Balazs Toldi
bae68d4a99 Fix PrivateMessageDataSource making way to many requests 2023-08-18 13:18:21 +02:00
Balazs Toldi
3e17e3364d Sending private messages 2023-08-18 09:46:51 +02:00
Balazs Toldi
9626500586 Fix names on private message page 2023-08-18 09:46:51 +02:00
Balazs Toldi
92fcb811c3 Rebase to master 2023-08-18 09:46:43 +02:00
Balazs Toldi
81e2fdcf91 Fix lifecycle for ViewUser/ViewCommunity activities 2023-08-18 09:22:35 +02:00
Balazs Toldi
171338f492 Nicer stats for communities
This commit adds more info on the community detail page. The design is heavily inspired by Memmy.

Closes #45
2023-08-18 08:55:56 +02:00
Balazs Toldi
cc21588a66 Nicer stats for users
This commit adds more info on the user detail page. The design is heavily inspired by Memmy
2023-08-17 23:35:07 +02:00
Balazs Toldi
b5356ee5eb Fix long display name issues 2023-08-17 22:27:45 +02:00
Balazs Toldi
ec9be3f6af Fix compact view showing username instead of the community name
Closes #131
2023-08-17 22:02:48 +02:00
Balazs Toldi
ac5e67c032 Added LemmyPostAPI
Forgot to include in my prev commit.

Added LemmyPostAPI

Forgot to include in my prev commit.
2023-08-17 16:27:00 +02:00
Balazs Toldi
fd24f04254 Report posts and comments.
Closes #92
2023-08-17 15:46:18 +02:00
Balazs Toldi
0b74574fa6 Merge remote-tracking branch 'codeberg/master' 2023-08-17 08:43:15 +02:00
Balazs Toldi
2704ff0ecf Show community and user display name
Closes #34
2023-08-17 08:43:10 +02:00
owatnext
f4c33e08e2 Translated using Weblate (Welsh)
Currently translated at 0.6% (8 of 1234 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/cy/
2023-08-16 23:29:15 +00:00
SinTan1729
5dddf2e39d Translated using Weblate (Bengali)
Currently translated at 2.5% (32 of 1234 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/bn/
2023-08-16 23:29:15 +00:00
abiiM
487afce565 Translated using Weblate (Spanish)
Currently translated at 91.8% (1133 of 1234 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/es/
2023-08-16 23:29:15 +00:00
JnkLtt
f31a13568c Translated using Weblate (German)
Currently translated at 94.4% (1166 of 1234 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/de/
2023-08-16 23:29:14 +00:00
genoxidedev1
04341991bf Translated using Weblate (German)
Currently translated at 94.4% (1166 of 1234 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/de/
2023-08-16 23:29:14 +00:00
Balazs Toldi
a7c2a67d0c Better loading for View User datail activity
Closes #64
2023-08-16 19:44:46 +02:00
Balazs Toldi
4ec6666f93 Make instance names clickable 2023-08-16 19:35:40 +02:00
Bazsalanszky
fcc0181075 Better post layout on post detail page 2023-08-16 16:54:27 +02:00
Bazsalanszky
1c4e5f3659 Fix compile issue 2023-08-16 10:31:53 +02:00
Balazs Toldi
a120fcf068 Better post layout on post listing
This commit fixes the issue where the user and community names had multiple line breaks in them if they were too long. I broke the instance part to a different textview with different colours.
2023-08-16 08:11:31 +02:00
Balazs Toldi
0328f34df2 Fix separated up/down vote counts when on the right side
Closes #123
2023-08-15 21:44:20 +02:00
Bazsalanszky
7849115000 Merge pull request 'Fix instance URL field hint on Login activity' (#121) from bugfix/instance_url_overlap into master
Reviewed-on: https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/pulls/121
2023-08-15 16:19:48 +00:00
Balazs Toldi
41e14aab9d Fix instance URL field hint on Login activity 2023-08-15 15:57:38 +02:00
Bazsalanszky
074b5d012c Merge pull request 'fix #110 default colors' (#118) from American_Jesus/Infinity-For-Lemmy:fix-110-colors into master
Reviewed-on: https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/pulls/118
Reviewed-by: Bazsalanszky <bazsalanszky@noreply.codeberg.org>
2023-08-15 13:39:59 +00:00
Generator
8a3ee7931d fix #110 default colors 2023-08-15 14:19:51 +01:00
Balazs Toldi
dce5a8d89c Fix resolving communities from non-home instance URLs 2023-08-15 08:23:14 +02:00
Balazs Toldi
a82f2b68e3 Merge branch 'feature/bugfixes' 2023-08-15 08:11:01 +02:00
Balazs Toldi
a36ddccefd Fix parsing user display name 2023-08-15 08:10:21 +02:00
Balazs Toldi
bbe696a37b Fix anonymous link resolving 2023-08-15 07:55:07 +02:00
Bazsalanszky
13ec5f84c4 Merge pull request 'Nightly build fixes' (#116) from feature/nightly into master
Reviewed-on: https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/pulls/116
2023-08-15 05:33:17 +00:00
Balazs Toldi
587ebbb309 Change nightly build app name 2023-08-15 07:15:43 +02:00
Balazs Toldi
485611970f Potential fix for nightly build version codes 2023-08-15 07:15:19 +02:00
Bazsalanszky
c0738947b7 Merge pull request 'Nightly releases' (#109) from feature/nightly into master
Reviewed-on: https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/pulls/109
2023-08-14 19:16:31 +00:00
Balazs Toldi
f1145d826e Merge remote-tracking branch 'codeberg/feature/nightly' into feature/nightly 2023-08-14 21:14:19 +02:00
Balazs Toldi
aa4f587443 Minro change to nightly.yaml 2023-08-14 21:14:09 +02:00
Balazs Toldi
e559e4acd2 Minro change to nightly.yaml 2023-08-14 21:14:09 +02:00
Balazs Toldi
db1e000325 Minro change to nightly.yaml 2023-08-14 21:14:09 +02:00
Balazs Toldi
4f57c17f73 Minro change to nightly.yaml 2023-08-14 21:14:09 +02:00
Balazs Toldi
21af736fa4 Check nightly build 2023-08-14 21:14:09 +02:00
Balazs Toldi
72ba80ff87 Use secrets in update-fdroid-data step 2023-08-14 21:14:09 +02:00
Bazsalanszky
450e96fdbe Merge pull request 'Set Dracula default dark theme. fix #86' (#110) from American_Jesus/Infinity-For-Lemmy:default-theme-dracula into master
Reviewed-on: https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/pulls/110
Reviewed-by: Bazsalanszky <bazsalanszky@noreply.codeberg.org>
2023-08-14 19:11:38 +00:00
Generator
fcc60e1b16 remove extra double quote 2023-08-14 15:56:22 +01:00
owatnext
e888282d24 Translated using Weblate (Welsh)
Currently translated at 0.4% (5 of 1234 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/cy/
2023-08-14 14:53:05 +00:00
SinTan1729
237d33f2e4 Translated using Weblate (Bengali)
Currently translated at 1.5% (19 of 1234 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/bn/
2023-08-14 14:53:05 +00:00
American_Jesus
babb0d28bb Translated using Weblate (Portuguese)
Currently translated at 99.0% (1222 of 1234 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/pt/
2023-08-14 14:53:05 +00:00
ybinnenweg
53eb7cbe91 Translated using Weblate (Dutch)
Currently translated at 83.6% (1032 of 1234 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/nl/
2023-08-14 14:53:04 +00:00
Bazsalanszky
fed84f9942 Translated using Weblate (Hungarian)
Currently translated at 82.8% (1022 of 1234 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/hu/
2023-08-14 14:53:04 +00:00
DestroyerAce
d4896a1f87 Translated using Weblate (Hindi)
Currently translated at 71.8% (887 of 1234 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/hi/
2023-08-14 14:53:04 +00:00
Generator
21879bec7d Set Dracula default dark theme 2023-08-14 14:41:01 +01:00
Balazs Toldi
bb143cfecb Minro change to nightly.yaml 2023-08-14 10:49:48 +02:00
Balazs Toldi
6475b4808a Minro change to nightly.yaml 2023-08-14 10:44:04 +02:00
Balazs Toldi
57a58cc518 Minro change to nightly.yaml 2023-08-14 10:39:36 +02:00
Balazs Toldi
8a5b6aa972 Minro change to nightly.yaml 2023-08-14 10:35:05 +02:00
Balazs Toldi
6813770d57 Check nightly build 2023-08-14 10:16:48 +02:00
Balazs Toldi
118b6cd430 Use secrets in update-fdroid-data step 2023-08-14 10:09:59 +02:00
Balazs Toldi
b984e35284 Change image for update-fdroid-data task in nightly.yaml 2023-08-14 09:21:05 +02:00
Balazs Toldi
f2a2a3029d Minor change in nightly pipeline 2023-08-14 09:12:06 +02:00
Balazs Toldi
b4ab1ba414 Update nightly build with signing keys 2023-08-14 08:47:20 +02:00
Balazs Toldi
d244e0ed42 Link resolver to change API base url.
This fixes the issue when opening a link while the app is fully closed
2023-08-14 08:09:51 +02:00
Balazs Toldi
81c190a9c0 Fix steps in nightly build 2023-08-13 22:08:19 +02:00
Balazs Toldi
e2f36c334b Fix steps in nightly build 2023-08-13 22:04:25 +02:00
Balazs Toldi
891215fcb3 Fix path for pull-repo-config step in nightly 2023-08-13 21:58:56 +02:00
Balazs Toldi
04e022cbbc Do not run the build pipeline on cron jobs 2023-08-13 21:54:51 +02:00
Balazs Toldi
1f4f3a475d Fix nightly build apk name 2023-08-13 21:52:52 +02:00
Balazs Toldi
3e6d435116 Fix nightly build indentation in CI definition 2023-08-13 21:42:20 +02:00
Balazs Toldi
9c6f946602 Test nightly build CI 2023-08-13 21:39:19 +02:00
Balazs Toldi
053c9e73b0 Fix parsing Community/post title with "&" characters 2023-08-13 17:03:25 +02:00
Balazs Toldi
acd1aef851 Fix editing post with empty URL field 2023-08-13 16:44:36 +02:00
Balazs Toldi
a3a753a9dd Add "Nightly" build type variant 2023-08-13 15:57:32 +02:00
Balazs Toldi
0ea491bcfc Fix issue with changing comment sort type on post page 2023-08-12 21:54:29 +02:00
Balazs Toldi
946d35b5d9 Show account qualified name in the navigation drawer.
Closes #24
2023-08-12 21:47:38 +02:00
Balazs Toldi
5098cb698d Show account qualified name in the navigation drawer.
Closes #24
2023-08-12 21:25:30 +02:00
Balazs Toldi
47a06c372e Merge remote-tracking branch 'codeberg/master' 2023-08-12 21:02:49 +02:00
Balazs Toldi
7877001533 Fix bugs related to fetching blocked users 2023-08-12 21:02:44 +02:00
Balazs Toldi
23d41846d0 Fix dialog title on blocking community page 2023-08-12 20:44:24 +02:00
Balazs Toldi
dc4dc17b6c Block user/community on post detail view 2023-08-12 20:43:07 +02:00
owatnext
6c8892938a Added translation using Weblate (Welsh) 2023-08-12 13:52:16 +00:00
SinTan1729
2f2d86bc3f Added translation using Weblate (Bengali) 2023-08-11 23:42:10 +00:00
Balazs Toldi
ecd3d008de Merge remote-tracking branch 'codeberg/master' 2023-08-11 23:59:46 +02:00
Balazs Toldi
f5172a17db Fix removing blocked things 2023-08-11 23:59:42 +02:00
Eryk Michalak
662a5bd597 Translated using Weblate (Polish)
Currently translated at 89.3% (1100 of 1231 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/pl/
2023-08-11 21:54:17 +00:00
Balazs Toldi
6621748de5 Block User option
This commit adds implementation to the block/unblock user option
2023-08-11 23:54:10 +02:00
Balazs Toldi
37fa76b79a Merge remote-tracking branch 'codeberg/master' 2023-08-11 23:21:13 +02:00
Balazs Toldi
c7acb50522 Do not show a follow button when searching for a user
Lemmy does not handle following users. An option for this was shown on the search results. Close #103
2023-08-11 23:21:09 +02:00
creepen
64304ad637 Translated using Weblate (Russian)
Currently translated at 98.8% (1208 of 1222 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/ru/
2023-08-11 18:09:56 +00:00
Balazs Toldi
635ca332da Merge remote-tracking branch 'codeberg/master' 2023-08-11 20:09:39 +02:00
Balazs Toldi
e2a15ab925 Add blocked thing listing activity
Added activity that displays the blocked users and communities
2023-08-11 20:09:34 +02:00
Balazs Toldi
016801419f Remove "Add to multicommunity" option from user/community pages 2023-08-11 10:49:01 +02:00
American_Jesus
48d79bc353 Translated using Weblate (Portuguese)
Currently translated at 90.5% (1107 of 1222 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/pt/
2023-08-11 08:44:01 +00:00
frenki
b8094fded8 Translated using Weblate (Italian)
Currently translated at 92.8% (1135 of 1222 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/it/
2023-08-11 08:44:01 +00:00
Bazsalanszky
8c82ba0e91 Translated using Weblate (Hungarian)
Currently translated at 80.7% (987 of 1222 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/hu/
2023-08-11 08:44:01 +00:00
JnkLtt
3ff9c06843 Translated using Weblate (German)
Currently translated at 95.0% (1162 of 1222 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/de/
2023-08-11 08:44:01 +00:00
Balazs Toldi
45ae8342ee Merge remote-tracking branch 'codeberg/master' 2023-08-11 10:43:54 +02:00
Balazs Toldi
b8c3dae807 Rename Home feed to "Subscribed" feed 2023-08-11 10:42:09 +02:00
Balazs Toldi
3afd2601f0 Fix issue with default sort times
Previously, if the default sort type is set to "top of x time", most failed to load any posts.
2023-08-11 08:42:16 +02:00
Balazs Toldi
82414bba55 Highlight pinned posts
This commits adds a pin icon to featured posts on communities or on the instance.
2023-08-10 21:44:36 +02:00
Balazs Toldi
7a39b2341b Small fixes related to parsing and soring
Closes #96
2023-08-10 21:12:49 +02:00
Balazs Toldi
37ab47bc34 Fix wierd issue when trying to open reddit@lemmy.world 2023-08-10 21:03:04 +02:00
Balazs Toldi
21b111cc2d Fix crash when trying to share sack trace
Closes #80
2023-08-10 20:44:26 +02:00
Bazsalanszky
b3c2f6213d Fix crash when unsaving post on a post detail page
Closes #90
2023-08-10 17:23:36 +02:00
Bazsalanszky
c3de94012a Merge remote-tracking branch 'origin/master' 2023-08-10 17:18:37 +02:00
Bazsalanszky
804eb64b5b Fix downvote count not being visible on comments 2023-08-10 17:18:31 +02:00
Bazsalanszky
6a4aa8075d Post detail up/downvote separation
This commit separates the up and downvote values on a post detail page.
2023-08-10 17:17:08 +02:00
Bazsalanszky
692aca4eca Translated using Weblate (Hungarian)
Currently translated at 79.4% (971 of 1222 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/hu/
2023-08-10 11:58:06 +00:00
Bazsalanszky
dd00802561 Merge remote-tracking branch 'weblate/master' 2023-08-10 13:43:36 +02:00
Bazsalanszky
a3e0fea200 Translated using Weblate (Hungarian)
Currently translated at 77.9% (952 of 1222 strings)

Translation: Infinity for Lemmy/App
Translate-URL: https://translate.codeberg.org/projects/infinity-for-lemmy/app/hu/
2023-08-10 11:39:34 +00:00
Bazsalanszky
304125ea0d Merge remote-tracking branch 'weblate/master' 2023-08-10 13:38:56 +02:00
Bazsalanszky
a465ebb5b4 Switch to codeberg translate!
Switched to codeberg translate instead of the hosted weblate
2023-08-10 13:35:31 +02:00
balazs
b39d00eba6 Translated using Weblate (Hungarian)
Currently translated at 78.6% (961 of 1222 strings)

Translation: Infinity for Lemmy/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/hu/
2023-08-10 13:26:09 +02:00
balazs
1ebdce309d Translated using Weblate (Hungarian)
Currently translated at 78.6% (961 of 1222 strings)

Translation: Infinity for Lemmy/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/hu/
2023-08-10 11:16:46 +02:00
balazs
d29b7585f7 Translated using Weblate (Hungarian)
Currently translated at 78.3% (957 of 1222 strings)

Translation: Infinity for Lemmy/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/hu/
2023-08-10 11:16:46 +02:00
Bazsalanszky
276560678c Minor change in strings.xml 2023-08-10 11:16:39 +02:00
Bazsalanszky
10c23a65c5 Changes on the separate up/down vote view on posts 2023-08-10 11:08:34 +02:00
Bazsalanszky
4e4f4377e7 Update woodpecker pipeline 2023-08-10 11:00:56 +02:00
Bazsalanszky
2e6c9db614 Separate comment up and downvotes
This commit makes it possible to separate up and downvotes in the comments as well.
2023-08-10 10:59:02 +02:00
Bazsalanszky
2375ba9d35 Merge remote-tracking branch 'weblate/master' 2023-08-10 09:08:44 +02:00
Allan Nordhøy
a11ccb7cf6 Added translation using Weblate (Norwegian Bokmål) 2023-08-10 03:22:13 +02:00
Bruno Guerreiro
a54241294d Translated using Weblate (Portuguese)
Currently translated at 87.3% (1066 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/pt/
2023-08-09 20:39:29 +02:00
Bazsalanszky
46b509c1fb Merge remote-tracking branch 'origin/master' 2023-08-09 20:39:24 +02:00
Bazsalanszky
b13dd58c70 Basic up/down vote separation
This commit adds separation option of the up and downvote scres for post on the main page.
2023-08-09 20:39:12 +02:00
Bruno Guerreiro
4312b250ce Translated using Weblate (Portuguese)
Currently translated at 86.8% (1061 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/pt/
2023-08-08 16:15:04 +02:00
Alex
ff4c9180a0 Translated using Weblate (French)
Currently translated at 94.1% (1150 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/fr/
2023-08-08 16:15:04 +02:00
Balazs Toldi
be0bd40995 Show NSFW communities on search
There was a bug in the code that caused the nsfw settings to report "false" value in the community search.
2023-08-08 16:13:16 +02:00
Bruno Guerreiro
726d6d0faf Translated using Weblate (Portuguese)
Currently translated at 86.3% (1054 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/pt/
2023-08-08 07:28:03 +02:00
Bruno Guerreiro
14ce356c4d Translated using Weblate (Portuguese)
Currently translated at 86.3% (1054 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/pt/
2023-08-07 15:41:50 +02:00
Bazsalanszky
930a425af5 Merge pull request 'README.md add download badges' (#79) from American_Jesus/Infinity-For-Lemmy:readme-badges into master
Reviewed-on: https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/pulls/79
2023-08-07 13:33:28 +00:00
Generator
7168cecbcb README.md add download badges
Centrer logo image
2023-08-07 14:26:06 +01:00
Bazsalanszky
7f067023e7 Merge pull request 'Fix CI link' (#76) from Gusted/Infinity-For-Lemmy:fix-ci-link into master
Reviewed-on: https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/pulls/76
2023-08-07 12:29:29 +00:00
Bazsalanszky
167aecb696 Fix crashes related to incorrect instance URL 2023-08-07 13:56:20 +02:00
Bazsalanszky
9872e6e806 Linkify community and user names
This commit makes user and community names clickable in post/comments. Closes #71?
2023-08-07 13:49:18 +02:00
Hosted Weblate
05adc343a2 Update translation files
Updated by "Remove blank strings" hook in Weblate.

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/
2023-08-07 09:03:26 +02:00
Anonymous
58e3dfa084 Translated using Weblate (Chinese (Simplified))
Currently translated at 91.8% (1121 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/zh_Hans/
2023-08-07 09:02:59 +02:00
Anonymous
3068423c01 Translated using Weblate (Vietnamese)
Currently translated at 91.1% (1113 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/vi/
2023-08-07 09:02:53 +02:00
Anonymous
3c960f60d1 Translated using Weblate (Ukrainian)
Currently translated at 94.7% (1157 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/uk/
2023-08-07 09:02:47 +02:00
Anonymous
a153fc4afb Translated using Weblate (Turkish)
Currently translated at 91.1% (1113 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/tr/
2023-08-07 09:02:40 +02:00
Anonymous
4a19fbb745 Translated using Weblate (Somali)
Currently translated at 2.9% (36 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/so/
2023-08-07 09:02:34 +02:00
Anonymous
bb8c10fc98 Translated using Weblate (Russian)
Currently translated at 94.7% (1157 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/ru/
2023-08-07 09:02:29 +02:00
Anonymous
97af73f055 Translated using Weblate (Romanian)
Currently translated at 94.7% (1157 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/ro/
2023-08-07 09:02:22 +02:00
Anonymous
73d18082c4 Translated using Weblate (Portuguese)
Currently translated at 85.3% (1042 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/pt/
2023-08-07 09:02:16 +02:00
Anonymous
4b78e80edd Translated using Weblate (Portuguese (Brazil))
Currently translated at 94.7% (1157 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/pt_BR/
2023-08-07 09:02:10 +02:00
Anonymous
78ba4b0fda Translated using Weblate (Polish)
Currently translated at 86.8% (1061 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/pl/
2023-08-07 09:02:04 +02:00
Anonymous
a1c5baac6b Translated using Weblate (Dutch)
Currently translated at 81.7% (998 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/nl/
2023-08-07 09:01:58 +02:00
Anonymous
c4b811090d Translated using Weblate (Japanese)
Currently translated at 81.4% (994 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/ja/
2023-08-07 09:01:51 +02:00
Anonymous
fbdccfb639 Translated using Weblate (Italian)
Currently translated at 91.1% (1113 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/it/
2023-08-07 09:01:45 +02:00
Anonymous
c1162fd618 Translated using Weblate (Hungarian)
Currently translated at 77.8% (951 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/hu/
2023-08-07 09:01:39 +02:00
Anonymous
4d7a148cfe Translated using Weblate (Croatian)
Currently translated at 74.4% (909 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/hr/
2023-08-07 09:01:32 +02:00
Anonymous
c7b1602648 Translated using Weblate (Hindi)
Currently translated at 71.0% (868 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/hi/
2023-08-07 09:01:24 +02:00
Anonymous
a82a454ad2 Translated using Weblate (French)
Currently translated at 82.2% (1004 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/fr/
2023-08-07 09:01:17 +02:00
Anonymous
9533378003 Translated using Weblate (Spanish)
Currently translated at 91.1% (1113 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/es/
2023-08-07 09:01:11 +02:00
Anonymous
dc1edcc78c Translated using Weblate (German)
Currently translated at 94.7% (1157 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/de/
2023-08-07 09:01:06 +02:00
Anonymous
6d8b040f6d Translated using Weblate (Czech)
Currently translated at 91.1% (1113 of 1221 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/cs/
2023-08-07 09:01:00 +02:00
Bazsalanszky
60f07f7707 Empty login fields crash fix
This commit resolves the issue where the app crashes on the Login page if one of the mandatory filed is left empty.
2023-08-07 08:45:44 +02:00
balazs
f6b7130d0c Translated using Weblate (Hungarian)
Currently translated at 78.0% (951 of 1218 strings)

Translation: LemmInfinity/Codeberg
Translate-URL: https://hosted.weblate.org/projects/lemminfinity/codeberg/hu/
2023-08-07 08:43:51 +02:00
Bazsalanszky
9fea056063 Empty login fields crash fix
This commit resolves the issue where the app crashes on the Login page if one of the mandatory filed is left empty.
2023-08-07 08:43:42 +02:00
Gusted
859e9ab5d6 Fix CI link
The CI link currently links to an blank page, I'm not sure if it worked before and got broken by the [`1.0.0`](https://github.com/woodpecker-ci/woodpecker/releases/tag/v1.0.0) release of Woodpecker CI.
2023-08-06 20:31:13 +00:00
Bazsalanszky
4821718407 Add weblate to contributions section of readme
This is a requirement for getting the Libre plan on weblate.
2023-08-06 22:14:39 +02:00
Bazsalanszky
67a13f8ecb Fix "show all comments" button crash
Closes #72
2023-08-06 21:31:15 +02:00
Bazsalanszky
40e4782b32 Minor fix to ViewUserDetailActivity 2023-08-06 10:38:47 +02:00
Bazsalanszky
2ab5ab3ce5 Fix posting from community home page
This commit resolves the issue that made the app crash after trying to post from a community home page. Closes #70
2023-08-06 09:37:46 +02:00
Bazsalanszky
88fb054640 Fix bottom navigation bar profile button
Closes #69
2023-08-06 09:21:10 +02:00
Bazsalanszky
4ce8fd6a63 Fix view all comments button 2023-08-05 19:53:49 +02:00
Balazs Toldi
ffc2d669e5 Show images in comments and post
Replace image links in posts and comments with actual images.
2023-08-05 19:07:23 +02:00
Bazsalanszky
926e1162f0 Removed more reddit related options
Removed options related to reddit, like flairs and awards.
2023-08-05 18:06:50 +02:00
Bazsalanszky
6cf69ee26d Disable downvote button when downvotes are disable on the account's instance
This commit hides the downvote button from account where the instance disabled the downvote functionality.

Note: You need to switch accounts to take effect!
2023-08-05 17:09:48 +02:00
Bazsalanszky
279820c1be Remove award and flair related settings
These do not work on Lemmy. We do not need them.
2023-08-05 16:27:58 +02:00
Bazsalanszky
1d7031f3d4 Fix issues related to image loading
Resolved some issues related to loading icons of users on community pages
2023-08-05 16:20:33 +02:00
Bazsalanszky
252e00b67a Fix issue related to loading community data
In some cases loading the creation date of the community made the app crash. Now it has been resolved.
2023-08-05 16:19:37 +02:00
Bazsalanszky
a8d63c7480 Fix loading community and user images
This commit resolves two issues:
1. Loading community icons on the homepage sometimes showed the wrong community icon
2. Loading user avatars failed before when tried them in the comments
2023-08-05 16:01:28 +02:00
Bazsalanszky
2020172b56 Unsave comment fix
Resolve issue where unsaving the app crashes the app.

Closes #55
2023-08-05 14:41:31 +02:00
Bazsalanszky
2d55a4c8ec Fix issue with NSFW Communites
This commit resolves the issue where posts from NSFW communities appeared on the Home page, but not when opening the community it self.

Closes #49
2023-08-05 14:32:15 +02:00
Bazsalanszky
20a3e0220b Fix CrashReportsFragment url
Now uses the our repo instead of the upstream one!
2023-08-05 14:21:44 +02:00
Bazsalanszky
feeeefa2d2 Possible fix to loading videos on home page 2023-08-05 14:21:08 +02:00
Bazsalanszky
d25137020f Bug report template 2023-08-05 14:19:23 +02:00
Bazsalanszky
3c4fb4162e Merge remote-tracking branch 'origin/master' 2023-08-05 14:17:27 +02:00
Bazsalanszky
28e9ae950e Bug report issue template 2023-08-05 14:16:22 +02:00
Bazsalanszky
888e741aa9 Parse video posts
Parse post with direct links to videos as Video type posts. Autoplay also works with these.
2023-08-05 13:57:07 +02:00
Bazsalanszky
9f7a6e1738 Merge pull request 'I replaced the empty community icon with one that uses a lemmy-like icon instead' (#57) from carrotcake/Infinity-For-Lemmy:new-picture into master
Reviewed-on: https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/pulls/57
2023-08-05 11:34:53 +00:00
Bazsalanszky
76f4a0738f Merge pull request 'Update locale-pt' (#53) from American_Jesus/Infinity-For-Lemmy:locale-pt into master
Reviewed-on: https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/pulls/53
2023-08-05 11:33:16 +00:00
carrotcake
63327946be I replaced the empty community icon with one that uses a lemmy-like icon instead 2023-08-04 22:58:56 -04:00
Bazsalanszky
84d90adc54 Updated fastlane short description 2023-08-04 17:09:36 +02:00
Generator
cf15732a39 fix string 2023-08-04 15:38:14 +01:00
Generator
2eee73753f change Popular to Local 2023-08-04 15:33:37 +01:00
Generator
62d097357a fix strings and typos 2023-08-04 15:29:41 +01:00
Bazsalanszky
c35a690335 Updated README with more accureate information
Updated README to report all the supported features by the app.
2023-08-04 16:17:17 +02:00
Generator
18af76ce92 update locale pt 2023-08-04 15:13:11 +01:00
Bazsalanszky
6e7256d9a5 Minor fix for "Cake day" parsing
It now only shows the date
2023-08-04 15:59:18 +02:00
Bazsalanszky
2af6c5a742 Show more context when loading a single comment
This commit makes it so that when loading a single comment (e.g. from the inbox) it also shows the parent comment.

Closes #47
2023-08-04 15:55:40 +02:00
Bazsalanszky
5c39fddbc6 Fix bug with the "show all comments" button
Fix bug where if the "Show all comments" button is pressed, the original comment disappears.
Closes #36
2023-08-04 15:30:20 +02:00
Bazsalanszky
a708853199 Fix community icon on compact view
Closes #43
2023-08-04 15:22:53 +02:00
Bazsalanszky
acb651cf92 Merge pull request 'Remove reddit related stuff' (#51) from reddit_removal into master
Reviewed-on: https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/pulls/51
2023-08-04 13:06:20 +00:00
Bazsalanszky
562c91acb2 Fix sort types in settings
Closes #25
2023-08-04 15:00:42 +02:00
Bazsalanszky
484f9607b1 Removed description from the community view page
The community's description was shown both on the community page (bellow the subscription button) and on the about page. Now it's only on the about page, to make the UI less cluttered.
Closes #42
2023-08-04 14:38:34 +02:00
Bazsalanszky
9149ee224c Better since time on Community Pages 2023-08-04 14:34:30 +02:00
Bazsalanszky
1bb1d3b9af Fix sort types on search page
Closes #19
2023-08-04 14:05:40 +02:00
Bazsalanszky
0b76390069 View user bug fix
Resolved the issue where clicking on a user from the inbox was not functioning properly.
2023-08-04 13:19:24 +02:00
Bazsalanszky
5de8751079 Remove some reddit specific options from a few places
Removed multireddits. Also remove the "random" option from the "more options" menu
2023-08-04 13:19:24 +02:00
Bazsalanszky
4bfe1b0c02 Remove unused elements from navigation drawer
This makes it more accurate for Lemmy.
2023-08-04 13:19:24 +02:00
Kuro
15c1676d0b Removed mentionings of reddit in english and german and a few mentionings in other languages. 2023-08-04 13:19:24 +02:00
Bazsalanszky
49ff90aad1 Merge pull request 'Removed mentionings of reddit in english and german and a few mentionings in other languages.' (#44) from Kuro/Infinity-For-Lemmy:removing_reddit_strings into master
Reviewed-on: https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/pulls/44
2023-08-04 07:48:20 +00:00
Kuro
6adaaf1965 Removed mentionings of reddit in english and german and a few mentionings in other languages. 2023-08-03 15:28:27 +02:00
Balazs Toldi
6d114f84fa Fix post when editing a text only post 2023-08-03 09:02:08 +02:00
Balazs Toldi
394cff9ebe Inbox notification update
This commit trys to add notifications to the app by Updateing the PullNotificationWorker class.
2023-08-03 08:26:52 +02:00
Balazs Toldi
465abd4498 Inbox Read all button function
This commit adds functionality for the read all option in the InboxActivity
2023-08-03 07:51:22 +02:00
Balazs Toldi
0178569f14 Mark as read for replies 2023-08-03 07:21:41 +02:00
Balazs Toldi
f7185445e1 Show inbox count on navigation drawer 2023-08-03 06:58:55 +02:00
Balazs Toldi
d4b107bc79 Add option to have circular FAB icon 2023-08-02 22:03:26 +02:00
Balazs Toldi
fd14753a1d Fixing bug where posts on the home screen with images look different after refreshing.
This bug fixes the issue my previous commit caused. Now post loading go brrrrr.
2023-08-02 21:37:09 +02:00
Balazs Toldi
7cc4e93ad4 Faster Post parsing
This commit dramatically increases post parsing and loading times. However, posts on the home screen with images are bugged.
2023-08-02 07:52:20 +02:00
Balazs Toldi
4c95404fe1 Basic InboxActivity
This commits adds basic functionality for the Inbox Activity. It can now show you replies and mentions.
2023-08-01 15:24:44 +02:00
Balazs Toldi
1c2212f0fe Remove .github folder 2023-08-01 12:54:50 +02:00
Balazs Toldi
065fcedd34 Delete posts and comments
This comments makes the delete post and delete comment buttons functional.

Closes #29
2023-08-01 09:57:15 +02:00
Balazs Toldi
3a66a79f49 Post editing functionality
Post editing is now functional! You can now edit the post you've made.

Closes #30
2023-08-01 09:32:34 +02:00
Balazs Toldi
907f6e92c3 Bump version 2023-07-31 22:33:42 +02:00
Balazs Toldi
426c3e6979 Better posting activities
You can now add content to Image and Link type posts!
2023-07-31 22:18:37 +02:00
Balazs Toldi
92292be472 Groundwork for editing posts 2023-07-31 16:21:45 +02:00
Balazs Toldi
3e10186c7c Mark as read functionality
This commits adds the mark post as read functionality. Previously, the app crashed if it tried to mark a post as read.
2023-07-31 15:33:59 +02:00
Balazs Toldi
1974322013 Resolve comments from links
Now you can set the app as a the default app for lemmy URLs.
Closes #32 and #18
2023-07-31 14:34:21 +02:00
Balazs Toldi
a2e22bc525 Resolve posts from links 2023-07-31 13:46:34 +02:00
471 changed files with 50661 additions and 37151 deletions

BIN
.assets/codeberg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
.assets/fdroid-badge.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@@ -0,0 +1,49 @@
---
name: "Bug Report"
about: "Report a Bug!"
title: " [Bug] "
ref: "master"
labels:
- Kind/Bug
---
### Description of the Issue:
<!-- Provide a clear and concise description of what the issue is about. -->
### Steps to Reproduce:
<!-- Explain the steps to reproduce the issue, if applicable. -->
1.
2.
3.
### Expected Behavior:
<!-- Describe what you expected to happen. -->
### Actual Behavior:
<!-- Describe what actually happened. Include screenshots if applicable. -->
### App Information:
- **Version:** <!-- e.g. 1.0.0 -->
- **Device:** <!-- e.g. Samsung Galaxy S10 -->
- **Android Version:** <!-- e.g. Android 11 -->
- **Installation Source:** <!-- e.g. Google Play Store, APK -->
### Log Files:
<!-- If applicable, include log files or error messages related to this issue. -->
### Additional Context:
<!-- Add any other context about the problem here, such as relevant system configuration or screenshots. -->
### Potential Solutions or Workarounds:
<!-- If you know of any potential solutions or workarounds for this issue, please describe them here. -->

View File

@@ -0,0 +1,28 @@
---
name: "Feature request"
about: "Request a feature!"
title: "[Feature] "
ref: "master"
labels:
- Kind/Feature
---
### Description
<!-- A clear and concise description of what the feature is and what problem it solves. -->
### Background
<!-- Any background information or context that would be helpful. -->
### Proposed Solution
<!--
- Describe the solution you'd like.
- A clear and concise description of what you want to happen.
- Include any alternative solutions or features you've considered.
- Add any technical details, mockups, or examples if available.
-->
### Additional Context
<!-- Add any other context, screenshots, or links to existing issues/discussions about the feature here. -->

View File

@@ -1 +0,0 @@

View File

@@ -1 +0,0 @@

View File

@@ -1,14 +0,0 @@
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to read this announcement!
- type: textarea
id: description
attributes:
label: description
description: Please describe the announcement in as much detail as possible.
placeholder: Make an announcement here...
validations:
required: true

View File

@@ -1,74 +0,0 @@
body:
- type: markdown
attributes:
value: |
Have an idea for a new feature or an improvement? Let us know here!
- type: checkboxes
id: checklist
attributes:
label: Checklist
options:
- label: I have used the search function for [open](https://github.com/Docile-Alligator/Infinity-For-Reddit/discussions/categories/ideas) **and** [closed](https://github.com/Docile-Alligator/Infinity-For-Reddit/discussions/categories/completed-ideas) ideas to see if someone else has already submitted the same request.
required: true
- label: I will describe the feature with as much detail as possible.
required: true
- type: markdown
attributes:
value: |
Thanks for taking the time to share your idea!
- type: textarea
id: description
attributes:
label: Description
description: Please describe your idea in as much detail as possible.
placeholder: I think it would be great if...
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Alternatives
description: Please describe any alternative solutions or features you've considered.
placeholder: I've considered...
validations:
required: false
- type: textarea
id: additional
attributes:
label: Additional context
description: Add your use-case, screenshots, mock-up, or anything else you think might be helpful.
placeholder: I think this would be a great addition because...
validations:
required: true
- type: dropdown
id: importance
attributes:
label: How important is this feature?
multiple: false
options:
- Critical
- Important
- Nice to have
- type: textarea
id: other
attributes:
label: Anything else?
description: Is there anything else you'd like to add?
validations:
required: false
- type: textarea
id: solution
attributes:
label: Solution
description: If you have an idea of how this can be implemented, please share it here.
placeholder: I think this could be done by...
validations:
required: false

2
.github/FUNDING.yml vendored
View File

@@ -1,2 +0,0 @@
github: Docile-Alligator
patreon: docile_alligator

View File

@@ -1,94 +0,0 @@
name: Bug Report
description: Create a report to help us improve existing features
labels: ['type: possible bug']
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
- type: checkboxes
id: checklist
attributes:
label: Checklist
options:
- label: I have used the search function for [open](https://github.com/Docile-Alligator/Infinity-For-Reddit/issues) **and** [closed](https://github.com/Docile-Alligator/Infinity-For-Reddit/issues?q=is%3Aissue+is%3Aclosed) issues to see if someone else has already submitted the same bug report.
required: true
- label: I will describe the problem with as much detail as possible.
required: true
- label: If the bug only occurs with a certain link, post, image..., I will include the URL.
required: true
- type: input
id: version
attributes:
label: App version
description: We need the actual version number found on the settings screen.
placeholder: x.y.z
validations:
required: true
- type: dropdown
id: source
attributes:
label: Where did you get the app from
multiple: false
options:
- Google Play
- F-Droid
- Other
validations:
required: true
- type: input
id: android_version
attributes:
label: Android version
description: Please mention if you are using a custom rom!
validations:
required: true
- type: input
id: device
attributes:
label: Device model
- type: input
id: first
attributes:
label: First occurred
placeholder: about x days/weeks ago
- type: textarea
id: steps
attributes:
label: Steps to reproduce
placeholder: |
1. This
2. Then that
3. Then this
4. Etc.
- type: textarea
id: links
attributes:
label: Example post, link, markdown...
- type: textarea
id: expected
attributes:
label: Expected behaviour
description: After following the steps, what did you think Infinity would do?
- type: textarea
id: current
attributes:
label: Current behaviour
description: What did Infinity do instead? Screenshots might help. Usually, you can take a screenshot of your smartphone by pressing *Power* + *Volume down* for a few seconds.
- type: textarea
id: logs
attributes:
label: Logs
description: If you are experiencing a crash, including the stacktrace will likely get it fixed sooner.

View File

@@ -1,11 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: Feature Request
url: https://github.com/Docile-Alligator/Infinity-For-Reddit/discussions/categories/ideas
about: Discuss ideas for new features of changes
- name: Questions
url: https://github.com/Docile-Alligator/Infinity-For-Reddit/discussions/categories/q-a
about: Please ask and answer questions here.
- name: Help needed
url: https://github.com/Docile-Alligator/Infinity-For-Reddit/discussions/categories/help-needed
about: Please ask for help here

View File

@@ -1,23 +0,0 @@
version: 2
updates:
# Updates for Gradle dependencies used in the app
- package-ecosystem: gradle
directory: "/"
schedule:
interval: "daily"
commit-message:
prefix: "⬆[Gradle]"
reviewers:
- "Wladefant"
- "Docile-Alligator"
# Updates for GitHub Actions used in the repository
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: "weekly"
commit-message:
prefix: "⬆[GitHub Actions]"
reviewers:
- "Wladefant"
- "Docile-Alligator"

View File

@@ -1,32 +0,0 @@
name: Build
on:
push:
pull_request:
workflow_dispatch:
jobs:
Build:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Set-up JDK 11
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'temurin'
- name: Setup and build with Gradle
uses: gradle/gradle-build-action@v2
with:
arguments: build -x lint
- name: Upload apk
uses: actions/upload-artifact@v3
with:
name: Infinity-${{github.sha}}
path: app/build/outputs/apk/
if-no-files-found: error

View File

@@ -1,34 +0,0 @@
name: CodeQL
on:
push:
branches:
- master
pull_request:
workflow_dispatch:
schedule:
- cron: '0 12 * * *'
jobs:
Analyze:
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: java
- name: Autobuild
uses: github/codeql-action/autobuild@v2
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2

2
.gitignore vendored
View File

@@ -56,6 +56,8 @@ gen-external-apklibs
# NDK
obj/
**/ndkHelperBin
**/.cxx
# IntelliJ IDEA
*.iml

View File

@@ -1,14 +1,15 @@
pipeline:
steps:
build:
image: alvrme/alpine-android:android-33-jdk11
commands:
- apk add --no-cache python3
- ./gradlew :app:assembleRelease
when:
path: [ app/**, build.gradle ]
sign:
image: alvrme/alpine-android:android-33-jdk11
commands:
- ./scripts/apk-sign.sh LemmInfinity-signed.apk app/build/outputs/apk/release/app-release-unsigned.apk
- ./scripts/apk-sign.sh Eternity-signed.apk app/build/outputs/apk/release/app-release-unsigned.apk
secrets: [ APK_KS_PASS, APK_KS, APK_KS_ALIAS ]
when:
event: [ tag ]
@@ -17,11 +18,13 @@ pipeline:
settings:
base_url: https://codeberg.org
files:
- LemmInfinity-signed.apk
- Eternity-signed.apk
api_key:
from_secret: GITEA_ACCESS_TOKEN
target: main
prerelease: true
note: "This is an alpha release. Expect many bugs and unfinished features!"
when:
event: [ tag ]
event: [ tag ]
when:
event: [ push, tag, pull_request ]

77
.woodpecker/nightly.yaml Normal file
View File

@@ -0,0 +1,77 @@
clone:
git:
image: woodpeckerci/plugin-git
settings:
partial: false
steps:
build:
image: alvrme/alpine-android:android-33-jdk11
commands:
- apk add --no-cache python3
- ./gradlew :app:assembleNightly
sign:
image: alvrme/alpine-android:android-33-jdk11
commands:
- ./scripts/apk-sign.sh eu.toldi.infinityforlemmy.nightly.apk app/build/outputs/apk/nightly/eu.toldi.infinityforlemmy.nightly.apk
secrets: [ APK_KS_PASS, APK_KS, APK_KS_ALIAS ]
pull-repo-config:
image: codeberg.org/freeyourgadget/android-fdroid-tools:latest
commands:
- cd ..
- pwd
- mkdir repoconfig
- cd repoconfig
- pwd
- git clone --depth 1 https://codeberg.org/Bazsalanszky/fdroid-repo-config
- cp /woodpecker/src/codeberg.org/Bazsalanszky/Eternity/eu.toldi.infinityforlemmy.nightly.apk fdroid-repo-config/repo/
pull-pages:
image: codeberg.org/freeyourgadget/android-fdroid-tools:latest
commands:
- cd ..
- pwd
- mkdir pages
- cd pages
- pwd
- git clone --depth 2 https://codeberg.org/Bazsalanszky/pages
- cd pages
- git config user.name "CODEBERG CI"
- git config user.email "noreply@nodomain.nodomain"
# reset and remove, later force push, to keep repo size small
- git reset --soft HEAD~1
- git status
update-fdroid-data:
image: cs8898/android-fdroid-sdk:33.0.0
commands:
- pwd
- cd ../repoconfig/fdroid-repo-config/
- echo -n "$${FDROID_KS}" | base64 -d > keystore.p12
- cat keystore.p12 | sha256sum
- sed -i "s|KS_PASS|$${FDROID_KS_PASS}|g" config.yml
- sed -i "s|KEY_PASS|$${FDROID_KEY_PASS}|g" config.yml
- fdroid update
- fdroid deploy
- ls -laR repo
secrets: [ FDROID_KS_PASS, FDROID_KEY_PASS, FDROID_KS ]
push-pages-update-repo:
image: codeberg.org/freeyourgadget/android-fdroid-tools:latest
commands:
- if [ -f .do_not_build ]; then return 0; fi
- cd ../pages/pages/
- git add -A
- git status
- git diff
- ls -lsR fdroid/repo
- git commit -m "autodeploy"
- git remote remove origin
- git remote add origin https://Bazsalanszky:"$${GITEA_ACCESS_TOKEN}"@codeberg.org/Bazsalanszky/pages.git
# force push as we removed all data
- git push -f origin main
- cd ../../
- pwd
- ls -la
secrets: [ GITEA_ACCESS_TOKEN ]
when:
event: cron

110
README.md
View File

@@ -1,53 +1,97 @@
<h1 align="center">
Infinity for Lemmy
Eternity for Lemmy
</h1>
<div align="center">
A Lemmy client for Android written in Java. It's a fork of the [Infinity for Reddit](https://github.com/Docile-Alligator/Infinity-For-Reddit) project, currenty in early development.
<img align="right" src="https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/raw/branch/master/fastlane/metadata/android/en-US/images/icon.png" width=200>
</div>
<br>
<div align="center">
<img src="https://codeberg.org/Bazsalanszky/Eternity/raw/branch/master/fastlane/metadata/android/en-US/images/icon.png" width=256>
[![status-badge](https://ci.codeberg.org/api/badges/12474/status.svg)](https://ci.codeberg.org/12474)
[![status-badge](https://ci.codeberg.org/api/badges/12474/status.svg)](https://ci.codeberg.org/repos/12474)
[![Liberapay patrons](https://img.shields.io/liberapay/patrons/bazsalanszky)](https://liberapay.com/Bazsalanszky)
<a href="https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/issues">Report a Bug</a>
<a href="https://codeberg.org/Bazsalanszky/Eternity/issues">Report a Bug</a>
</div>
<br>
<div align="center">
<a href="https://f-droid.org/packages/eu.toldi.infinityforlemmy/">
<img src="./.assets/fdroid-badge.png" height="80">
</a>
<a href="https://play.google.com/store/apps/details?id=eu.toldi.infinityforlemmy">
<img src="./.assets/google-play-badge.png" height="80">
</a>
<a href="https://codeberg.org/Bazsalanszky/Eternity/releases/">
<img src="./.assets/codeberg.png" height="80">
</a>
</div>
---
## Action Items for Infinity for Lemmy
## Features
Infinity for Lemmy is currently in the early stages of development. Expect many unfinished features and bugs!
Eternity is currently in the early stages of development. Expect many unfinished features and bugs!
- [x] Implementation of basic post browsing feature
- [x] Support for multiple account handling
- [x] Functionality for post upvotes/downvotes
- [x] Functionality to browse comments
- [ ] Capability for creating a new post
- [x] Ability to create comments
- [ ] Elimination of code/string references specific to Reddit
- [ ] Incorporation of private messaging feature
- [ ] Feature for saving posts
- [ ] Account editing function
- [ ] Multi community view?
### Browsing Lemmy
- Explore various feeds (Subscribed/Local/All) and communities
- Subscribe or unsubscribe from specific communities, with the option to block
- Discover communities federated with the current instance
- Favorite a community for quick access
- Manage your subscriptions and blocked communities
### Content Engagement
- Engage with content by voting, saving, sharing, and creating posts or comments
- Enjoy endless scrolling through feeds and posts
- Tailor the view settings for posts (card,compact, gallery)
- Set default preferences for post and comment sorting
- Stay updated with notifications for replies
### Account Management
- Sign in to multiple accounts or instances, and effortlessly switch between them
- Use the inbox features to view replies, mentions, and private messages
- Access your profile to view your posts, comments, and saved content
### Customization
- Choose between various theme options including Light, Dark, OLED
- Support Material You theming
- Explore user-created themes
- Customize font settings
- Optional bottom navigation bar
- Discover a plethora of other customization features
<img
src="https://codeberg.org/Bazsalanszky/Eternity/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png"
alt="Screenshot 1"
height="200" >
<img
src="https://codeberg.org/Bazsalanszky/Eternity/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png"
alt="Screenshot 2"
height="200" >
<img
src="https://codeberg.org/Bazsalanszky/Eternity/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png"
alt="Screenshot 3"
height="200" >
<img
src="https://codeberg.org/Bazsalanszky/Eternity/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png"
alt="Screenshot 4"
height="200" >
<img
src="https://codeberg.org/Bazsalanszky/Eternity/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png"
alt="Screenshot 5"
height="200" >
## Contributing
@@ -65,16 +109,21 @@ Don't forget to give the project a star! Thanks again!
4. Push to the Branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request
Here are other ways you can help:
### Translation
- [Report Bugs](https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/issues)
You can also help Eternity by translating it to your native langugage! Translations are done via [Weblate](https://translate.codeberg.org/projects/infinity-for-lemmy/app/)!
[![Translation](https://translate.codeberg.org/widgets/infinity-for-lemmy/-/app/multi-auto.svg)](https://translate.codeberg.org/engage/Eternity/)
### Reporting bugs
You can also contribute by [reporting bugs](https://codeberg.org/Bazsalanszky/Eternity/issues)
<p align="right">(<a href="#top">back to top</a>)</p>
## License
Distributed under the AGPL-3.0 License. See <a href="https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/src/branch/master/LICENSE">LICENSE</a> for more information.
Distributed under the AGPL-3.0 License. See <a href="https://codeberg.org/Bazsalanszky/Eternity/src/branch/master/LICENSE">LICENSE</a> for more information.
<p align="right">(<a href="#top">back to top</a>)</p>
@@ -82,7 +131,6 @@ Distributed under the AGPL-3.0 License. See <a href="https://codeberg.org/Bazsal
[@bazsalanszky@lemmy.toldi.eu](https://lemmy.toldi.eu/u/bazsalanszky) - (Owner)
Project Link: [https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy](https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy)
Project Link: [https://codeberg.org/Bazsalanszky/Eternity](https://codeberg.org/Bazsalanszky/Eternity)
<p align="right">(<a href="#top">back to top</a>)</p>

View File

@@ -1,5 +1,18 @@
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
def getCommitVersionCode = { ->
try {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'rev-list', 'HEAD', '--count'
standardOutput = stdout
}
return Integer.valueOf(stdout.toString().trim())
} catch (ignored) {
return null
}
}
android {
@@ -8,8 +21,8 @@ android {
applicationId "eu.toldi.infinityforlemmy"
minSdk 21
targetSdk 33
versionCode 125
versionName "0.0.5"
versionCode 131
versionName "0.1.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
javaCompileOptions {
annotationProcessorOptions {
@@ -18,10 +31,13 @@ android {
}
}
buildTypes {
release {
minifyEnabled false
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
minifiedRelease {
initWith buildTypes.release
zipAlignEnabled true
@@ -33,7 +49,33 @@ android {
applicationIdSuffix '.debug'
versionNameSuffix ' (DEBUG)'
}
nightly {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
applicationIdSuffix '.nightly'
versionNameSuffix ' (NIGHTLY)'
}
applicationVariants.all { variant ->
variant.resValue "string", "applicationId", variant.applicationId
if (variant.buildType.name == 'nightly') {
variant.outputs.all {
setVersionCodeOverride(getCommitVersionCode())
setVersionNameOverride(variant.versionName)
outputFileName = "${applicationId}.apk"
}
}
}
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
@@ -52,7 +94,41 @@ android {
buildFeatures {
viewBinding true
}
packagingOptions {
doNotStrip '**/*.so'
}
// Kotlin jvm target
kotlinOptions {
jvmTarget = '11'
}
namespace 'eu.toldi.infinityforlemmy'
task rearrangeClass(type: Exec) {
commandLine 'python3', '../scripts/fixEventBus.py'
}
applicationVariants.all { variant ->
if (variant.name == 'release') {
task("compileSingleFile${variant.name.capitalize()}", type: JavaCompile, dependsOn: rearrangeClass) {
def filePath = project.rootDir.absolutePath + '/app/build/generated/ap_generated_sources/release/out/eu/toldi/infinityforlemmy/'
source = files(filePath)
includes = ["**/EventBusIndex.java"]
classpath = variant.getCompileClasspath() + files(project.rootDir.absolutePath + '/app/build/intermediates/javac/release/classes')
destinationDir = file("$buildDir/intermediates/javac/release/classes")
}
tasks.withType(JavaCompile).all { task ->
if (task.name == 'compileReleaseJavaWithJavac') {
task.finalizedBy "compileSingleFile${variant.name.capitalize()}"
}
}
}
}
}
dependencies {
@@ -63,6 +139,7 @@ dependencies {
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
def lifecycleVersion = "2.5.1"
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion"
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycleVersion"
@@ -108,6 +185,7 @@ dependencies {
implementation "com.google.dagger:dagger:$daggerVersion"
annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion"
// Binding
// NOTE: Deprecated in favor of viewbinding
def butterknifeVersion = "10.2.3"
@@ -149,11 +227,12 @@ dependencies {
def glideVersion = "4.12.0"
implementation "com.github.bumptech.glide:glide:$glideVersion"
annotationProcessor "com.github.bumptech.glide:compiler:$glideVersion"
implementation "com.github.bumptech.glide:okhttp-integration:$glideVersion"
implementation 'jp.wasabeef:glide-transformations:4.3.0'
implementation 'com.github.santalu:aspect-ratio-imageview:1.0.9'
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.23'
def bivVersion = "1.8.1"
implementation "com.github.piasy:BigImageViewer:bivVersion"
implementation "com.github.piasy:BigImageViewer:$bivVersion"
implementation "com.github.piasy:GlideImageLoader:$bivVersion"
implementation "com.github.piasy:GlideImageViewFactory:$bivVersion"
@@ -165,6 +244,7 @@ dependencies {
implementation "io.noties.markwon:recycler-table:$markwonVersion"
implementation "io.noties.markwon:simple-ext:$markwonVersion"
implementation "io.noties.markwon:inline-parser:$markwonVersion"
implementation "io.noties.markwon:image-glide:$markwonVersion"
implementation 'com.atlassian.commonmark:commonmark-ext-gfm-tables:0.14.0'
implementation 'me.saket:better-link-movement-method:2.2.0'
@@ -191,8 +271,42 @@ dependencies {
implementation 'com.otaliastudios:zoomlayout:1.9.0'
implementation 'androidx.core:core-splashscreen:1.0.1'
/**** Builds and flavors ****/
// debugImplementation because LeakCanary should only run in debug builds.
//debugImplementation 'com.squareup.leakcanary:leakcanary-android:x.y'
}
// NB: Android Studio can't find the imports; this does not affect the
// actual build since Gradle can find them just fine.
import com.android.tools.profgen.ArtProfileKt
import com.android.tools.profgen.ArtProfileSerializer
import com.android.tools.profgen.DexFile
project.afterEvaluate {
tasks.each { task ->
if (task.name.startsWith("compile") && task.name.endsWith("ReleaseArtProfile")) {
task.doLast {
outputs.files.each { file ->
if (file.name.endsWith(".profm")) {
println("Sorting ${file} ...")
def version = ArtProfileSerializer.valueOf("METADATA_0_0_2")
def profile = ArtProfileKt.ArtProfile(file)
def keys = new ArrayList(profile.profileData.keySet())
def sortedData = new LinkedHashMap()
Collections.sort keys, new DexFile.Companion()
keys.each { key -> sortedData[key] = profile.profileData[key] }
new FileOutputStream(file).with {
write(version.magicBytes$profgen)
write(version.versionBytes$profgen)
version.write$profgen(it, sortedData, "")
}
}
}
}
}
}
}

View File

@@ -5,6 +5,8 @@
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
-dontobfuscate
-keepattributes SourceFile,LineNumberTable
## Preferences reflection
-keep class * extends androidx.preference.PreferenceFragmentCompat

View File

@@ -1,3 +1,3 @@
<resources>
<string name="application_name" translatable="false">Infinity for Lemmy (Debug)</string>
<string name="application_name" translatable="false">Eternity (Debug)</string>
</resources>

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
xmlns:tools="http://schemas.android.com/tools"
package="eu.toldi.infinityforlemmy">
<queries>
<intent>
@@ -23,7 +24,7 @@
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<application
android:name=".Infinity"
@@ -35,6 +36,29 @@
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true"
tools:replace="android:label">
<activity
android:name=".activities.InstanceInfoActivity"
android:label="@string/instance_info"
android:configChanges="orientation|screenLayout|screenSize|layoutDirection"
android:parentActivityName=".activities.MainActivity"
android:theme="@style/AppTheme.Slidable" />
<activity
android:name=".activities.CommentFilterUsageListingActivity"
android:parentActivityName=".activities.SettingsActivity"
android:theme="@style/AppTheme.NoActionBar"
android:exported="false" />
<activity
android:name=".activities.CustomizeCommentFilterActivity"
android:label="@string/customize_comment_filter_activity_label"
android:parentActivityName=".activities.SettingsActivity"
android:theme="@style/AppTheme.NoActionBar"
android:exported="false" />
<activity
android:name=".activities.CommentFilterPreferenceActivity"
android:label="@string/comment_filter_preference_activity_label"
android:parentActivityName=".activities.SettingsActivity"
android:theme="@style/AppTheme.NoActionBar"
android:exported="false" />
<activity
android:name=".activities.HistoryActivity"
android:exported="false"
@@ -430,12 +454,38 @@
android:label="@string/application_name"
android:theme="@style/AppTheme.Launcher"
android:windowSoftInputMode="adjustPan">
<intent-filter>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity-alias
android:name=".DefaultIcon"
android:targetActivity=".activities.MainActivity"
android:label="@string/application_name"
android:enabled="true"
android:icon="@mipmap/ic_launcher"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</activity-alias>
<activity-alias
android:name=".OriginalIcon"
android:targetActivity=".activities.MainActivity"
android:label="@string/application_name"
android:enabled="false"
android:icon="@mipmap/original_ic_launcher"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity
android:name=".activities.LoginActivity"
android:configChanges="orientation|screenLayout|screenSize|layoutDirection"

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

@@ -2,16 +2,22 @@ package eu.toldi.infinityforlemmy;
import android.app.Application;
import org.jetbrains.annotations.NotNull;
import javax.inject.Singleton;
import dagger.BindsInstance;
import dagger.Component;
import eu.toldi.infinityforlemmy.activities.AccountPostsActivity;
import eu.toldi.infinityforlemmy.activities.AccountSavedThingActivity;
import eu.toldi.infinityforlemmy.activities.BlockedThingListingActivity;
import eu.toldi.infinityforlemmy.activities.CommentActivity;
import eu.toldi.infinityforlemmy.activities.CommentFilterPreferenceActivity;
import eu.toldi.infinityforlemmy.activities.CommentFilterUsageListingActivity;
import eu.toldi.infinityforlemmy.activities.CreateMultiRedditActivity;
import eu.toldi.infinityforlemmy.activities.CustomThemeListingActivity;
import eu.toldi.infinityforlemmy.activities.CustomThemePreviewActivity;
import eu.toldi.infinityforlemmy.activities.CustomizeCommentFilterActivity;
import eu.toldi.infinityforlemmy.activities.CustomizePostFilterActivity;
import eu.toldi.infinityforlemmy.activities.CustomizeThemeActivity;
import eu.toldi.infinityforlemmy.activities.EditCommentActivity;
@@ -22,8 +28,8 @@ import eu.toldi.infinityforlemmy.activities.FetchRandomSubredditOrPostActivity;
import eu.toldi.infinityforlemmy.activities.FilteredPostsActivity;
import eu.toldi.infinityforlemmy.activities.FullMarkdownActivity;
import eu.toldi.infinityforlemmy.activities.GiveAwardActivity;
import eu.toldi.infinityforlemmy.activities.HistoryActivity;
import eu.toldi.infinityforlemmy.activities.InboxActivity;
import eu.toldi.infinityforlemmy.activities.InstanceInfoActivity;
import eu.toldi.infinityforlemmy.activities.LinkResolverActivity;
import eu.toldi.infinityforlemmy.activities.LockScreenActivity;
import eu.toldi.infinityforlemmy.activities.LoginActivity;
@@ -65,14 +71,17 @@ import eu.toldi.infinityforlemmy.activities.ViewVideoActivity;
import eu.toldi.infinityforlemmy.activities.WebViewActivity;
import eu.toldi.infinityforlemmy.activities.WikiActivity;
import eu.toldi.infinityforlemmy.bottomsheetfragments.AccountChooserBottomSheetFragment;
import eu.toldi.infinityforlemmy.bottomsheetfragments.CommentMoreBottomSheetFragment;
import eu.toldi.infinityforlemmy.bottomsheetfragments.FlairBottomSheetFragment;
import eu.toldi.infinityforlemmy.fragments.BlockedCommunitiesListingFragment;
import eu.toldi.infinityforlemmy.fragments.BlockedUsersListingFragment;
import eu.toldi.infinityforlemmy.fragments.CommentsListingFragment;
import eu.toldi.infinityforlemmy.fragments.FollowedUsersListingFragment;
import eu.toldi.infinityforlemmy.fragments.HistoryPostFragment;
import eu.toldi.infinityforlemmy.fragments.InboxFragment;
import eu.toldi.infinityforlemmy.fragments.MorePostsInfoFragment;
import eu.toldi.infinityforlemmy.fragments.MultiRedditListingFragment;
import eu.toldi.infinityforlemmy.fragments.PostFragment;
import eu.toldi.infinityforlemmy.fragments.PrivateMessageFragment;
import eu.toldi.infinityforlemmy.fragments.SidebarFragment;
import eu.toldi.infinityforlemmy.fragments.SubredditListingFragment;
import eu.toldi.infinityforlemmy.fragments.SubscribedSubredditsListingFragment;
@@ -105,7 +114,7 @@ import eu.toldi.infinityforlemmy.settings.TranslationFragment;
import eu.toldi.infinityforlemmy.settings.VideoPreferenceFragment;
@Singleton
@Component(modules = {AppModule.class, NetworkModule.class})
@Component(modules = {AppModule.class, NetworkModule.class, PostEnricherModule.class})
public interface AppComponent {
void inject(MainActivity mainActivity);
@@ -301,12 +310,26 @@ public interface AppComponent {
void inject(MaterialYouWorker materialYouWorker);
void inject(HistoryPostFragment historyPostFragment);
void inject(HistoryActivity historyActivity);
void inject(MorePostsInfoFragment morePostsInfoFragment);
void inject(BlockedThingListingActivity blockedThingListingActivity);
void inject(BlockedCommunitiesListingFragment blockedCommunitiesListingFragment);
void inject(BlockedUsersListingFragment blockedUsersListingFragment);
void inject(CommentMoreBottomSheetFragment commentMoreBottomSheetFragment);
void inject(PrivateMessageFragment privateMessageFragment);
void inject(@NotNull InstanceInfoActivity instanceInfoActivity);
void inject(CommentFilterPreferenceActivity commentFilterPreferenceActivity);
void inject(CustomizeCommentFilterActivity customizeCommentFilterActivity);
void inject(CommentFilterUsageListingActivity commentFilterUsageListingActivity);
@Component.Factory
interface Factory {
AppComponent create(@BindsInstance Application application);

View File

@@ -22,6 +22,8 @@ import dagger.Module;
import dagger.Provides;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.customviews.LoopAvailableExoCreator;
import eu.toldi.infinityforlemmy.post.MarkPostAsRead;
import eu.toldi.infinityforlemmy.post.ObjectResolver;
import eu.toldi.infinityforlemmy.utils.CustomThemeSharedPreferencesUtils;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import eu.toldi.infinityforlemmy.videoautoplay.Config;
@@ -192,8 +194,8 @@ abstract class AppModule {
@Provides
@Singleton
static ExoCreator provideExoCreator(Config config,
ToroExo toroExo,
@Named("default") SharedPreferences sharedPreferences) {
ToroExo toroExo,
@Named("default") SharedPreferences sharedPreferences) {
return new LoopAvailableExoCreator(toroExo, config, sharedPreferences);
}
@@ -202,4 +204,16 @@ abstract class AppModule {
static Executor provideExecutor() {
return Executors.newFixedThreadPool(4);
}
@Provides
@Singleton
static ObjectResolver provideObjectResolver(@Named("no_oauth") RetrofitHolder retrofitHolder) {
return new ObjectResolver(retrofitHolder);
}
@Provides
@Singleton
static MarkPostAsRead provideMarkPostAsRead(@Named("no_oauth") RetrofitHolder retrofitHolder) {
return new MarkPostAsRead(retrofitHolder);
}
}

View File

@@ -5,7 +5,9 @@ import androidx.annotation.NonNull;
import java.util.HashMap;
import java.util.Map;
import eu.toldi.infinityforlemmy.apis.RedditAPI;
import eu.toldi.infinityforlemmy.apis.LemmyAPI;
import eu.toldi.infinityforlemmy.dto.DeleteCommentDTO;
import eu.toldi.infinityforlemmy.dto.DeletePostDTO;
import eu.toldi.infinityforlemmy.utils.APIUtils;
import retrofit2.Call;
import retrofit2.Callback;
@@ -13,10 +15,11 @@ import retrofit2.Response;
import retrofit2.Retrofit;
public class DeleteThing {
public static void delete(Retrofit oauthRetrofit, String fullname, String accessToken, DeleteThingListener deleteThingListener) {
public static void deletePost(Retrofit retrofit, int post_id, String accessToken, DeleteThingListener deleteThingListener) {
Map<String, String> params = new HashMap<>();
params.put(APIUtils.ID_KEY, fullname);
oauthRetrofit.create(RedditAPI.class).delete(APIUtils.getOAuthHeader(accessToken), params).enqueue(new Callback<String>() {
params.put(APIUtils.ID_KEY, String.valueOf(post_id));
retrofit.create(LemmyAPI.class).postDelete(new DeletePostDTO(post_id, true, accessToken)).enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
if (response.isSuccessful()) {
@@ -33,6 +36,27 @@ public class DeleteThing {
});
}
public static void deleteComment(Retrofit retrofit, int comment_id, String accessToken, DeleteThingListener deleteThingListener) {
Map<String, String> params = new HashMap<>();
params.put(APIUtils.ID_KEY, String.valueOf(comment_id));
retrofit.create(LemmyAPI.class).commentDelete(new DeleteCommentDTO(comment_id, true, accessToken)).enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
if (response.isSuccessful()) {
deleteThingListener.deleteSuccess();
} else {
deleteThingListener.deleteFailed();
}
}
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
deleteThingListener.deleteFailed();
}
});
}
public interface DeleteThingListener {
void deleteSuccess();

View File

@@ -1,7 +1,5 @@
package eu.toldi.infinityforlemmy;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Handler;
import org.json.JSONException;
@@ -12,9 +10,7 @@ import java.util.concurrent.Executor;
import eu.toldi.infinityforlemmy.apis.GfycatAPI;
import eu.toldi.infinityforlemmy.apis.RedgifsAPI;
import eu.toldi.infinityforlemmy.utils.APIUtils;
import eu.toldi.infinityforlemmy.utils.JSONUtils;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;
@@ -44,14 +40,12 @@ public class FetchGfycatOrRedgifsVideoLinks {
});
}
public static void fetchRedgifsVideoLinks(Context context, Executor executor, Handler handler, Retrofit redgifsRetrofit,
SharedPreferences currentAccountSharedPreferences,
public static void fetchRedgifsVideoLinks(Executor executor, Handler handler, Retrofit redgifsRetrofit,
String gfycatId,
FetchGfycatOrRedgifsVideoLinksListener fetchGfycatOrRedgifsVideoLinksListener) {
executor.execute(() -> {
try {
Response<String> response = redgifsRetrofit.create(RedgifsAPI.class).getRedgifsData(APIUtils.getRedgifsOAuthHeader(currentAccountSharedPreferences.getString(SharedPreferencesUtils.REDGIFS_ACCESS_TOKEN, "")),
gfycatId, APIUtils.USER_AGENT).execute();
Response<String> response = redgifsRetrofit.create(RedgifsAPI.class).getRedgifsData(gfycatId).execute();
if (response.isSuccessful()) {
parseRedgifsVideoLinks(handler, response.body(), fetchGfycatOrRedgifsVideoLinksListener);
} else {

View File

@@ -1,7 +1,6 @@
package eu.toldi.infinityforlemmy;
import android.os.AsyncTask;
import android.text.Html;
import androidx.annotation.NonNull;
@@ -9,9 +8,6 @@ import org.json.JSONException;
import org.json.JSONObject;
import eu.toldi.infinityforlemmy.apis.LemmyAPI;
import eu.toldi.infinityforlemmy.apis.RedditAPI;
import eu.toldi.infinityforlemmy.utils.APIUtils;
import eu.toldi.infinityforlemmy.utils.JSONUtils;
import eu.toldi.infinityforlemmy.utils.LemmyUtils;
import retrofit2.Call;
import retrofit2.Callback;
@@ -83,7 +79,7 @@ public class FetchMyInfo {
if (!person.isNull("banner")) {
bannerImageUrl = person.getString("banner");
}
display_name = person.getString("name");
display_name = (person.has("display_name")) ? person.getString("display_name") : person.getString("name");
redditDataRoomDatabase.accountDao().updateAccountInfo(name, profileImageUrl, bannerImageUrl);
} catch (JSONException e) {
parseFailed = true;

View File

@@ -20,6 +20,7 @@ import retrofit2.Response;
public class FetchStreamableVideo {
public interface FetchStreamableVideoListener {
void success(StreamableVideo streamableVideo);
void failed();
}
@@ -33,7 +34,12 @@ public class FetchStreamableVideo {
String title = jsonObject.getString(JSONUtils.TITLE_KEY);
JSONObject filesObject = jsonObject.getJSONObject(JSONUtils.FILES_KEY);
StreamableVideo.Media mp4 = parseMedia(filesObject.getJSONObject(JSONUtils.MP4_KEY));
StreamableVideo.Media mp4Mobile = parseMedia(filesObject.getJSONObject(JSONUtils.MP4_MOBILE_KEY));
StreamableVideo.Media mp4MobileTemp = null;
try {
mp4MobileTemp = parseMedia(filesObject.getJSONObject(JSONUtils.MP4_MOBILE_KEY));
} catch (JSONException e) {
}
StreamableVideo.Media mp4Mobile = mp4MobileTemp;
handler.post(() -> fetchStreamableVideoListener.success(new StreamableVideo(title, mp4, mp4Mobile)));
} else {
handler.post(fetchStreamableVideoListener::failed);
@@ -55,7 +61,12 @@ public class FetchStreamableVideo {
String title = jsonObject.getString(JSONUtils.TITLE_KEY);
JSONObject filesObject = jsonObject.getJSONObject(JSONUtils.FILES_KEY);
StreamableVideo.Media mp4 = parseMedia(filesObject.getJSONObject(JSONUtils.MP4_KEY));
StreamableVideo.Media mp4Mobile = parseMedia(filesObject.getJSONObject(JSONUtils.MP4_MOBILE_KEY));
StreamableVideo.Media mp4MobileTemp = null;
try {
mp4MobileTemp = parseMedia(filesObject.getJSONObject(JSONUtils.MP4_MOBILE_KEY));
} catch (JSONException e) {
}
StreamableVideo.Media mp4Mobile = mp4MobileTemp;
if (mp4 == null && mp4Mobile == null) {
handler.post(fetchStreamableVideoListener::failed);
return;

View File

@@ -11,6 +11,16 @@ import android.os.Bundle;
import android.view.WindowManager;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;
import androidx.lifecycle.ProcessLifecycleOwner;
import com.bumptech.glide.Glide;
import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader;
import com.bumptech.glide.load.model.GlideUrl;
import com.evernote.android.state.StateSaver;
import com.livefront.bridge.Bridge;
import com.livefront.bridge.SavedStateHandler;
@@ -18,15 +28,11 @@ import com.livefront.bridge.SavedStateHandler;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import java.io.InputStream;
import javax.inject.Inject;
import javax.inject.Named;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;
import androidx.lifecycle.ProcessLifecycleOwner;
import eu.toldi.infinityforlemmy.activities.LockScreenActivity;
import eu.toldi.infinityforlemmy.broadcastreceivers.NetworkWifiStatusReceiver;
import eu.toldi.infinityforlemmy.broadcastreceivers.WallpaperChangeReceiver;
@@ -38,6 +44,8 @@ import eu.toldi.infinityforlemmy.font.FontFamily;
import eu.toldi.infinityforlemmy.font.TitleFontFamily;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import eu.toldi.infinityforlemmy.utils.Utils;
import okhttp3.Call;
import okhttp3.OkHttpClient;
public class Infinity extends Application implements LifecycleObserver {
public Typeface typeface;
@@ -55,6 +63,9 @@ public class Infinity extends Application implements LifecycleObserver {
@Inject
@Named("security")
SharedPreferences mSecuritySharedPreferences;
@Inject
@Named("glide")
OkHttpClient glideOkHttpClient;
@Override
public void onCreate() {
@@ -159,6 +170,9 @@ public class Infinity extends Application implements LifecycleObserver {
registerReceiver(mNetworkWifiStatusReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
registerReceiver(new WallpaperChangeReceiver(mSharedPreferences), new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED));
OkHttpUrlLoader.Factory factory = new OkHttpUrlLoader.Factory((Call.Factory) glideOkHttpClient);
Glide.get(this).getRegistry().replace(GlideUrl.class, InputStream.class, factory);
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)

View File

@@ -9,16 +9,16 @@ import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
import eu.toldi.infinityforlemmy.apis.RedgifsAPI;
import eu.toldi.infinityforlemmy.apis.StreamableAPI;
import eu.toldi.infinityforlemmy.network.SortTypeConverterFactory;
import eu.toldi.infinityforlemmy.comment.LemmyCommentAPI;
import eu.toldi.infinityforlemmy.post.LemmyPostAPI;
import eu.toldi.infinityforlemmy.privatemessage.LemmyPrivateMessageAPI;
import eu.toldi.infinityforlemmy.utils.APIUtils;
import okhttp3.ConnectionPool;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.guava.GuavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;
@Module(includes = AppModule.class)
abstract class NetworkModule {
@@ -35,6 +35,21 @@ abstract class NetworkModule {
.build();
}
@Provides
@Named("glide")
@Singleton
static OkHttpClient provideGlideOkHttp(@Named("base") OkHttpClient baseOkHttp,
@Named("RedgifsAccessTokenAuthenticator") Interceptor redGifsAuthenticator) {
return baseOkHttp.newBuilder()
.addInterceptor(chain -> chain.proceed(
chain.request()
.newBuilder()
.header("User-Agent", APIUtils.USER_AGENT)
.build()
))
.addInterceptor(redGifsAuthenticator)
.build();
}
@Provides
@Named("base")
@@ -166,6 +181,12 @@ abstract class NetworkModule {
.build();
}
@Provides
@Singleton
static RedgifsAPI provideRedgifsAPI(@Named("redgifs") Retrofit redgifsRetrofit) {
return redgifsRetrofit.create(RedgifsAPI.class);
}
@Provides
@Named("imgur")
@Singleton
@@ -216,4 +237,31 @@ abstract class NetworkModule {
static StreamableAPI provideStreamableApi(@Named("streamable") Retrofit streamableRetrofit) {
return streamableRetrofit.create(StreamableAPI.class);
}
@Provides
@Singleton
static LemmyPostAPI providePostAPI(@Named("no_oauth") RetrofitHolder retrofitHolder) {
return new LemmyPostAPI(retrofitHolder);
}
@Provides
@Singleton
static LemmyCommentAPI provideCommentAPI(@Named("no_oauth") RetrofitHolder retrofitHolder) {
return new LemmyCommentAPI(retrofitHolder);
}
@Provides
@Singleton
static LemmyPrivateMessageAPI provideLemmyPrivateMessageAPI(@Named("base") RetrofitHolder retrofit) {
return new LemmyPrivateMessageAPI(retrofit);
}
@Provides
@Named("lemmyVerse")
@Singleton
static Retrofit provideLemmyVerseRetrofit(@Named("base") RetrofitHolder retrofit) {
return retrofit.getRetrofit().newBuilder()
.baseUrl(APIUtils.LEMMYVERSE_API_BASE_URI)
.build();
}
}

View File

@@ -110,9 +110,9 @@ class ParseSubscribedThing {
boolean postingRestrictedToMods = community.getBoolean("posting_restricted_to_mods");
int instanceId = community.getInt("instance_id");
int subscribers = data.getJSONObject("counts").getInt("subscribers");
newSubscribedSubredditData.add(new SubscribedSubredditData(id, title, LemmyUtils.actorID2FullName(actorId), iconUrl, accountName));
newSubredditData.add(new SubredditData(id,name,title,description,removed,published,updated,deleted,nsfw,actorId,local,iconUrl,bannerImageUrl,hidden,postingRestrictedToMods,instanceId,subscribers));
boolean isBlocked = data.getBoolean("blocked");
newSubscribedSubredditData.add(new SubscribedSubredditData(id, title, LemmyUtils.actorID2FullName(actorId), iconUrl, accountName, false));
newSubredditData.add(new SubredditData(id, name, title, description, removed, published, updated, deleted, nsfw, actorId, local, iconUrl, bannerImageUrl, hidden, postingRestrictedToMods, instanceId, subscribers, isBlocked));
}
} catch (JSONException e) {

View File

@@ -0,0 +1,26 @@
package eu.toldi.infinityforlemmy;
import java.util.Set;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoSet;
import eu.toldi.infinityforlemmy.apis.RedgifsAPI;
import eu.toldi.infinityforlemmy.post.enrich.CompositePostEnricher;
import eu.toldi.infinityforlemmy.post.enrich.PostEnricher;
import eu.toldi.infinityforlemmy.post.enrich.RedGifsPostEnricher;
@Module
abstract class PostEnricherModule {
@Provides
@IntoSet
static PostEnricher provideRedGifsPostEnricher(RedgifsAPI redgifsAPI) {
return new RedGifsPostEnricher(redgifsAPI);
}
@Provides
static PostEnricher providePostEnricher(Set<PostEnricher> postEnrichers) {
return new CompositePostEnricher(postEnrichers);
}
}

View File

@@ -4,10 +4,12 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.work.Worker;
@@ -28,13 +30,11 @@ import javax.inject.Named;
import eu.toldi.infinityforlemmy.account.Account;
import eu.toldi.infinityforlemmy.activities.InboxActivity;
import eu.toldi.infinityforlemmy.activities.LinkResolverActivity;
import eu.toldi.infinityforlemmy.apis.RedditAPI;
import eu.toldi.infinityforlemmy.apis.LemmyAPI;
import eu.toldi.infinityforlemmy.comment.Comment;
import eu.toldi.infinityforlemmy.comment.ParseComment;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.message.FetchMessage;
import eu.toldi.infinityforlemmy.message.Message;
import eu.toldi.infinityforlemmy.message.ParseMessage;
import eu.toldi.infinityforlemmy.utils.APIUtils;
import eu.toldi.infinityforlemmy.utils.JSONUtils;
import eu.toldi.infinityforlemmy.message.CommentInteraction;
import eu.toldi.infinityforlemmy.utils.NotificationUtils;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import retrofit2.Call;
@@ -88,9 +88,16 @@ public class PullNotificationWorker extends Worker {
if (response != null && response.isSuccessful() && response.body() != null) {
String responseBody = response.body();
JSONArray messageArray = new JSONObject(responseBody).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY);
ArrayList<Message> messages = ParseMessage.parseMessages(messageArray,
context.getResources().getConfiguration().locale, FetchMessage.MESSAGE_TYPE_NOTIFICATION);
JSONArray messageArray = new JSONObject(responseBody).getJSONArray("replies");
List<CommentInteraction> messages = new ArrayList<>();
for (int i = 0; i < messageArray.length(); i++) {
JSONObject commentInteractionObject = messageArray.getJSONObject(i);
Comment comment = ParseComment.parseSingleComment(commentInteractionObject);
boolean isRead = !commentInteractionObject.getJSONObject("comment_reply").getBoolean("read");
int id = commentInteractionObject.getJSONObject("comment_reply").getInt("id");
messages.add(new CommentInteraction(id, comment, isRead));
}
if (!messages.isEmpty()) {
NotificationCompat.Builder summaryBuilder = NotificationUtils.buildSummaryNotification(context,
@@ -110,77 +117,36 @@ public class PullNotificationWorker extends Worker {
int pendingIntentFlags = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE : PendingIntent.FLAG_UPDATE_CURRENT;
for (int messageIndex = messageSize - 1; messageIndex >= 0; messageIndex--) {
Message message = messages.get(messageIndex);
if (message.getTimeUTC() <= lastNotificationTime) {
CommentInteraction message = messages.get(messageIndex);
if (message.getComment().getCommentTimeMillis() <= lastNotificationTime) {
continue;
}
hasValidMessage = true;
inboxStyle.addLine(message.getAuthor() + " " + message.getBody());
inboxStyle.addLine(message.getComment().getAuthorQualifiedName() + " " + message.getComment().getCommentMarkdown());
String title = message.getComment().getAuthorQualifiedName();
String summary = message.getComment().getCommunityQualifiedName();
String kind = message.getKind();
String title;
String summary;
if (kind.equals(Message.TYPE_COMMENT) || kind.equals(Message.TYPE_LINK)) {
title = message.getAuthor();
summary = message.getSubject().substring(0, 1).toUpperCase() + message.getSubject().substring(1);
} else {
title = message.getTitle() == null || message.getTitle().equals("") ? message.getSubject() : message.getTitle();
if (kind.equals(Message.TYPE_ACCOUNT)) {
summary = context.getString(R.string.notification_summary_account);
} else if (kind.equals(Message.TYPE_MESSAGE)) {
summary = context.getString(R.string.notification_summary_message);
} else if (kind.equals(Message.TYPE_SUBREDDIT)) {
summary = context.getString(R.string.notification_summary_community);
} else {
summary = context.getString(R.string.notification_summary_award);
}
}
NotificationCompat.Builder builder = NotificationUtils.buildNotification(notificationManager,
context, title, message.getBody(), summary,
context, title, message.getComment().getCommentMarkdown(), summary,
NotificationUtils.CHANNEL_ID_NEW_MESSAGES,
NotificationUtils.CHANNEL_NEW_MESSAGES,
NotificationUtils.getAccountGroupName(accountName), color);
if (kind.equals(Message.TYPE_COMMENT)) {
Intent intent = new Intent(context, LinkResolverActivity.class);
Uri uri = Uri.parse(message.getContext());
intent.setData(uri);
intent.putExtra(LinkResolverActivity.EXTRA_NEW_ACCOUNT_NAME, accountName);
intent.putExtra(LinkResolverActivity.EXTRA_MESSAGE_FULLNAME, message.getFullname());
PendingIntent pendingIntent = PendingIntent.getActivity(context, accountIndex * 6, intent, pendingIntentFlags);
builder.setContentIntent(pendingIntent);
} else if (kind.equals(Message.TYPE_ACCOUNT)) {
Intent intent = new Intent(context, InboxActivity.class);
intent.putExtra(InboxActivity.EXTRA_NEW_ACCOUNT_NAME, accountName);
PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, accountIndex * 6 + 1, intent, pendingIntentFlags);
builder.setContentIntent(summaryPendingIntent);
} else if (kind.equals(Message.TYPE_LINK)) {
Intent intent = new Intent(context, LinkResolverActivity.class);
Uri uri = Uri.parse(message.getContext());
intent.setData(uri);
intent.putExtra(LinkResolverActivity.EXTRA_NEW_ACCOUNT_NAME, accountName);
intent.putExtra(LinkResolverActivity.EXTRA_MESSAGE_FULLNAME, message.getFullname());
PendingIntent pendingIntent = PendingIntent.getActivity(context, accountIndex * 6 + 2, intent, pendingIntentFlags);
builder.setContentIntent(pendingIntent);
} else if (kind.equals(Message.TYPE_MESSAGE)) {
Intent intent = new Intent(context, InboxActivity.class);
intent.putExtra(InboxActivity.EXTRA_NEW_ACCOUNT_NAME, accountName);
intent.putExtra(InboxActivity.EXTRA_VIEW_MESSAGE, true);
PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, accountIndex * 6 + 3, intent, pendingIntentFlags);
builder.setContentIntent(summaryPendingIntent);
} else if (kind.equals(Message.TYPE_SUBREDDIT)) {
Intent intent = new Intent(context, InboxActivity.class);
intent.putExtra(InboxActivity.EXTRA_NEW_ACCOUNT_NAME, accountName);
PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, accountIndex * 6 + 4, intent, pendingIntentFlags);
builder.setContentIntent(summaryPendingIntent);
} else {
Intent intent = new Intent(context, InboxActivity.class);
intent.putExtra(InboxActivity.EXTRA_NEW_ACCOUNT_NAME, accountName);
PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, accountIndex * 6 + 5, intent, pendingIntentFlags);
builder.setContentIntent(summaryPendingIntent);
Intent intent = new Intent(context, LinkResolverActivity.class);
Uri uri = Uri.parse(message.getComment().getPermalink());
intent.setData(uri);
intent.putExtra(LinkResolverActivity.EXTRA_NEW_ACCOUNT_NAME, accountName);
intent.putExtra(LinkResolverActivity.EXTRA_MESSAGE_FULLNAME, message.getId());
PendingIntent pendingIntent = PendingIntent.getActivity(context, accountIndex * 6, intent, pendingIntentFlags);
builder.setContentIntent(pendingIntent);
if (ActivityCompat.checkSelfPermission(this.getApplicationContext(), android.Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
return Result.failure();
}
notificationManager.notify(NotificationUtils.getNotificationIdUnreadMessage(accountIndex, messageIndex), builder.build());
}
@@ -216,10 +182,7 @@ public class PullNotificationWorker extends Worker {
if (retryCount < 0) {
return null;
}
Call<String> call = mOauthWithoutAuthenticatorRetrofit.create(RedditAPI.class)
.getMessages(APIUtils.getOAuthHeader(account.getAccessToken()),
FetchMessage.WHERE_UNREAD, null);
Call<String> call = mRetrofit.getRetrofit().create(LemmyAPI.class).userReplies("New", 1, 25, true, account.getAccessToken());
Response<String> response = call.execute();
if (response.isSuccessful()) {

View File

@@ -13,6 +13,14 @@ import androidx.sqlite.db.SupportSQLiteDatabase;
import eu.toldi.infinityforlemmy.account.Account;
import eu.toldi.infinityforlemmy.account.AccountDao;
import eu.toldi.infinityforlemmy.blockedcommunity.BlockedCommunityDao;
import eu.toldi.infinityforlemmy.blockedcommunity.BlockedCommunityData;
import eu.toldi.infinityforlemmy.blockeduser.BlockedUserDao;
import eu.toldi.infinityforlemmy.blockeduser.BlockedUserData;
import eu.toldi.infinityforlemmy.commentfilter.CommentFilter;
import eu.toldi.infinityforlemmy.commentfilter.CommentFilterDao;
import eu.toldi.infinityforlemmy.commentfilter.CommentFilterUsage;
import eu.toldi.infinityforlemmy.commentfilter.CommentFilterUsageDao;
import eu.toldi.infinityforlemmy.customtheme.CustomTheme;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeDao;
import eu.toldi.infinityforlemmy.multireddit.AnonymousMultiredditSubreddit;
@@ -38,7 +46,8 @@ import eu.toldi.infinityforlemmy.user.UserData;
@Database(entities = {Account.class, SubredditData.class, SubscribedSubredditData.class, UserData.class,
SubscribedUserData.class, MultiReddit.class, CustomTheme.class, RecentSearchQuery.class,
ReadPost.class, PostFilter.class, PostFilterUsage.class, AnonymousMultiredditSubreddit.class}, version = 23)
ReadPost.class, PostFilter.class, PostFilterUsage.class, AnonymousMultiredditSubreddit.class,
BlockedUserData.class, BlockedCommunityData.class, CommentFilter.class, CommentFilterUsage.class}, version = 28)
public abstract class RedditDataRoomDatabase extends RoomDatabase {
public static RedditDataRoomDatabase create(final Context context) {
@@ -49,7 +58,7 @@ public abstract class RedditDataRoomDatabase extends RoomDatabase {
MIGRATION_9_10, MIGRATION_10_11, MIGRATION_11_12, MIGRATION_12_13,
MIGRATION_13_14, MIGRATION_14_15, MIGRATION_15_16, MIGRATION_16_17,
MIGRATION_17_18, MIGRATION_18_19, MIGRATION_19_20, MIGRATION_20_21,
MIGRATION_21_22, MIGRATION_22_23)
MIGRATION_21_22, MIGRATION_22_23, MIGRATION_23_24, MIGRATION_24_25, MIGRATION_25_26, MIGRATION_26_27, MIGRATION_27_28)
.build();
}
@@ -59,6 +68,10 @@ public abstract class RedditDataRoomDatabase extends RoomDatabase {
public abstract SubscribedSubredditDao subscribedSubredditDao();
public abstract BlockedUserDao blockedUserDao();
public abstract BlockedCommunityDao blockedCommunityDao();
public abstract UserDao userDao();
public abstract SubscribedUserDao subscribedUserDao();
@@ -77,6 +90,10 @@ public abstract class RedditDataRoomDatabase extends RoomDatabase {
public abstract AnonymousMultiredditSubredditDao anonymousMultiredditSubredditDao();
public abstract CommentFilterDao commentFilterDao();
public abstract CommentFilterUsageDao commentFilterUsageDao();
private static final Migration MIGRATION_1_2 = new Migration(1, 2) {
@Override
public void migrate(SupportSQLiteDatabase database) {
@@ -383,4 +400,49 @@ public abstract class RedditDataRoomDatabase extends RoomDatabase {
}
}
};
private static final Migration MIGRATION_23_24 = new Migration(23, 24) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE accounts ADD COLUMN can_downvote INTEGER DEFAULT 1 NOT NULL");
}
};
private static final Migration MIGRATION_24_25 = new Migration(24, 25) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE subreddits ADD COLUMN blocked INTEGER DEFAULT 1 NOT NULL");
}
};
private static final Migration MIGRATION_25_26 = new Migration(25, 26) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("CREATE TABLE blocked_users" +
"(name TEXT, id INTEGER NOT NULL, avatar TEXT, qualified_name TEXT, account_name TEXT NOT NULL, PRIMARY KEY( id, account_name))");
database.execSQL("CREATE TABLE blocked_communities" +
"(name TEXT, icon TEXT, id INTEGER NOT NULL, qualified_name TEXT, account_name TEXT NOT NULL, PRIMARY KEY( id, account_name))");
}
};
private static final Migration MIGRATION_26_27 = new Migration(26, 27) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE subscribed_subreddits"
+ " ADD COLUMN is_favorite INTEGER DEFAULT 0 NOT NULL");
}
};
private static final Migration MIGRATION_27_28 = new Migration(27, 28) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE custom_themes ADD COLUMN filled_card_view_background_color INTEGER DEFAULT " + Color.parseColor("#E6F4FF") + " NOT NULL");
database.execSQL("ALTER TABLE custom_themes ADD COLUMN read_post_filled_card_view_background_color INTEGER DEFAULT " + Color.parseColor("#F5F5F5") + " NOT NULL");
database.execSQL("CREATE TABLE comment_filter " +
"(name TEXT NOT NULL PRIMARY KEY, max_vote INTEGER NOT NULL, min_vote INTEGER NOT NULL, exclude_strings TEXT, exclude_users TEXT)");
database.execSQL("CREATE TABLE comment_filter_usage (name TEXT NOT NULL, usage INTEGER NOT NULL, " +
"name_of_usage TEXT NOT NULL, PRIMARY KEY(name, usage, name_of_usage), FOREIGN KEY(name) REFERENCES comment_filter(name) ON DELETE CASCADE)");
}
};
}

View File

@@ -14,7 +14,6 @@ import java.util.Map;
import eu.toldi.infinityforlemmy.apis.RedgifsAPI;
import eu.toldi.infinityforlemmy.utils.APIUtils;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.Response;
import retrofit2.Call;
@@ -22,6 +21,8 @@ import retrofit2.Retrofit;
import retrofit2.converter.scalars.ScalarsConverterFactory;
public class RedgifsAccessTokenAuthenticator implements Interceptor {
private static final String REDGIFS_HOST = "redgifs.com";
private SharedPreferences mCurrentAccountSharedPreferences;
public RedgifsAccessTokenAuthenticator(SharedPreferences currentAccountSharedPreferences) {
@@ -60,7 +61,17 @@ public class RedgifsAccessTokenAuthenticator implements Interceptor {
@NonNull
@Override
public Response intercept(@NonNull Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
if (!chain.request().url().host().endsWith(REDGIFS_HOST)) {
return chain.proceed(chain.request());
}
String currentAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.REDGIFS_ACCESS_TOKEN, "");
Response response = chain.proceed(
chain.request().newBuilder()
.addHeader(APIUtils.AUTHORIZATION_KEY, APIUtils.AUTHORIZATION_BASE + currentAccessToken)
.build()
);
if (response.code() == 401 || response.code() == 400) {
String accessTokenHeader = response.request().header(APIUtils.AUTHORIZATION_KEY);
if (accessTokenHeader == null) {
@@ -74,13 +85,21 @@ public class RedgifsAccessTokenAuthenticator implements Interceptor {
String newAccessToken = refreshAccessToken();
if (!newAccessToken.equals("")) {
response.close();
return chain.proceed(response.request().newBuilder().headers(Headers.of(APIUtils.getRedgifsOAuthHeader(newAccessToken))).build());
return chain.proceed(
chain.request().newBuilder()
.addHeader(APIUtils.AUTHORIZATION_KEY, APIUtils.AUTHORIZATION_BASE + newAccessToken)
.build()
);
} else {
return response;
}
} else {
response.close();
return chain.proceed(response.request().newBuilder().headers(Headers.of(APIUtils.getRedgifsOAuthHeader(accessTokenFromSharedPreferences))).build());
return chain.proceed(
chain.request().newBuilder()
.addHeader(APIUtils.AUTHORIZATION_KEY, APIUtils.AUTHORIZATION_BASE + accessTokenFromSharedPreferences)
.build()
);
}
}
}

View File

@@ -1,7 +1,10 @@
package eu.toldi.infinityforlemmy;
import android.util.Log;
import eu.toldi.infinityforlemmy.network.SortTypeConverterFactory;
import eu.toldi.infinityforlemmy.utils.APIUtils;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.guava.GuavaCallAdapterFactory;
@@ -12,8 +15,14 @@ public class RetrofitHolder {
private Retrofit retrofit;
private OkHttpClient okHttpClient;
private OkHttpClient okHttpClientBase;
private String baseURL = APIUtils.API_BASE_URI;
private String accessToken = null;
private Interceptor oAuthInterceptor;
public Retrofit getRetrofit() {
return retrofit;
}
@@ -24,11 +33,16 @@ public class RetrofitHolder {
}
public String getBaseURL() {
return baseURL;
String result = baseURL;
if (baseURL.endsWith("/")) {
result = baseURL.substring(0, baseURL.length() - 1);
}
return result;
}
public RetrofitHolder(OkHttpClient okHttpClient) {
this.okHttpClient = okHttpClient;
this.okHttpClientBase = okHttpClient;
this.retrofit = createRetrofit(okHttpClient, APIUtils.API_BASE_URI);
}
@@ -42,4 +56,18 @@ public class RetrofitHolder {
.addConverterFactory(GsonConverterFactory.create())
.build();
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
OkHttpClient.Builder builder = okHttpClientBase.newBuilder();
Log.d("RetrofitHolder", "Access token changed");
if (accessToken != null && !accessToken.equals("")) {
Log.i("RetrofitHolder", "Setting access token interceptor");
oAuthInterceptor = APIUtils.getOAuthInterceptor(accessToken);
builder.addInterceptor(oAuthInterceptor);
}
okHttpClient = builder.build();
retrofit = createRetrofit(okHttpClient, baseURL);
}
}

View File

@@ -43,12 +43,15 @@ public class SortType {
TOP_TWELVE_HOURS("TopTwelveHour", "Top"),
TOP_DAY("TopDay", "Top"),
TOP_WEEK("TopWeek", "Top"),
TOP_MONTH("month", "Top"),
TOP_MONTH("TopMonth", "Top"),
TOP_THREE_MONTHS("TopThreeMonths", "Top"),
TOP_SIX_MONTHS("TopSixMonths", "Top"),
TOP_NINE_MONTHS("TopNineMonths", "Top"),
TOP_YEAR("TopYear", "Top"),
TOP_ALL("TopAll", "Top");
TOP_ALL("TopAll", "Top"),
SCALED("Scaled", "Scaled"),
CONTROVERSIAL("Controversial", "Controversial");
public final String value;
public final String fullName;
@@ -69,15 +72,15 @@ public class SortType {
}
public enum Time {
HOUR("TopHour", "Top Hour"),
SIX_HOURS("TopSixHour", "Top Six Hours"),
TWELVE_HOURS("TopTwelveHour", "Top Twelve Hours"),
HOUR("hour", "Hour"),
SIX_HOURS("SixHour", "Six Hours"),
TWELVE_HOURS("TwelveHour", "Twelve Hours"),
DAY("day", "Day"),
WEEK("week", "Week"),
MONTH("month", "Month"),
THREE_MONTHS("TopThreeMonth", "Top Three Months"),
SIX_MONTHS("TopSixMonth", "Top Six Months"),
NINE_MONTHS("TopNineMonth", "Top Nine Months"),
THREE_MONTHS("ThreeMonths", "Three Months"),
SIX_MONTHS("SixMonths", "Six Months"),
NINE_MONTHS("NineMonths", "Nine Months"),
YEAR("year", "Year"),
ALL("all", "All Time");
@@ -88,5 +91,14 @@ public class SortType {
this.value = value;
this.fullName = fullName;
}
public static Time fromValue(String value) {
for (Time time : values()) {
if (time.value.equalsIgnoreCase(value)) {
return time;
}
}
return null;
}
}
}

View File

@@ -32,6 +32,9 @@ public class Account implements Parcelable {
@ColumnInfo(name = "instance_url")
private String instance_url;
@ColumnInfo(name = "can_downvote")
private boolean canDownvote = true;
@Ignore
protected Account(Parcel in) {
accountName = in.readString();
@@ -42,6 +45,7 @@ public class Account implements Parcelable {
code = in.readString();
isCurrentUser = in.readByte() != 0;
instance_url = in.readString();
canDownvote = in.readByte() != 0;
}
public static final Creator<Account> CREATOR = new Creator<Account>() {
@@ -58,11 +62,11 @@ public class Account implements Parcelable {
@Ignore
public static Account getAnonymousAccount() {
return new Account("-",null, null, null, null, null, false,null);
return new Account("-",null, null, null, null, null, false,null,true);
}
public Account(@NonNull String accountName, String display_name, String accessToken, String code,
String profileImageUrl, String bannerImageUrl, boolean isCurrentUser,String instance_url) {
String profileImageUrl, String bannerImageUrl, boolean isCurrentUser,String instance_url, boolean canDownvote) {
this.accountName = accountName;
this.display_name = display_name;
this.accessToken = accessToken;
@@ -71,6 +75,7 @@ public class Account implements Parcelable {
this.bannerImageUrl = bannerImageUrl;
this.isCurrentUser = isCurrentUser;
this.instance_url = instance_url;
this.canDownvote = canDownvote;
}
@NonNull
@@ -116,6 +121,10 @@ public class Account implements Parcelable {
return instance_url;
}
public boolean canDownvote() {
return canDownvote;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(accountName);
@@ -126,5 +135,6 @@ public class Account implements Parcelable {
dest.writeString(code);
dest.writeByte((byte) (isCurrentUser ? 1 : 0));
dest.writeString(instance_url);
dest.writeByte((byte) (canDownvote ? 1 : 0));
}
}

View File

@@ -0,0 +1,85 @@
package eu.toldi.infinityforlemmy.account;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import eu.toldi.infinityforlemmy.apis.LemmyAPI;
import eu.toldi.infinityforlemmy.blockedcommunity.BlockedCommunityData;
import eu.toldi.infinityforlemmy.blockeduser.BlockedUserData;
import eu.toldi.infinityforlemmy.subreddit.ParseSubredditData;
import eu.toldi.infinityforlemmy.subreddit.SubredditData;
import eu.toldi.infinityforlemmy.utils.LemmyUtils;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Retrofit;
public class FetchBlockedThings {
public static void fetchBlockedThings(Retrofit mRetrofit, String accessToken, String accountName, FetchBlockedThingsListener fetchBlockedThingsListener) {
LemmyAPI lemmyAPI = mRetrofit.create(LemmyAPI.class);
Call<String> call = lemmyAPI.getSiteInfo(accessToken);
call.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, retrofit2.Response<String> response) {
if (response.isSuccessful()) {
String siteInfo = response.body();
if (siteInfo != null) {
List<BlockedUserData> blockedUsers = new ArrayList<>();
List<BlockedCommunityData> blockedCommunities = new ArrayList<>();
try {
JSONObject siteInfoJson = new JSONObject(siteInfo).getJSONObject("my_user");
JSONArray blockedUsersJson = (siteInfoJson.has("person_blocks")) ? siteInfoJson.getJSONArray("person_blocks") : null;
JSONArray blockedCommunitiesJson = (siteInfoJson.has("community_blocks")) ? siteInfoJson.getJSONArray("community_blocks") : null;
if (blockedUsersJson != null) {
for (int i = 0; i < blockedUsersJson.length(); i++) {
JSONObject blockedUserJson = blockedUsersJson.getJSONObject(i).getJSONObject("target");
int id = blockedUserJson.getInt("id");
String name = blockedUserJson.getString("name");
String avatar = "";
if (blockedUserJson.has("avatar"))
avatar = blockedUserJson.getString("avatar");
String qualifiedName = LemmyUtils.actorID2FullName(blockedUserJson.getString("actor_id"));
BlockedUserData blockedUserData = new BlockedUserData(id, name, avatar, qualifiedName, accountName);
blockedUsers.add(blockedUserData);
}
}
if (blockedCommunitiesJson != null) {
for (int i = 0; i < blockedCommunitiesJson.length(); i++) {
JSONObject blockedCommunityJson = blockedCommunitiesJson.getJSONObject(i);
SubredditData blockedCommunityData = ParseSubredditData.parseSubredditData(blockedCommunityJson, true);
blockedCommunities.add(new BlockedCommunityData(blockedCommunityData, accountName));
}
}
fetchBlockedThingsListener.onFetchBlockedThingsSuccess(blockedUsers, blockedCommunities);
} catch (JSONException e) {
e.printStackTrace();
fetchBlockedThingsListener.onFetchBlockedThingsFailure();
}
} else {
fetchBlockedThingsListener.onFetchBlockedThingsFailure();
}
} else {
fetchBlockedThingsListener.onFetchBlockedThingsFailure();
}
}
@Override
public void onFailure(Call<String> call, Throwable t) {
fetchBlockedThingsListener.onFetchBlockedThingsFailure();
}
});
}
public interface FetchBlockedThingsListener {
void onFetchBlockedThingsSuccess(List<BlockedUserData> blockedUsers, List<BlockedCommunityData> blockedCommunities);
void onFetchBlockedThingsFailure();
}
}

View File

@@ -8,6 +8,7 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -40,6 +41,7 @@ import eu.toldi.infinityforlemmy.events.ChangeNSFWEvent;
import eu.toldi.infinityforlemmy.events.SwitchAccountEvent;
import eu.toldi.infinityforlemmy.fragments.CommentsListingFragment;
import eu.toldi.infinityforlemmy.fragments.PostFragment;
import eu.toldi.infinityforlemmy.post.MarkPostAsRead;
import eu.toldi.infinityforlemmy.post.Post;
import eu.toldi.infinityforlemmy.post.PostPagingSource;
import eu.toldi.infinityforlemmy.readpost.InsertReadPost;
@@ -64,10 +66,15 @@ public class AccountSavedThingActivity extends BaseActivity implements ActivityT
CustomThemeWrapper mCustomThemeWrapper;
@Inject
Executor mExecutor;
@Inject
MarkPostAsRead markPostAsRead;
private FragmentManager fragmentManager;
private SectionsPagerAdapter sectionsPagerAdapter;
private String mAccessToken;
private String mAccountName;
private String mAccountQualifiedName;
private PostLayoutBottomSheetFragment postLayoutBottomSheetFragment;
private ActivityAccountSavedThingBinding binding;
@@ -116,6 +123,7 @@ public class AccountSavedThingActivity extends BaseActivity implements ActivityT
mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null);
mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null);
mAccountQualifiedName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, null);
initializeViewPager();
}
@@ -249,7 +257,17 @@ public class AccountSavedThingActivity extends BaseActivity implements ActivityT
@Override
public void markPostAsRead(Post post) {
InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, mAccountName, post.getId());
markPostAsRead.markPostAsRead(post.getId(), mAccessToken, new MarkPostAsRead.MarkPostAsReadListener() {
@Override
public void onMarkPostAsReadSuccess() {
InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, mAccountQualifiedName, post.getId());
}
@Override
public void onMarkPostAsReadFailed() {
Toast.makeText(AccountSavedThingActivity.this, R.string.mark_post_as_read_failed, Toast.LENGTH_SHORT).show();
}
});
}
private class SectionsPagerAdapter extends FragmentStateAdapter {
@@ -265,7 +283,7 @@ public class AccountSavedThingActivity extends BaseActivity implements ActivityT
PostFragment fragment = new PostFragment();
Bundle bundle = new Bundle();
bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostPagingSource.TYPE_USER);
bundle.putString(PostFragment.EXTRA_USER_NAME, mAccountName);
bundle.putString(PostFragment.EXTRA_USER_NAME, mAccountQualifiedName);
bundle.putString(PostFragment.EXTRA_USER_WHERE, PostPagingSource.USER_WHERE_SAVED);
bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken);
bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName);
@@ -275,7 +293,7 @@ public class AccountSavedThingActivity extends BaseActivity implements ActivityT
}
CommentsListingFragment fragment = new CommentsListingFragment();
Bundle bundle = new Bundle();
bundle.putString(CommentsListingFragment.EXTRA_USERNAME, mAccountName);
bundle.putString(CommentsListingFragment.EXTRA_USERNAME, mAccountQualifiedName);
bundle.putString(CommentsListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken);
bundle.putString(CommentsListingFragment.EXTRA_ACCOUNT_NAME, mAccountName);
bundle.putBoolean(CommentsListingFragment.EXTRA_ARE_SAVED_COMMENTS, true);

View File

@@ -39,6 +39,9 @@ import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.shape.CornerFamily;
import com.google.android.material.shape.MaterialShapeDrawable;
import com.google.android.material.shape.ShapeAppearanceModel;
import com.google.android.material.tabs.TabLayout;
import java.lang.reflect.Field;
@@ -377,9 +380,18 @@ public abstract class BaseActivity extends AppCompatActivity implements CustomFo
button.setTextColor(customThemeWrapper.getFABIconColor());
}
protected void applyFABTheme(FloatingActionButton fab) {
protected void applyFABTheme(FloatingActionButton fab, boolean isCircular) {
fab.setBackgroundTintList(ColorStateList.valueOf(customThemeWrapper.getColorAccent()));
fab.setImageTintList(ColorStateList.valueOf(customThemeWrapper.getFABIconColor()));
if (isCircular) {
ShapeAppearanceModel shapeAppearanceModel = ShapeAppearanceModel.builder()
.setAllCorners(CornerFamily.ROUNDED, 100) // Adjust the radius value to control the roundness
.build();
// Apply the circular shape to the FAB
MaterialShapeDrawable shapeDrawable = new MaterialShapeDrawable(shapeAppearanceModel);
fab.setShapeAppearanceModel(shapeAppearanceModel);
}
}
protected void fixViewPager2Sensitivity(ViewPager2 viewPager2) {

View File

@@ -0,0 +1,462 @@
package eu.toldi.infinityforlemmy.activities;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.core.view.inputmethod.EditorInfoCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.tabs.TabLayout;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import java.util.List;
import java.util.concurrent.Executor;
import javax.inject.Inject;
import javax.inject.Named;
import butterknife.BindView;
import butterknife.ButterKnife;
import eu.toldi.infinityforlemmy.ActivityToolbarInterface;
import eu.toldi.infinityforlemmy.FragmentCommunicator;
import eu.toldi.infinityforlemmy.Infinity;
import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.RedditDataRoomDatabase;
import eu.toldi.infinityforlemmy.RetrofitHolder;
import eu.toldi.infinityforlemmy.account.FetchBlockedThings;
import eu.toldi.infinityforlemmy.asynctasks.InsertBlockedThings;
import eu.toldi.infinityforlemmy.blockedcommunity.BlockedCommunityData;
import eu.toldi.infinityforlemmy.blockeduser.BlockedUserData;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.customviews.ViewPagerBugFixed;
import eu.toldi.infinityforlemmy.customviews.slidr.Slidr;
import eu.toldi.infinityforlemmy.events.GoBackToMainPageEvent;
import eu.toldi.infinityforlemmy.events.SwitchAccountEvent;
import eu.toldi.infinityforlemmy.fragments.BlockedCommunitiesListingFragment;
import eu.toldi.infinityforlemmy.fragments.BlockedUsersListingFragment;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import eu.toldi.infinityforlemmy.utils.Utils;
import retrofit2.Retrofit;
public class BlockedThingListingActivity extends BaseActivity implements ActivityToolbarInterface {
public static final String EXTRA_SHOW_MULTIREDDITS = "ESM";
private static final String INSERT_SUBSCRIBED_SUBREDDIT_STATE = "ISSS";
private static final String INSERT_MULTIREDDIT_STATE = "IMS";
@BindView(R.id.coordinator_layout_subscribed_thing_listing_activity)
CoordinatorLayout coordinatorLayout;
@BindView(R.id.appbar_layout_subscribed_thing_listing_activity)
AppBarLayout appBarLayout;
@BindView(R.id.collapsing_toolbar_layout_subscribed_thing_listing_activity)
CollapsingToolbarLayout collapsingToolbarLayout;
@BindView(R.id.toolbar_subscribed_thing_listing_activity)
Toolbar toolbar;
@BindView(R.id.search_edit_text_subscribed_thing_listing_activity)
EditText searchEditText;
@BindView(R.id.tab_layout_subscribed_thing_listing_activity)
TabLayout tabLayout;
@BindView(R.id.view_pager_subscribed_thing_listing_activity)
ViewPagerBugFixed viewPager;
@BindView(R.id.fab_subscribed_thing_listing_activity)
FloatingActionButton fab;
@Inject
@Named("oauth")
Retrofit mOauthRetrofit;
@Inject
@Named("no_oauth")
RetrofitHolder mRetrofit;
@Inject
RedditDataRoomDatabase mRedditDataRoomDatabase;
@Inject
@Named("default")
SharedPreferences mSharedPreferences;
@Inject
@Named("current_account")
SharedPreferences mCurrentAccountSharedPreferences;
@Inject
CustomThemeWrapper mCustomThemeWrapper;
@Inject
Executor mExecutor;
private String mAccessToken;
private String mAccountName;
private String mAccountQualifiedName;
private boolean mInsertSuccess = false;
private boolean mInsertMultiredditSuccess = false;
private boolean showMultiReddits = false;
private SectionsPagerAdapter sectionsPagerAdapter;
private Menu mMenu;
@Override
protected void onCreate(Bundle savedInstanceState) {
((Infinity) getApplication()).getAppComponent().inject(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_subscribed_thing_listing);
ButterKnife.bind(this);
EventBus.getDefault().register(this);
applyCustomTheme();
if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) {
mSliderPanel = Slidr.attach(this);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Window window = getWindow();
if (isChangeStatusBarIconColor()) {
addOnOffsetChangedListener(appBarLayout);
}
if (isImmersiveInterface()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
window.setDecorFitsSystemWindows(false);
} else {
window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
adjustToolbar(toolbar);
int navBarHeight = getNavBarHeight();
if (navBarHeight > 0) {
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
params.bottomMargin += navBarHeight;
fab.setLayoutParams(params);
}
}
}
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
setToolbarGoToTop(toolbar);
mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null);
mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, "-");
mAccountQualifiedName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, "-");
if (savedInstanceState != null) {
mInsertSuccess = savedInstanceState.getBoolean(INSERT_SUBSCRIBED_SUBREDDIT_STATE);
mInsertMultiredditSuccess = savedInstanceState.getBoolean(INSERT_MULTIREDDIT_STATE);
} else {
showMultiReddits = getIntent().getBooleanExtra(EXTRA_SHOW_MULTIREDDITS, false);
}
if (mAccessToken == null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
searchEditText.setImeOptions(searchEditText.getImeOptions() | EditorInfoCompat.IME_FLAG_NO_PERSONALIZED_LEARNING);
}
searchEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
sectionsPagerAdapter.changeSearchQuery(editable.toString());
}
});
initializeViewPagerAndLoadSubscriptions();
}
@Override
public SharedPreferences getDefaultSharedPreferences() {
return mSharedPreferences;
}
@Override
protected CustomThemeWrapper getCustomThemeWrapper() {
return mCustomThemeWrapper;
}
@Override
protected void applyCustomTheme() {
coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor());
applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, collapsingToolbarLayout, toolbar);
applyTabLayoutTheme(tabLayout);
applyFABTheme(fab, mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false));
searchEditText.setTextColor(mCustomThemeWrapper.getToolbarPrimaryTextAndIconColor());
searchEditText.setHintTextColor(mCustomThemeWrapper.getToolbarSecondaryTextColor());
}
private void initializeViewPagerAndLoadSubscriptions() {
fab.setOnClickListener(view -> {
Intent intent = new Intent(this, CreateMultiRedditActivity.class);
startActivity(intent);
});
sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(sectionsPagerAdapter);
viewPager.setOffscreenPageLimit(2);
if (viewPager.getCurrentItem() != 2) {
fab.hide();
}
viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
if (position == 0) {
unlockSwipeRightToGoBack();
fab.hide();
} else {
lockSwipeRightToGoBack();
if (position != 2) {
fab.hide();
} else {
fab.show();
}
}
}
});
tabLayout.setupWithViewPager(viewPager);
if (showMultiReddits) {
viewPager.setCurrentItem(2, false);
}
loadBlocks(false);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.subscribed_thing_listing_activity, menu);
mMenu = menu;
applyMenuItemTheme(menu);
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == R.id.action_search_subscribed_thing_listing_activity) {
item.setVisible(false);
searchEditText.setVisibility(View.VISIBLE);
searchEditText.requestFocus();
if (searchEditText.requestFocus()) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(searchEditText, InputMethodManager.SHOW_IMPLICIT);
}
return true;
} else if (item.getItemId() == android.R.id.home) {
if (searchEditText.getVisibility() == View.VISIBLE) {
Utils.hideKeyboard(this);
searchEditText.setVisibility(View.GONE);
searchEditText.setText("");
mMenu.findItem(R.id.action_search_subscribed_thing_listing_activity).setVisible(true);
sectionsPagerAdapter.changeSearchQuery("");
return true;
}
finish();
return true;
}
return false;
}
@Override
public void onBackPressed() {
if (searchEditText.getVisibility() == View.VISIBLE) {
Utils.hideKeyboard(this);
searchEditText.setVisibility(View.GONE);
searchEditText.setText("");
mMenu.findItem(R.id.action_search_subscribed_thing_listing_activity).setVisible(true);
sectionsPagerAdapter.changeSearchQuery("");
} else {
super.onBackPressed();
}
}
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(INSERT_SUBSCRIBED_SUBREDDIT_STATE, mInsertSuccess);
outState.putBoolean(INSERT_MULTIREDDIT_STATE, mInsertMultiredditSuccess);
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
public void loadBlocks(boolean forceLoad) {
if (mAccessToken != null && !(!forceLoad && mInsertSuccess)) {
FetchBlockedThings.fetchBlockedThings(mRetrofit.getRetrofit(), mAccessToken, mAccountQualifiedName, new FetchBlockedThings.FetchBlockedThingsListener() {
@Override
public void onFetchBlockedThingsSuccess(List<BlockedUserData> blockedUsers, List<BlockedCommunityData> blockedCommunities) {
InsertBlockedThings.insertBlockedThings(mExecutor, new Handler(), mRedditDataRoomDatabase, mAccountQualifiedName,
blockedCommunities, blockedUsers, () -> {
mInsertSuccess = true;
sectionsPagerAdapter.stopRefreshProgressbar();
});
}
@Override
public void onFetchBlockedThingsFailure() {
}
});
}
}
@Subscribe
public void onAccountSwitchEvent(SwitchAccountEvent event) {
finish();
}
@Subscribe
public void goBackToMainPageEvent(GoBackToMainPageEvent event) {
finish();
}
@Override
public void onLongPress() {
if (sectionsPagerAdapter != null) {
sectionsPagerAdapter.goBackToTop();
}
}
@Override
public void lockSwipeRightToGoBack() {
if (mSliderPanel != null) {
mSliderPanel.lock();
}
}
@Override
public void unlockSwipeRightToGoBack() {
if (mSliderPanel != null) {
mSliderPanel.unlock();
}
}
private class SectionsPagerAdapter extends FragmentPagerAdapter {
private BlockedCommunitiesListingFragment blockedCommunitiesListingFragment;
private BlockedUsersListingFragment followedUsersListingFragment;
public SectionsPagerAdapter(FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
@NonNull
@Override
public Fragment getItem(int position) {
switch (position) {
default:
case 0: {
BlockedCommunitiesListingFragment fragment = new BlockedCommunitiesListingFragment();
Bundle bundle = new Bundle();
bundle.putBoolean(BlockedCommunitiesListingFragment.EXTRA_IS_SUBREDDIT_SELECTION, false);
bundle.putString(BlockedCommunitiesListingFragment.EXTRA_ACCOUNT_NAME, mAccountName);
bundle.putString(BlockedCommunitiesListingFragment.EXTRA_ACCOUNT_QUALIFIED_NAME, mAccountQualifiedName);
bundle.putString(BlockedCommunitiesListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken);
fragment.setArguments(bundle);
return fragment;
}
case 1: {
BlockedUsersListingFragment fragment = new BlockedUsersListingFragment();
Bundle bundle = new Bundle();
bundle.putString(BlockedUsersListingFragment.EXTRA_ACCOUNT_NAME, mAccountQualifiedName);
bundle.putString(BlockedUsersListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken);
fragment.setArguments(bundle);
return fragment;
}
}
}
@Override
public int getCount() {
return 2;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return Utils.getTabTextWithCustomFont(typeface, getString(R.string.communities));
case 1:
return Utils.getTabTextWithCustomFont(typeface, getString(R.string.users));
case 2:
return Utils.getTabTextWithCustomFont(typeface, getString(R.string.multi_reddits));
}
return null;
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
if (position == 0) {
blockedCommunitiesListingFragment = (BlockedCommunitiesListingFragment) fragment;
} else if (position == 1) {
followedUsersListingFragment = (BlockedUsersListingFragment) fragment;
}
return fragment;
}
void stopRefreshProgressbar() {
if (blockedCommunitiesListingFragment != null) {
((FragmentCommunicator) blockedCommunitiesListingFragment).stopRefreshProgressbar();
}
if (followedUsersListingFragment != null) {
((FragmentCommunicator) followedUsersListingFragment).stopRefreshProgressbar();
}
}
void goBackToTop() {
if (viewPager.getCurrentItem() == 0) {
blockedCommunitiesListingFragment.goBackToTop();
} else if (viewPager.getCurrentItem() == 1) {
followedUsersListingFragment.goBackToTop();
}
}
void changeSearchQuery(String searchQuery) {
if (blockedCommunitiesListingFragment != null) {
blockedCommunitiesListingFragment.changeSearchQuery(searchQuery);
}
if (followedUsersListingFragment != null) {
followedUsersListingFragment.changeSearchQuery(searchQuery);
}
}
}
}

View File

@@ -205,7 +205,7 @@ public class CommentActivity extends BaseActivity implements UploadImageEnabledA
}
};
Markwon postBodyMarkwon = MarkdownUtils.createFullRedditMarkwon(this,
miscPlugin, parentTextColor, parentSpoilerBackgroundColor, null);
miscPlugin, parentTextColor, parentSpoilerBackgroundColor, null, mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_IMAGE_PREVIEW, false));
MarkwonAdapter markwonAdapter = MarkdownUtils.createTablesAdapter();
binding.commentContentMarkdownView.setLayoutManager(new LinearLayoutManagerBugFixed(this));
binding.commentContentMarkdownView.setAdapter(markwonAdapter);
@@ -226,7 +226,7 @@ public class CommentActivity extends BaseActivity implements UploadImageEnabledA
setSupportActionBar(binding.commentToolbar);
mGlide = Glide.with(this);
mGlide = Glide.with(getApplication());
if (savedInstanceState != null) {
selectedAccount = savedInstanceState.getParcelable(SELECTED_ACCOUNT_STATE);
@@ -513,8 +513,8 @@ public class CommentActivity extends BaseActivity implements UploadImageEnabledA
int start = Math.max(binding.commentCommentEditText.getSelectionStart(), 0);
int end = Math.max(binding.commentCommentEditText.getSelectionEnd(), 0);
binding.commentCommentEditText.getText().replace(Math.min(start, end), Math.max(start, end),
"[" + uploadedImage.imageName + "](" + uploadedImage.imageUrl + ")",
0, "[]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length());
"![" + uploadedImage.imageName + "](" + uploadedImage.imageUrl + ")",
0, "![]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length());
}
@Override

View File

@@ -0,0 +1,126 @@
package eu.toldi.infinityforlemmy.activities;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.MenuItem;
import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModelProvider;
import java.util.concurrent.Executor;
import javax.inject.Inject;
import javax.inject.Named;
import butterknife.ButterKnife;
import eu.toldi.infinityforlemmy.Infinity;
import eu.toldi.infinityforlemmy.RedditDataRoomDatabase;
import eu.toldi.infinityforlemmy.adapters.CommentFilterWithUsageRecyclerViewAdapter;
import eu.toldi.infinityforlemmy.bottomsheetfragments.CommentFilterOptionsBottomSheetFragment;
import eu.toldi.infinityforlemmy.commentfilter.CommentFilter;
import eu.toldi.infinityforlemmy.commentfilter.DeleteCommentFilter;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.databinding.ActivityCommentFilterPreferenceBinding;
import eu.toldi.infinityforlemmy.commentfilter.CommentFilterWithUsageViewModel;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
public class CommentFilterPreferenceActivity extends BaseActivity {
private ActivityCommentFilterPreferenceBinding binding;
@Inject
@Named("default")
SharedPreferences sharedPreferences;
@Inject
RedditDataRoomDatabase redditDataRoomDatabase;
@Inject
CustomThemeWrapper customThemeWrapper;
@Inject
Executor executor;
public CommentFilterWithUsageViewModel commentFilterWithUsageViewModel;
private CommentFilterWithUsageRecyclerViewAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
((Infinity) getApplication()).getAppComponent().inject(this);
setImmersiveModeNotApplicable();
super.onCreate(savedInstanceState);
binding = ActivityCommentFilterPreferenceBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
ButterKnife.bind(this);
applyCustomTheme();
setSupportActionBar(binding.toolbarCommentFilterPreferenceActivity);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
binding.fabCommentFilterPreferenceActivity.setOnClickListener(view -> {
Intent intent = new Intent(this, CustomizeCommentFilterActivity.class);
intent.putExtra(CustomizeCommentFilterActivity.EXTRA_FROM_SETTINGS, true);
startActivity(intent);
});
adapter = new CommentFilterWithUsageRecyclerViewAdapter(this, commentFilter -> {
CommentFilterOptionsBottomSheetFragment commentFilterOptionsBottomSheetFragment = new CommentFilterOptionsBottomSheetFragment();
Bundle bundle = new Bundle();
bundle.putParcelable(CommentFilterOptionsBottomSheetFragment.EXTRA_POST_FILTER, commentFilter);
commentFilterOptionsBottomSheetFragment.setArguments(bundle);
commentFilterOptionsBottomSheetFragment.show(getSupportFragmentManager(), commentFilterOptionsBottomSheetFragment.getTag());
});
binding.recyclerViewCommentFilterPreferenceActivity.setAdapter(adapter);
commentFilterWithUsageViewModel = new ViewModelProvider(this,
new CommentFilterWithUsageViewModel.Factory(redditDataRoomDatabase)).get(CommentFilterWithUsageViewModel.class);
commentFilterWithUsageViewModel.getCommentFilterWithUsageListLiveData().observe(this, commentFilterWithUsages -> adapter.setCommentFilterWithUsageList(commentFilterWithUsages));
}
public void editCommentFilter(CommentFilter commentFilter) {
Intent intent = new Intent(this, CustomizeCommentFilterActivity.class);
intent.putExtra(CustomizeCommentFilterActivity.EXTRA_COMMENT_FILTER, commentFilter);
intent.putExtra(CustomizeCommentFilterActivity.EXTRA_FROM_SETTINGS, true);
startActivity(intent);
}
public void applyCommentFilterTo(CommentFilter commentFilter) {
Intent intent = new Intent(this, CommentFilterUsageListingActivity.class);
intent.putExtra(CommentFilterUsageListingActivity.EXTRA_COMMENT_FILTER, commentFilter);
startActivity(intent);
}
public void deleteCommentFilter(CommentFilter commentFilter) {
DeleteCommentFilter.deleteCommentFilter(redditDataRoomDatabase, executor, commentFilter);
}
@Override
protected SharedPreferences getDefaultSharedPreferences() {
return sharedPreferences;
}
@Override
protected CustomThemeWrapper getCustomThemeWrapper() {
return customThemeWrapper;
}
@Override
protected void applyCustomTheme() {
applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(binding.appbarLayoutCommentFilterPreferenceActivity, binding.collapsingToolbarLayoutCommentFilterPreferenceActivity, binding.toolbarCommentFilterPreferenceActivity);
applyFABTheme(binding.fabCommentFilterPreferenceActivity, sharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false));
binding.getRoot().setBackgroundColor(customThemeWrapper.getBackgroundColor());
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
return true;
}
return false;
}
}

View File

@@ -0,0 +1,181 @@
package eu.toldi.infinityforlemmy.activities;
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.res.ColorStateList;
import android.os.Bundle;
import android.os.Handler;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModelProvider;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textfield.TextInputLayout;
import java.util.concurrent.Executor;
import javax.inject.Inject;
import javax.inject.Named;
import eu.toldi.infinityforlemmy.Infinity;
import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.RedditDataRoomDatabase;
import eu.toldi.infinityforlemmy.bottomsheetfragments.CommentFilterUsageOptionsBottomSheetFragment;
import eu.toldi.infinityforlemmy.bottomsheetfragments.NewCommentFilterUsageBottomSheetFragment;
import eu.toldi.infinityforlemmy.commentfilter.CommentFilter;
import eu.toldi.infinityforlemmy.commentfilter.CommentFilterUsage;
import eu.toldi.infinityforlemmy.commentfilter.CommentFilterUsageViewModel;
import eu.toldi.infinityforlemmy.commentfilter.DeleteCommentFilterUsage;
import eu.toldi.infinityforlemmy.commentfilter.SaveCommentFilterUsage;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.databinding.ActivityCommentFilterUsageListingBinding;
import eu.toldi.infinityforlemmy.adapters.CommentFilterUsageRecyclerViewAdapter;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import eu.toldi.infinityforlemmy.utils.Utils;
public class CommentFilterUsageListingActivity extends BaseActivity {
public static final String EXTRA_COMMENT_FILTER = "ECF";
@Inject
@Named("default")
SharedPreferences sharedPreferences;
@Inject
RedditDataRoomDatabase redditDataRoomDatabase;
@Inject
CustomThemeWrapper customThemeWrapper;
@Inject
Executor executor;
private ActivityCommentFilterUsageListingBinding binding;
public CommentFilterUsageViewModel commentFilterUsageViewModel;
private CommentFilterUsageRecyclerViewAdapter adapter;
private CommentFilter commentFilter;
@Override
protected void onCreate(Bundle savedInstanceState) {
((Infinity) getApplication()).getAppComponent().inject(this);
setImmersiveModeNotApplicable();
super.onCreate(savedInstanceState);
binding = ActivityCommentFilterUsageListingBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
applyCustomTheme();
setSupportActionBar(binding.toolbarCommentFilterUsageListingActivity);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
commentFilter = getIntent().getParcelableExtra(EXTRA_COMMENT_FILTER);
setTitle(commentFilter.name);
binding.fabCommentFilterUsageListingActivity.setOnClickListener(view -> {
NewCommentFilterUsageBottomSheetFragment newCommentFilterUsageBottomSheetFragment = new NewCommentFilterUsageBottomSheetFragment();
newCommentFilterUsageBottomSheetFragment.show(getSupportFragmentManager(), newCommentFilterUsageBottomSheetFragment.getTag());
});
adapter = new CommentFilterUsageRecyclerViewAdapter(this, customThemeWrapper, commentFilterUsage -> {
CommentFilterUsageOptionsBottomSheetFragment commentFilterUsageOptionsBottomSheetFragment = new CommentFilterUsageOptionsBottomSheetFragment();
Bundle bundle = new Bundle();
bundle.putParcelable(CommentFilterUsageOptionsBottomSheetFragment.EXTRA_COMMENT_FILTER_USAGE, commentFilterUsage);
commentFilterUsageOptionsBottomSheetFragment.setArguments(bundle);
commentFilterUsageOptionsBottomSheetFragment.show(getSupportFragmentManager(), commentFilterUsageOptionsBottomSheetFragment.getTag());
});
binding.recyclerViewCommentFilterUsageListingActivity.setAdapter(adapter);
commentFilterUsageViewModel = new ViewModelProvider(this,
new CommentFilterUsageViewModel.Factory(redditDataRoomDatabase, commentFilter.name)).get(CommentFilterUsageViewModel.class);
commentFilterUsageViewModel.getCommentFilterUsageListLiveData().observe(this, commentFilterUsages -> adapter.setCommentFilterUsages(commentFilterUsages));
}
public void newCommentFilterUsage(int type) {
switch (type) {
case CommentFilterUsage.SUBREDDIT_TYPE:
editAndCommentFilterUsageNameOfUsage(type, null);
break;
}
}
private void editAndCommentFilterUsageNameOfUsage(int type, String nameOfUsage) {
View dialogView = getLayoutInflater().inflate(R.layout.dialog_edit_post_or_comment_filter_name_of_usage, null);
TextView messageTextView = dialogView.findViewById(R.id.message_text_view_edit_post_or_comment_filter_name_of_usage_dialog);
messageTextView.setVisibility(View.GONE);
TextInputLayout textInputLayout = dialogView.findViewById(R.id.text_input_layout_edit_post_or_comment_filter_name_of_usage_dialog);
TextInputEditText textInputEditText = dialogView.findViewById(R.id.text_input_edit_text_edit_post_or_comment_filter_name_of_usage_dialog);
int primaryTextColor = customThemeWrapper.getPrimaryTextColor();
textInputLayout.setBoxStrokeColor(primaryTextColor);
textInputLayout.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor));
textInputEditText.setTextColor(primaryTextColor);
if (nameOfUsage != null) {
textInputEditText.setText(nameOfUsage);
}
textInputEditText.requestFocus();
int titleStringId = R.string.community;
switch (type) {
case CommentFilterUsage.SUBREDDIT_TYPE:
textInputEditText.setHint(R.string.settings_tab_community_name);
break;
}
Utils.showKeyboard(this, new Handler(), textInputEditText);
new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme)
.setTitle(titleStringId)
.setView(dialogView)
.setPositiveButton(R.string.ok, (editTextDialogInterface, i1)
-> {
Utils.hideKeyboard(this);
CommentFilterUsage commentFilterUsage;
if (!textInputEditText.getText().toString().equals("")) {
commentFilterUsage = new CommentFilterUsage(commentFilter.name, type, textInputEditText.getText().toString());
SaveCommentFilterUsage.saveCommentFilterUsage(redditDataRoomDatabase, executor, commentFilterUsage);
}
})
.setNegativeButton(R.string.cancel, null)
.setOnDismissListener(editTextDialogInterface -> {
Utils.hideKeyboard(this);
})
.show();
}
public void editCommentFilterUsage(CommentFilterUsage commentFilterUsage) {
editAndCommentFilterUsageNameOfUsage(commentFilterUsage.usage, commentFilterUsage.nameOfUsage);
}
public void deleteCommentFilterUsage(CommentFilterUsage commentFilterUsage) {
DeleteCommentFilterUsage.deleteCommentFilterUsage(redditDataRoomDatabase, executor, commentFilterUsage);
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
return true;
}
return false;
}
@Override
protected SharedPreferences getDefaultSharedPreferences() {
return sharedPreferences;
}
@Override
protected CustomThemeWrapper getCustomThemeWrapper() {
return customThemeWrapper;
}
@Override
protected void applyCustomTheme() {
applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(binding.appbarLayoutCommentFilterUsageListingActivity, binding.collapsingToolbarLayoutCommentFilterUsageListingActivity, binding.toolbarCommentFilterUsageListingActivity);
applyFABTheme(binding.fabCommentFilterUsageListingActivity, sharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false));
binding.getRoot().setBackgroundColor(customThemeWrapper.getBackgroundColor());
}
}

View File

@@ -51,6 +51,7 @@ import eu.toldi.infinityforlemmy.customtheme.CustomThemeViewModel;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.events.RecreateActivityEvent;
import eu.toldi.infinityforlemmy.utils.CustomThemeSharedPreferencesUtils;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import eu.toldi.infinityforlemmy.utils.Utils;
public class CustomThemeListingActivity extends BaseActivity implements
@@ -154,7 +155,7 @@ public class CustomThemeListingActivity extends BaseActivity implements
@Override
protected void applyCustomTheme() {
applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, collapsingToolbarLayout, toolbar);
applyFABTheme(fab);
applyFABTheme(fab, sharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false));
}
@Override

View File

@@ -0,0 +1,302 @@
package eu.toldi.infinityforlemmy.activities;
import android.app.Activity;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.concurrent.Executor;
import java.util.regex.PatternSyntaxException;
import javax.inject.Inject;
import javax.inject.Named;
import eu.toldi.infinityforlemmy.Infinity;
import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.RedditDataRoomDatabase;
import eu.toldi.infinityforlemmy.commentfilter.CommentFilter;
import eu.toldi.infinityforlemmy.commentfilter.SaveCommentFilter;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.databinding.ActivityCustomizeCommentFilterBinding;
import eu.toldi.infinityforlemmy.utils.Utils;
public class CustomizeCommentFilterActivity extends BaseActivity {
public static final String EXTRA_COMMENT_FILTER = "ECF";
public static final String EXTRA_FROM_SETTINGS = "EFS";
public static final String RETURN_EXTRA_COMMENT_FILTER = "RECF";
private static final String COMMENT_FILTER_STATE = "CFS";
private static final String ORIGINAL_NAME_STATE = "ONS";
@Inject
RedditDataRoomDatabase mRedditDataRoomDatabase;
@Inject
@Named("default")
SharedPreferences mSharedPreferences;
@Inject
@Named("current_account")
SharedPreferences currentAccountSharedPreferences;
@Inject
CustomThemeWrapper mCustomThemeWrapper;
@Inject
Executor mExecutor;
private CommentFilter commentFilter;
private boolean fromSettings;
private String originalName;
private ActivityCustomizeCommentFilterBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
((Infinity) getApplication()).getAppComponent().inject(this);
setImmersiveModeNotApplicable();
super.onCreate(savedInstanceState);
binding = ActivityCustomizeCommentFilterBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
applyCustomTheme();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) {
addOnOffsetChangedListener(binding.appbarLayoutCustomizeCommentFilterActivity);
}
setSupportActionBar(binding.toolbarCustomizeCommentFilterActivity);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
setToolbarGoToTop(binding.toolbarCustomizeCommentFilterActivity);
ActivityResultLauncher<Intent> requestAddUsersLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
Intent data = result.getData();
if (data == null) {
return;
}
ArrayList<String> usernames = data.getStringArrayListExtra(SearchActivity.RETURN_EXTRA_SELECTED_USERNAMES);
String currentUsers = binding.excludeUsersTextInputEditTextCustomizeCommentFilterActivity.getText().toString().trim();
if (usernames != null && !usernames.isEmpty()) {
if (!currentUsers.isEmpty() && currentUsers.charAt(currentUsers.length() - 1) != ',') {
String newString = currentUsers + ",";
binding.excludeUsersTextInputEditTextCustomizeCommentFilterActivity.setText(newString);
}
StringBuilder stringBuilder = new StringBuilder();
for (String s : usernames) {
stringBuilder.append(s).append(",");
}
stringBuilder.deleteCharAt(stringBuilder.length() - 1);
binding.excludeUsersTextInputEditTextCustomizeCommentFilterActivity.append(stringBuilder.toString());
}
});
binding.addUsersImageViewCustomizeCommentFilterActivity.setOnClickListener(view -> {
Intent intent = new Intent(this, SearchActivity.class);
intent.putExtra(SearchActivity.EXTRA_SEARCH_ONLY_USERS, true);
intent.putExtra(SearchActivity.EXTRA_IS_MULTI_SELECTION, true);
requestAddUsersLauncher.launch(intent);
});
fromSettings = getIntent().getBooleanExtra(EXTRA_FROM_SETTINGS, false);
if (savedInstanceState != null) {
commentFilter = savedInstanceState.getParcelable(COMMENT_FILTER_STATE);
originalName = savedInstanceState.getString(ORIGINAL_NAME_STATE);
} else {
commentFilter = getIntent().getParcelableExtra(EXTRA_COMMENT_FILTER);
if (commentFilter == null) {
commentFilter = new CommentFilter();
originalName = "";
} else {
if (!fromSettings) {
originalName = "";
} else {
originalName = commentFilter.name;
}
}
bindView();
}
}
private void bindView() {
binding.nameTextInputEditTextCustomizeCommentFilterActivity.setText(commentFilter.name);
binding.excludeStringsTextInputEditTextCustomizeCommentFilterActivity.setText(commentFilter.excludeStrings);
binding.excludeUsersTextInputEditTextCustomizeCommentFilterActivity.setText(commentFilter.excludeUsers);
binding.minVoteTextInputEditTextCustomizeCommentFilterActivity.setText(Integer.toString(commentFilter.minVote));
binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity.setText(Integer.toString(commentFilter.maxVote));
}
@Override
protected SharedPreferences getDefaultSharedPreferences() {
return mSharedPreferences;
}
@Override
protected CustomThemeWrapper getCustomThemeWrapper() {
return mCustomThemeWrapper;
}
@Override
protected void applyCustomTheme() {
binding.getRoot().setBackgroundColor(mCustomThemeWrapper.getBackgroundColor());
applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(binding.appbarLayoutCustomizeCommentFilterActivity, binding.collapsingToolbarLayoutCustomizeCommentFilterActivity, binding.toolbarCustomizeCommentFilterActivity);
int primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor();
int primaryIconColor = mCustomThemeWrapper.getPrimaryIconColor();
Drawable cursorDrawable = Utils.getTintedDrawable(this, R.drawable.edit_text_cursor, primaryTextColor);
binding.nameTextInputLayoutCustomizeCommentFilterActivity.setBoxStrokeColor(primaryTextColor);
binding.nameTextInputLayoutCustomizeCommentFilterActivity.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor));
binding.nameTextInputEditTextCustomizeCommentFilterActivity.setTextColor(primaryTextColor);
binding.excludeStringsTextInputLayoutCustomizeCommentFilterActivity.setBoxStrokeColor(primaryTextColor);
binding.excludeStringsTextInputLayoutCustomizeCommentFilterActivity.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor));
binding.excludeStringsTextInputEditTextCustomizeCommentFilterActivity.setTextColor(primaryTextColor);
binding.excludeUsersTextInputLayoutCustomizeCommentFilterActivity.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor));
binding.excludeUsersTextInputEditTextCustomizeCommentFilterActivity.setTextColor(primaryTextColor);
binding.addUsersImageViewCustomizeCommentFilterActivity.setImageDrawable(Utils.getTintedDrawable(this, R.drawable.ic_add_24dp, primaryIconColor));
binding.minVoteTextInputLayoutCustomizeCommentFilterActivity.setBoxStrokeColor(primaryTextColor);
binding.minVoteTextInputLayoutCustomizeCommentFilterActivity.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor));
binding.minVoteTextInputEditTextCustomizeCommentFilterActivity.setTextColor(primaryTextColor);
binding.maxVoteTextInputLayoutCustomizeCommentFilterActivity.setBoxStrokeColor(primaryTextColor);
binding.maxVoteTextInputLayoutCustomizeCommentFilterActivity.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor));
binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity.setTextColor(primaryTextColor);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
binding.nameTextInputEditTextCustomizeCommentFilterActivity.setTextCursorDrawable(cursorDrawable);
binding.excludeStringsTextInputEditTextCustomizeCommentFilterActivity.setTextCursorDrawable(cursorDrawable);
binding.excludeUsersTextInputEditTextCustomizeCommentFilterActivity.setTextCursorDrawable(cursorDrawable);
binding.minVoteTextInputEditTextCustomizeCommentFilterActivity.setTextCursorDrawable(cursorDrawable);
binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity.setTextCursorDrawable(cursorDrawable);
} else {
setCursorDrawableColor(binding.nameTextInputEditTextCustomizeCommentFilterActivity, primaryTextColor);
setCursorDrawableColor(binding.excludeStringsTextInputEditTextCustomizeCommentFilterActivity, primaryTextColor);
setCursorDrawableColor(binding.excludeUsersTextInputEditTextCustomizeCommentFilterActivity, primaryTextColor);
setCursorDrawableColor(binding.minVoteTextInputEditTextCustomizeCommentFilterActivity, primaryTextColor);
setCursorDrawableColor(binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity, primaryTextColor);
}
if (typeface != null) {
Utils.setFontToAllTextViews(binding.getRoot(), typeface);
}
}
public void setCursorDrawableColor(EditText editText, int color) {
try {
Field fCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes");
fCursorDrawableRes.setAccessible(true);
int mCursorDrawableRes = fCursorDrawableRes.getInt(editText);
Field fEditor = TextView.class.getDeclaredField("mEditor");
fEditor.setAccessible(true);
Object editor = fEditor.get(editText);
Class<?> clazz = editor.getClass();
Field fCursorDrawable = clazz.getDeclaredField("mCursorDrawable");
fCursorDrawable.setAccessible(true);
Drawable[] drawables = new Drawable[2];
drawables[0] = editText.getContext().getResources().getDrawable(mCursorDrawableRes);
drawables[1] = editText.getContext().getResources().getDrawable(mCursorDrawableRes);
drawables[0].setColorFilter(color, PorterDuff.Mode.SRC_IN);
drawables[1].setColorFilter(color, PorterDuff.Mode.SRC_IN);
fCursorDrawable.set(editor, drawables);
} catch (Throwable ignored) {
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.customize_comment_filter_activity, menu);
if (fromSettings) {
menu.findItem(R.id.action_save_customize_comment_filter_activity).setVisible(false);
}
applyMenuItemTheme(menu);
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
return true;
} else if (item.getItemId() == R.id.action_save_customize_comment_filter_activity) {
try {
constructCommentFilter();
Intent returnIntent = new Intent();
returnIntent.putExtra(RETURN_EXTRA_COMMENT_FILTER, commentFilter);
setResult(Activity.RESULT_OK, returnIntent);
finish();
} catch (PatternSyntaxException e) {
Toast.makeText(this, R.string.invalid_regex, Toast.LENGTH_SHORT).show();
}
return true;
} else if (item.getItemId() == R.id.action_save_to_database_customize_comment_filter_activity) {
try {
constructCommentFilter();
if (!commentFilter.name.equals("")) {
saveCommentFilter(originalName);
} else {
Toast.makeText(CustomizeCommentFilterActivity.this, R.string.comment_filter_requires_a_name, Toast.LENGTH_LONG).show();
}
} catch (PatternSyntaxException e) {
Toast.makeText(this, R.string.invalid_regex, Toast.LENGTH_SHORT).show();
}
}
return false;
}
private void saveCommentFilter(String originalName) {
SaveCommentFilter.saveCommentFilter(mExecutor, new Handler(), mRedditDataRoomDatabase, commentFilter, originalName,
new SaveCommentFilter.SaveCommentFilterListener() {
@Override
public void success() {
Intent returnIntent = new Intent();
returnIntent.putExtra(RETURN_EXTRA_COMMENT_FILTER, commentFilter);
setResult(Activity.RESULT_OK, returnIntent);
finish();
}
@Override
public void duplicate() {
new MaterialAlertDialogBuilder(CustomizeCommentFilterActivity.this, R.style.MaterialAlertDialogTheme)
.setTitle(getString(R.string.duplicate_comment_filter_dialog_title, commentFilter.name))
.setMessage(R.string.duplicate_comment_filter_dialog_message)
.setPositiveButton(R.string.override, (dialogInterface, i) -> saveCommentFilter(commentFilter.name))
.setNegativeButton(R.string.cancel, null)
.show();
}
});
}
private void constructCommentFilter() throws PatternSyntaxException {
commentFilter.name = binding.nameTextInputEditTextCustomizeCommentFilterActivity.getText().toString();
commentFilter.excludeStrings = binding.excludeStringsTextInputEditTextCustomizeCommentFilterActivity.getText().toString();
commentFilter.excludeUsers = binding.excludeUsersTextInputEditTextCustomizeCommentFilterActivity.getText().toString();
commentFilter.maxVote = binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity.getText() == null || binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity.getText().toString().equals("") ? -1 : Integer.parseInt(binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity.getText().toString());
commentFilter.minVote = binding.minVoteTextInputEditTextCustomizeCommentFilterActivity.getText() == null || binding.minVoteTextInputEditTextCustomizeCommentFilterActivity.getText().toString().equals("") ? -1 : Integer.parseInt(binding.minVoteTextInputEditTextCustomizeCommentFilterActivity.getText().toString());
}
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable(COMMENT_FILTER_STATE, commentFilter);
outState.putString(ORIGINAL_NAME_STATE, originalName);
}
}

View File

@@ -226,10 +226,6 @@ public class CustomizePostFilterActivity extends BaseActivity {
applyCustomTheme();
if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) {
Slidr.attach(this);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) {
addOnOffsetChangedListener(appBarLayout);
}

View File

@@ -345,7 +345,7 @@ public class EditCommentActivity extends BaseActivity implements UploadImageEnab
int start = Math.max(contentEditText.getSelectionStart(), 0);
int end = Math.max(contentEditText.getSelectionEnd(), 0);
contentEditText.getText().replace(Math.min(start, end), Math.max(start, end),
"[" + uploadedImage.imageName + "](" + uploadedImage.imageUrl + ")",
0, "[]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length());
"![" + uploadedImage.imageName + "](" + uploadedImage.imageUrl + ")",
0, "![]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length());
}
}

View File

@@ -3,17 +3,20 @@ package eu.toldi.infinityforlemmy.activities;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.annotation.NonNull;
@@ -23,18 +26,22 @@ import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.core.content.FileProvider;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.snackbar.Snackbar;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.json.JSONException;
import org.xmlpull.v1.XmlPullParserException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import javax.inject.Inject;
@@ -48,14 +55,16 @@ import eu.toldi.infinityforlemmy.RetrofitHolder;
import eu.toldi.infinityforlemmy.UploadImageEnabledActivity;
import eu.toldi.infinityforlemmy.UploadedImage;
import eu.toldi.infinityforlemmy.adapters.MarkdownBottomBarRecyclerViewAdapter;
import eu.toldi.infinityforlemmy.apis.RedditAPI;
import eu.toldi.infinityforlemmy.apis.LemmyAPI;
import eu.toldi.infinityforlemmy.bottomsheetfragments.UploadedImagesBottomSheetFragment;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed;
import eu.toldi.infinityforlemmy.customviews.slidr.Slidr;
import eu.toldi.infinityforlemmy.dto.EditPostDTO;
import eu.toldi.infinityforlemmy.events.SwitchAccountEvent;
import eu.toldi.infinityforlemmy.utils.APIUtils;
import eu.toldi.infinityforlemmy.post.Post;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import eu.toldi.infinityforlemmy.utils.UploadImageUtils;
import eu.toldi.infinityforlemmy.utils.Utils;
import retrofit2.Call;
import retrofit2.Callback;
@@ -64,16 +73,19 @@ import retrofit2.Retrofit;
public class EditPostActivity extends BaseActivity implements UploadImageEnabledActivity {
public static final String EXTRA_TITLE = "ET";
public static final String EXTRA_CONTENT = "EC";
public static final String EXTRA_FULLNAME = "EF";
public static final String EXTRA_DATA = "ED";
private static final int UPLOAD_IMAGE_REQUEST_CODE = 1;
private static final int PICK_IMAGE_REQUEST_CODE = 100;
private static final int CAPTURE_IMAGE_REQUEST_CODE = 200;
private static final int MARKDOWN_PREVIEW_REQUEST_CODE = 300;
private static final String UPLOADED_IMAGES_STATE = "UIS";
private static final String picturePattern = "https:\\/\\/[^\\/]+\\/pictrs\\/image\\/([a-f\\d-]+\\.jpeg)";
@BindView(R.id.coordinator_layout_edit_post_activity)
CoordinatorLayout coordinatorLayout;
@BindView(R.id.appbar_layout_edit_post_activity)
@@ -81,13 +93,22 @@ public class EditPostActivity extends BaseActivity implements UploadImageEnabled
@BindView(R.id.toolbar_edit_post_activity)
Toolbar toolbar;
@BindView(R.id.post_title_text_view_edit_post_activity)
TextView titleTextView;
EditText titleEditText;
@BindView(R.id.divider_edit_post_activity)
View divider;
@BindView(R.id.post_text_content_edit_text_edit_post_activity)
EditText contentEditText;
@BindView(R.id.markdown_bottom_bar_recycler_view_edit_post_activity)
RecyclerView markdownBottomBarRecyclerView;
@BindView(R.id.post_link_edit_text_post_edit_activity)
EditText linkEditText;
@BindView(R.id.upload_image_button_post_edit_activity)
MaterialButton uploadImageButton;
@BindView(R.id.image_view_post_edit_activity)
ImageView imageView;
@Inject
@Named("no_oauth")
RetrofitHolder mRetrofit;
@@ -104,13 +125,16 @@ public class EditPostActivity extends BaseActivity implements UploadImageEnabled
CustomThemeWrapper mCustomThemeWrapper;
@Inject
Executor mExecutor;
private String mFullName;
private Post mPost;
private String mAccessToken;
private String mPostContent;
private boolean isSubmitting = false;
private Uri capturedImageUri;
private ArrayList<UploadedImage> uploadedImages = new ArrayList<>();
private RequestManager mGlide;
@Override
protected void onCreate(Bundle savedInstanceState) {
((Infinity) getApplication()).getAppComponent().inject(this);
@@ -138,11 +162,49 @@ public class EditPostActivity extends BaseActivity implements UploadImageEnabled
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mFullName = getIntent().getStringExtra(EXTRA_FULLNAME);
mPost = getIntent().getParcelableExtra(EXTRA_DATA);
if (mPost == null) {
finish();
}
mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null);
titleTextView.setText(getIntent().getStringExtra(EXTRA_TITLE));
mPostContent = getIntent().getStringExtra(EXTRA_CONTENT);
contentEditText.setText(mPostContent);
titleEditText.setText(mPost.getTitle());
contentEditText.setText(mPost.getSelfText());
linkEditText.setText(mPost.getUrl());
mGlide = Glide.with(getApplication());
if (mPost.getUrl() != null && mPost.getUrl().matches(picturePattern)) {
loadImage();
}
linkEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (charSequence.toString().matches(picturePattern)) {
loadImage();
} else {
uploadImageButton.setVisibility(View.VISIBLE);
imageView.setVisibility(View.GONE);
}
}
@Override
public void afterTextChanged(Editable editable) {
}
});
uploadImageButton.setOnClickListener(view -> {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, getString(R.string.select_from_gallery)), UPLOAD_IMAGE_REQUEST_CODE);
});
if (savedInstanceState != null) {
uploadedImages = savedInstanceState.getParcelableArrayList(UPLOADED_IMAGES_STATE);
@@ -190,18 +252,27 @@ public class EditPostActivity extends BaseActivity implements UploadImageEnabled
protected void applyCustomTheme() {
coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor());
applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, null, toolbar);
titleTextView.setTextColor(mCustomThemeWrapper.getPostTitleColor());
titleEditText.setTextColor(mCustomThemeWrapper.getPostTitleColor());
divider.setBackgroundColor(mCustomThemeWrapper.getPostTitleColor());
contentEditText.setTextColor(mCustomThemeWrapper.getPostContentColor());
linkEditText.setTextColor(mCustomThemeWrapper.getPostContentColor());
uploadImageButton.setTextColor(mCustomThemeWrapper.getButtonTextColor());
uploadImageButton.setBackgroundColor(mCustomThemeWrapper.getColorPrimaryLightTheme());
if (titleTypeface != null) {
titleTextView.setTypeface(titleTypeface);
titleEditText.setTypeface(titleTypeface);
}
if (contentTypeface != null) {
contentEditText.setTypeface(contentTypeface);
}
}
private void loadImage() {
uploadImageButton.setVisibility(View.GONE);
imageView.setVisibility(View.VISIBLE);
mGlide.load(mPost.getUrl()).into(imageView);
}
@Override
protected void onPause() {
super.onPause();
@@ -237,21 +308,19 @@ public class EditPostActivity extends BaseActivity implements UploadImageEnabled
isSubmitting = true;
Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_SHORT).show();
Map<String, String> params = new HashMap<>();
params.put(APIUtils.THING_ID_KEY, mFullName);
params.put(APIUtils.TEXT_KEY, contentEditText.getText().toString());
mRetrofit.getRetrofit().create(RedditAPI.class)
.editPostOrComment(APIUtils.getOAuthHeader(mAccessToken), params)
mRetrofit.getRetrofit().create(LemmyAPI.class).postUpdate(new EditPostDTO(mPost.getId(), titleEditText.getText().toString(), (linkEditText.getText().toString().isEmpty()) ? null : linkEditText.getText().toString(), contentEditText.getText().toString(), mPost.isNSFW(), null, mAccessToken))
.enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
isSubmitting = false;
Toast.makeText(EditPostActivity.this, R.string.edit_success, Toast.LENGTH_SHORT).show();
Intent returnIntent = new Intent();
setResult(RESULT_OK, returnIntent);
finish();
if (response.isSuccessful()) {
Toast.makeText(EditPostActivity.this, R.string.edit_success, Toast.LENGTH_SHORT).show();
Intent returnIntent = new Intent();
setResult(RESULT_OK, returnIntent);
finish();
} else {
Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show();
}
}
@Override
@@ -275,6 +344,39 @@ public class EditPostActivity extends BaseActivity implements UploadImageEnabled
}
Utils.uploadImageToReddit(this, mExecutor, mRetrofit,
mAccessToken, contentEditText, coordinatorLayout, data.getData(), uploadedImages);
} else if (requestCode == UPLOAD_IMAGE_REQUEST_CODE) {
if (data == null) {
Snackbar.make(coordinatorLayout, R.string.error_getting_image, Snackbar.LENGTH_SHORT).show();
return;
}
Toast.makeText(this, R.string.uploading_image, Toast.LENGTH_SHORT).show();
Handler handler = new Handler();
Uri imageUri = data.getData();
mExecutor.execute(() -> {
try {
Bitmap bitmap = Glide.with(getApplication()).asBitmap().load(imageUri).submit().get();
String imageUrlOrError = UploadImageUtils.uploadImage(mRetrofit, mAccessToken, bitmap);
handler.post(() -> {
if (imageUrlOrError != null && !imageUrlOrError.startsWith("Error: ")) {
String fileName = Utils.getFileName(this, imageUri);
if (fileName == null) {
fileName = imageUrlOrError;
}
mPost.setUrl(imageUrlOrError);
linkEditText.setText(imageUrlOrError);
Snackbar.make(coordinatorLayout, R.string.upload_image_success, Snackbar.LENGTH_LONG).show();
} else {
Toast.makeText(this, R.string.upload_image_failed, Toast.LENGTH_LONG).show();
}
});
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
handler.post(() -> Toast.makeText(this, R.string.get_image_bitmap_failed, Toast.LENGTH_LONG).show());
} catch (XmlPullParserException | JSONException | IOException e) {
e.printStackTrace();
handler.post(() -> Toast.makeText(this, R.string.error_processing_image, Toast.LENGTH_LONG).show());
}
});
} else if (requestCode == CAPTURE_IMAGE_REQUEST_CODE) {
Utils.uploadImageToReddit(this, mExecutor, mRetrofit,
mAccessToken, contentEditText, coordinatorLayout, capturedImageUri, uploadedImages);
@@ -282,6 +384,7 @@ public class EditPostActivity extends BaseActivity implements UploadImageEnabled
editPost();
}
}
}
@Override
@@ -305,7 +408,7 @@ public class EditPostActivity extends BaseActivity implements UploadImageEnabled
if (isSubmitting) {
promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_edit_post_detail);
} else {
if (contentEditText.getText().toString().equals(mPostContent)) {
if (contentEditText.getText().toString().equals(mPost.getSelfText())) {
finish();
} else {
promptAlertDialog(R.string.discard, R.string.discard_detail);
@@ -353,7 +456,7 @@ public class EditPostActivity extends BaseActivity implements UploadImageEnabled
int start = Math.max(contentEditText.getSelectionStart(), 0);
int end = Math.max(contentEditText.getSelectionEnd(), 0);
contentEditText.getText().replace(Math.min(start, end), Math.max(start, end),
"[" + uploadedImage.imageName + "](" + uploadedImage.imageUrl + ")",
0, "[]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length());
"![" + uploadedImage.imageName + "](" + uploadedImage.imageUrl + ")",
0, "![]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length());
}
}

View File

@@ -38,7 +38,6 @@ import javax.inject.Named;
import butterknife.BindView;
import butterknife.ButterKnife;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
import eu.toldi.infinityforlemmy.Infinity;
import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.RedditDataRoomDatabase;
@@ -52,6 +51,7 @@ import eu.toldi.infinityforlemmy.user.UserViewModel;
import eu.toldi.infinityforlemmy.utils.EditProfileUtils;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import eu.toldi.infinityforlemmy.utils.Utils;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
import pl.droidsonroids.gif.GifImageView;
import retrofit2.Retrofit;
@@ -135,7 +135,7 @@ public class EditProfileActivity extends BaseActivity {
startPickImage(PICK_IMAGE_AVATAR_REQUEST_CODE);
});
final RequestManager glide = Glide.with(this);
final RequestManager glide = Glide.with(getApplication());
final UserViewModel.Factory userViewModelFactory =
new UserViewModel.Factory(getApplication(), mRedditDataRoomDatabase, mAccountName);
final UserViewModel userViewModel =

View File

@@ -103,6 +103,8 @@ public class FilteredPostsActivity extends BaseActivity implements SortTypeSelec
public SubredditViewModel mSubredditViewModel;
private String mAccessToken;
private String mAccountName;
private String mAccountQualifiedName;
private String name;
private String userWhere;
private int postType;
@@ -158,6 +160,7 @@ public class FilteredPostsActivity extends BaseActivity implements SortTypeSelec
mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null);
mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null);
mAccountQualifiedName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, null);
name = getIntent().getStringExtra(EXTRA_NAME);
postType = getIntent().getIntExtra(EXTRA_POST_TYPE, PostPagingSource.TYPE_FRONT_PAGE);
@@ -262,14 +265,14 @@ public class FilteredPostsActivity extends BaseActivity implements SortTypeSelec
protected void applyCustomTheme() {
coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor());
applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, collapsingToolbarLayout, toolbar);
applyFABTheme(fab);
applyFABTheme(fab, mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false));
}
private void bindView(PostFilter postFilter, boolean initializeFragment) {
switch (postType) {
case PostPagingSource.TYPE_FRONT_PAGE:
case PostPagingSource.TYPE_ANONYMOUS_FRONT_PAGE:
getSupportActionBar().setTitle(R.string.home);
getSupportActionBar().setTitle(R.string.subscribed_feed);
break;
case PostPagingSource.TYPE_SEARCH:
getSupportActionBar().setTitle(R.string.search);
@@ -470,7 +473,7 @@ public class FilteredPostsActivity extends BaseActivity implements SortTypeSelec
@Override
public void markPostAsRead(Post post) {
InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, mAccountName, post.getId());
InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, mAccountQualifiedName, post.getId());
}
@Override

View File

@@ -29,12 +29,6 @@ import javax.inject.Named;
import butterknife.BindView;
import butterknife.ButterKnife;
import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon;
import io.noties.markwon.MarkwonConfiguration;
import io.noties.markwon.MarkwonPlugin;
import io.noties.markwon.core.MarkwonTheme;
import io.noties.markwon.recycler.MarkwonAdapter;
import eu.toldi.infinityforlemmy.Infinity;
import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
@@ -45,6 +39,12 @@ import eu.toldi.infinityforlemmy.customviews.slidr.Slidr;
import eu.toldi.infinityforlemmy.events.SwitchAccountEvent;
import eu.toldi.infinityforlemmy.markdown.MarkdownUtils;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon;
import io.noties.markwon.MarkwonConfiguration;
import io.noties.markwon.MarkwonPlugin;
import io.noties.markwon.core.MarkwonTheme;
import io.noties.markwon.recycler.MarkwonAdapter;
public class FullMarkdownActivity extends BaseActivity {
@@ -139,7 +139,7 @@ public class FullMarkdownActivity extends BaseActivity {
}
};
Markwon markwon = MarkdownUtils.createFullRedditMarkwon(this,
miscPlugin, markdownColor, spoilerBackgroundColor, null);
miscPlugin, markdownColor, spoilerBackgroundColor, null, mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_IMAGE_PREVIEW, false));
MarkwonAdapter markwonAdapter = MarkdownUtils.createTablesAdapter();
LinearLayoutManagerBugFixed linearLayoutManager = new SwipeLockLinearLayoutManager(this, new SwipeLockInterface() {

View File

@@ -1,336 +0,0 @@
package eu.toldi.infinityforlemmy.activities;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.android.material.tabs.TabLayout;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import javax.inject.Inject;
import javax.inject.Named;
import butterknife.BindView;
import butterknife.ButterKnife;
import eu.toldi.infinityforlemmy.ActivityToolbarInterface;
import eu.toldi.infinityforlemmy.Infinity;
import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.bottomsheetfragments.PostLayoutBottomSheetFragment;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.customviews.slidr.Slidr;
import eu.toldi.infinityforlemmy.events.ChangeNSFWEvent;
import eu.toldi.infinityforlemmy.events.SwitchAccountEvent;
import eu.toldi.infinityforlemmy.fragments.CommentsListingFragment;
import eu.toldi.infinityforlemmy.fragments.HistoryPostFragment;
import eu.toldi.infinityforlemmy.fragments.PostFragment;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
public class HistoryActivity extends BaseActivity implements ActivityToolbarInterface,
PostLayoutBottomSheetFragment.PostLayoutSelectionCallback {
@BindView(R.id.coordinator_layout_history_activity)
CoordinatorLayout coordinatorLayout;
@BindView(R.id.appbar_layout_history_activity)
AppBarLayout appBarLayout;
@BindView(R.id.collapsing_toolbar_layout_history_activity)
CollapsingToolbarLayout collapsingToolbarLayout;
@BindView(R.id.toolbar_history_activity)
Toolbar toolbar;
@BindView(R.id.tab_layout_tab_layout_history_activity_activity)
TabLayout tabLayout;
@BindView(R.id.view_pager_history_activity)
ViewPager2 viewPager2;
@Inject
@Named("default")
SharedPreferences mSharedPreferences;
@Inject
@Named("post_layout")
SharedPreferences mPostLayoutSharedPreferences;
@Inject
@Named("current_account")
SharedPreferences mCurrentAccountSharedPreferences;
@Inject
CustomThemeWrapper mCustomThemeWrapper;
private FragmentManager fragmentManager;
private SectionsPagerAdapter sectionsPagerAdapter;
private String mAccessToken;
private String mAccountName;
@Override
protected void onCreate(Bundle savedInstanceState) {
((Infinity) getApplication()).getAppComponent().inject(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_history);
ButterKnife.bind(this);
EventBus.getDefault().register(this);
applyCustomTheme();
if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) {
mSliderPanel = Slidr.attach(this);
}
//mViewPager2 = viewPager2;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Window window = getWindow();
if (isChangeStatusBarIconColor()) {
addOnOffsetChangedListener(appBarLayout);
}
if (isImmersiveInterface()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
window.setDecorFitsSystemWindows(false);
} else {
window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
adjustToolbar(toolbar);
}
}
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
setToolbarGoToTop(toolbar);
fragmentManager = getSupportFragmentManager();
mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null);
mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null);
initializeViewPager();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (sectionsPagerAdapter != null) {
return sectionsPagerAdapter.handleKeyDown(keyCode) || super.onKeyDown(keyCode, event);
}
return super.onKeyDown(keyCode, event);
}
@Override
public SharedPreferences getDefaultSharedPreferences() {
return mSharedPreferences;
}
@Override
protected CustomThemeWrapper getCustomThemeWrapper() {
return mCustomThemeWrapper;
}
@Override
protected void applyCustomTheme() {
coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor());
applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, collapsingToolbarLayout, toolbar);
applyTabLayoutTheme(tabLayout);
}
private void initializeViewPager() {
sectionsPagerAdapter = new SectionsPagerAdapter(this);
tabLayout.setVisibility(View.GONE);
viewPager2.setAdapter(sectionsPagerAdapter);
viewPager2.setOffscreenPageLimit(2);
//viewPager2.setUserInputEnabled(!mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS, false));
viewPager2.setUserInputEnabled(false);
/*new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> {
switch (position) {
case 0:
Utils.setTitleWithCustomFontToTab(typeface, tab, getString(R.string.posts));
break;
}
}).attach();*/
viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
if (position == 0) {
unlockSwipeRightToGoBack();
} else {
lockSwipeRightToGoBack();
}
}
});
fixViewPager2Sensitivity(viewPager2);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.history_activity, menu);
applyMenuItemTheme(menu);
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
int itemId = item.getItemId();
if (itemId == android.R.id.home) {
finish();
return true;
} else if (itemId == R.id.action_refresh_history_activity) {
sectionsPagerAdapter.refresh();
return true;
} else if (itemId == R.id.action_change_post_layout_history_activity) {
PostLayoutBottomSheetFragment postLayoutBottomSheetFragment = new PostLayoutBottomSheetFragment();
postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag());
return true;
}
return false;
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
@Subscribe
public void onAccountSwitchEvent(SwitchAccountEvent event) {
finish();
}
@Subscribe
public void onChangeNSFWEvent(ChangeNSFWEvent changeNSFWEvent) {
sectionsPagerAdapter.changeNSFW(changeNSFWEvent.nsfw);
}
@Override
public void onLongPress() {
if (sectionsPagerAdapter != null) {
sectionsPagerAdapter.goBackToTop();
}
}
@Override
public void lockSwipeRightToGoBack() {
if (mSliderPanel != null) {
mSliderPanel.lock();
}
}
@Override
public void unlockSwipeRightToGoBack() {
if (mSliderPanel != null) {
mSliderPanel.unlock();
}
}
@Override
public void postLayoutSelected(int postLayout) {
if (sectionsPagerAdapter != null) {
mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.HISTORY_POST_LAYOUT_READ_POST, postLayout).apply();
sectionsPagerAdapter.changePostLayout(postLayout);
}
}
private class SectionsPagerAdapter extends FragmentStateAdapter {
SectionsPagerAdapter(FragmentActivity fa) {
super(fa);
}
@NonNull
@Override
public Fragment createFragment(int position) {
if (position == 0) {
HistoryPostFragment fragment = new HistoryPostFragment();
Bundle bundle = new Bundle();
bundle.putInt(HistoryPostFragment.EXTRA_HISTORY_TYPE, HistoryPostFragment.HISTORY_TYPE_READ_POSTS);
bundle.putString(HistoryPostFragment.EXTRA_ACCESS_TOKEN, mAccessToken);
bundle.putString(HistoryPostFragment.EXTRA_ACCOUNT_NAME, mAccountName);
fragment.setArguments(bundle);
return fragment;
} else {
HistoryPostFragment fragment = new HistoryPostFragment();
Bundle bundle = new Bundle();
bundle.putInt(HistoryPostFragment.EXTRA_HISTORY_TYPE, HistoryPostFragment.HISTORY_TYPE_READ_POSTS);
bundle.putString(HistoryPostFragment.EXTRA_ACCESS_TOKEN, mAccessToken);
bundle.putString(HistoryPostFragment.EXTRA_ACCOUNT_NAME, mAccountName);
fragment.setArguments(bundle);
return fragment;
}
}
@Nullable
private Fragment getCurrentFragment() {
if (viewPager2 == null || fragmentManager == null) {
return null;
}
return fragmentManager.findFragmentByTag("f" + viewPager2.getCurrentItem());
}
public boolean handleKeyDown(int keyCode) {
if (viewPager2.getCurrentItem() == 0) {
Fragment fragment = getCurrentFragment();
if (fragment instanceof PostFragment) {
return ((PostFragment) fragment).handleKeyDown(keyCode);
}
}
return false;
}
public void refresh() {
Fragment fragment = getCurrentFragment();
if (fragment instanceof PostFragment) {
((PostFragment) fragment).refresh();
} else if (fragment instanceof CommentsListingFragment) {
((CommentsListingFragment) fragment).refresh();
}
}
public void changeNSFW(boolean nsfw) {
Fragment fragment = getCurrentFragment();
if (fragment instanceof PostFragment) {
((PostFragment) fragment).changeNSFW(nsfw);
}
}
public void changePostLayout(int postLayout) {
Fragment fragment = getCurrentFragment();
if (fragment instanceof HistoryPostFragment) {
((HistoryPostFragment) fragment).changePostLayout(postLayout);
}
}
public void goBackToTop() {
Fragment fragment = getCurrentFragment();
if (fragment instanceof PostFragment) {
((PostFragment) fragment).goBackToTop();
} else if (fragment instanceof CommentsListingFragment) {
((CommentsListingFragment) fragment).goBackToTop();
}
}
@Override
public int getItemCount() {
return 1;
}
}
}

View File

@@ -47,7 +47,6 @@ import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.RecyclerViewContentScrollingInterface;
import eu.toldi.infinityforlemmy.RedditDataRoomDatabase;
import eu.toldi.infinityforlemmy.RetrofitHolder;
import eu.toldi.infinityforlemmy.apis.RedditAPI;
import eu.toldi.infinityforlemmy.asynctasks.SwitchAccount;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.customviews.slidr.Slidr;
@@ -56,14 +55,12 @@ import eu.toldi.infinityforlemmy.events.PassPrivateMessageEvent;
import eu.toldi.infinityforlemmy.events.PassPrivateMessageIndexEvent;
import eu.toldi.infinityforlemmy.events.SwitchAccountEvent;
import eu.toldi.infinityforlemmy.fragments.InboxFragment;
import eu.toldi.infinityforlemmy.fragments.PrivateMessageFragment;
import eu.toldi.infinityforlemmy.message.CommentInteraction;
import eu.toldi.infinityforlemmy.message.FetchMessage;
import eu.toldi.infinityforlemmy.message.Message;
import eu.toldi.infinityforlemmy.utils.APIUtils;
import eu.toldi.infinityforlemmy.message.ReadMessage;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import eu.toldi.infinityforlemmy.utils.Utils;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class InboxActivity extends BaseActivity implements ActivityToolbarInterface, RecyclerViewContentScrollingInterface {
@@ -184,7 +181,7 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf
if (i == EditorInfo.IME_ACTION_DONE) {
Utils.hideKeyboard(this);
Intent pmIntent = new Intent(this, SendPrivateMessageActivity.class);
pmIntent.putExtra(SendPrivateMessageActivity.EXTRA_RECIPIENT_USERNAME, thingEditText.getText().toString());
//pmIntent.putExtra(SendPrivateMessageActivity.EXTRA_RECIPIENT_USERNAME, thingEditText.getText().toString());
startActivity(pmIntent);
return true;
}
@@ -197,7 +194,7 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf
-> {
Utils.hideKeyboard(this);
Intent pmIntent = new Intent(this, SendPrivateMessageActivity.class);
pmIntent.putExtra(SendPrivateMessageActivity.EXTRA_RECIPIENT_USERNAME, thingEditText.getText().toString());
//pmIntent.putExtra(SendPrivateMessageActivity.EXTRA_RECIPIENT_USERNAME, thingEditText.getText().toString());
startActivity(pmIntent);
})
.setNegativeButton(R.string.cancel, null)
@@ -229,7 +226,7 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf
mCoordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor());
applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(mAppBarLayout, mCollapsingToolbarLayout, mToolbar);
applyTabLayoutTheme(tabLayout);
applyFABTheme(fab);
applyFABTheme(fab, mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false));
}
private void getCurrentAccountAndFetchMessage(Bundle savedInstanceState) {
@@ -268,13 +265,16 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf
}
});
viewPager2.setAdapter(sectionsPagerAdapter);
viewPager2.setOffscreenPageLimit(2);
viewPager2.setOffscreenPageLimit(3);
new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> {
switch (position) {
case 0:
Utils.setTitleWithCustomFontToTab(typeface, tab, getString(R.string.notifications));
Utils.setTitleWithCustomFontToTab(typeface, tab, getString(R.string.replies));
break;
case 1:
Utils.setTitleWithCustomFontToTab(typeface, tab, getString(R.string.mentions));
break;
case 2:
Utils.setTitleWithCustomFontToTab(typeface, tab, getString(R.string.messages));
break;
}
@@ -302,31 +302,21 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf
return true;
} else if (item.getItemId() == R.id.action_read_all_messages_inbox_activity) {
if (mAccessToken != null) {
Toast.makeText(this, R.string.please_wait, Toast.LENGTH_SHORT).show();
mRetrofit.getRetrofit().create(RedditAPI.class).readAllMessages(APIUtils.getOAuthHeader(mAccessToken))
.enqueue(new Callback<>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
if (response.isSuccessful()) {
Toast.makeText(InboxActivity.this, R.string.read_all_messages_success, Toast.LENGTH_SHORT).show();
if (sectionsPagerAdapter != null) {
sectionsPagerAdapter.readAllMessages();
}
EventBus.getDefault().post(new ChangeInboxCountEvent(0));
} else {
if (response.code() == 429) {
Toast.makeText(InboxActivity.this, R.string.read_all_messages_time_limit, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(InboxActivity.this, R.string.read_all_messages_failed, Toast.LENGTH_LONG).show();
}
}
}
ReadMessage.readAllMessages(mRetrofit.getRetrofit(), mAccessToken, new ReadMessage.ReadMessageListener() {
@Override
public void readSuccess() {
Toast.makeText(InboxActivity.this, R.string.read_all_messages_success, Toast.LENGTH_SHORT).show();
if (sectionsPagerAdapter != null) {
sectionsPagerAdapter.readAllMessages();
}
EventBus.getDefault().post(new ChangeInboxCountEvent(0));
}
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
Toast.makeText(InboxActivity.this, R.string.read_all_messages_failed, Toast.LENGTH_LONG).show();
}
});
@Override
public void readFailed() {
}
});
}
} else if (item.getItemId() == android.R.id.home) {
finish();
@@ -341,7 +331,7 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf
if (resultCode == RESULT_OK && requestCode == SEARCH_USER_REQUEST_CODE && data != null) {
String username = data.getStringExtra(SearchActivity.EXTRA_RETURN_USER_NAME);
Intent intent = new Intent(this, SendPrivateMessageActivity.class);
intent.putExtra(SendPrivateMessageActivity.EXTRA_RECIPIENT_USERNAME, username);
//intent.putExtra(SendPrivateMessageActivity.EXTRA_RECIPIENT_USERNAME, username);
startActivity(intent);
}
}
@@ -438,7 +428,7 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf
}
}
Message getPrivateMessage(int index) {
CommentInteraction getPrivateMessage(int index) {
if (viewPager2 == null || fragmentManager == null) {
return null;
}
@@ -452,26 +442,27 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf
@NonNull
@Override
public Fragment createFragment(int position) {
if (position == 0) {
InboxFragment fragment = new InboxFragment();
Bundle bundle = new Bundle();
bundle.putString(InboxFragment.EXTRA_ACCESS_TOKEN, mAccessToken);
bundle.putString(InboxFragment.EXTRA_MESSAGE_WHERE, FetchMessage.WHERE_INBOX);
fragment.setArguments(bundle);
return fragment;
} else {
InboxFragment fragment = new InboxFragment();
Bundle bundle = new Bundle();
bundle.putString(InboxFragment.EXTRA_ACCESS_TOKEN, mAccessToken);
bundle.putString(InboxFragment.EXTRA_MESSAGE_WHERE, FetchMessage.WHERE_MESSAGES);
fragment.setArguments(bundle);
return fragment;
Fragment fragment = new InboxFragment();
Bundle bundle = new Bundle();
bundle.putString(InboxFragment.EXTRA_ACCESS_TOKEN, mAccessToken);
switch (position) {
case 0:
bundle.putString(InboxFragment.EXTRA_MESSAGE_WHERE, FetchMessage.WHERE_REPLIES);
break;
case 1:
bundle.putString(InboxFragment.EXTRA_MESSAGE_WHERE, FetchMessage.WHERE_MENTIONS);
break;
case 2:
fragment = new PrivateMessageFragment();
break;
}
fragment.setArguments(bundle);
return fragment;
}
@Override
public int getItemCount() {
return 2;
return 3;
}
}
}

View File

@@ -0,0 +1,266 @@
package eu.toldi.infinityforlemmy.activities;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.net.Uri;
import android.os.Bundle;
import android.text.Spanned;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.card.MaterialCardView;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
import eu.toldi.infinityforlemmy.Infinity;
import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.RetrofitHolder;
import eu.toldi.infinityforlemmy.adapters.AdminRecyclerViewAdapter;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed;
import eu.toldi.infinityforlemmy.customviews.slidr.Slidr;
import eu.toldi.infinityforlemmy.databinding.ActivityInstanceInfoBinding;
import eu.toldi.infinityforlemmy.markdown.MarkdownUtils;
import eu.toldi.infinityforlemmy.site.FetchSiteInfo;
import eu.toldi.infinityforlemmy.site.SiteInfo;
import eu.toldi.infinityforlemmy.site.SiteStatistics;
import eu.toldi.infinityforlemmy.user.BasicUserInfo;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon;
import io.noties.markwon.MarkwonConfiguration;
import io.noties.markwon.MarkwonPlugin;
import io.noties.markwon.core.MarkwonTheme;
import io.noties.markwon.recycler.MarkwonAdapter;
public class InstanceInfoActivity extends BaseActivity {
@Inject
@Named("default")
SharedPreferences mSharedPreferences;
@Inject
CustomThemeWrapper mCustomThemeWrapper;
@Inject
@Named("no_oauth")
RetrofitHolder mRetorifitHolder;
ActivityInstanceInfoBinding mInstanceInfoActivityViewBinding;
private CoordinatorLayout coordinatorLayout;
private Toolbar toolbar;
private AppBarLayout appBarLayout;
private ConstraintLayout mLoadingConstraintLayout;
private MaterialCardView mStatisticsCardView;
private TextView mUsersTextView;
private TextView mCommunitiesTextView;
private TextView mPostsTextView;
private TextView mCommentsTextView;
private TextView mActiveUsersTextView;
private ImageView mUsersImageView;
private ImageView mCommunitiesImageView;
private ImageView mPostsImageView;
private ImageView mCommentsImageView;
private ImageView mActiveUsersImageView;
private MaterialCardView mDescriptionCardView;
private RecyclerView mContentMarkdownView;
private RecyclerView mAdminsRecyclerView;
private MaterialCardView mAdminsCardView;
private MarkwonAdapter mMarkwonAdapter;
private Markwon mPostDetailMarkwon;
private AdminRecyclerViewAdapter mAdminAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
((Infinity) getApplication()).getAppComponent().inject(this);
super.onCreate(savedInstanceState);
mInstanceInfoActivityViewBinding = ActivityInstanceInfoBinding.inflate(getLayoutInflater());
View view = mInstanceInfoActivityViewBinding.getRoot();
setImmersiveModeNotApplicable();
setContentView(view);
setSupportActionBar(mInstanceInfoActivityViewBinding.toolbarInstanceInfoActivity);
setUpBindings();
applyCustomTheme();
if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) {
Slidr.attach(this);
}
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// Remove transparency from navigation bar
getWindow().setNavigationBarColor(mCustomThemeWrapper.getBackgroundColor());
int markdownColor = customThemeWrapper.getPostContentColor();
int postSpoilerBackgroundColor = markdownColor | 0xFF000000;
int linkColor = customThemeWrapper.getLinkColor();
MarkwonPlugin miscPlugin = new AbstractMarkwonPlugin() {
@Override
public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) {
if (InstanceInfoActivity.this.contentTypeface != null) {
textView.setTypeface(InstanceInfoActivity.this.contentTypeface);
}
textView.setTextColor(markdownColor);
textView.setHighlightColor(Color.TRANSPARENT);
}
@Override
public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) {
builder.linkResolver((view, link) -> {
Intent intent = new Intent(InstanceInfoActivity.this, LinkResolverActivity.class);
Uri uri = Uri.parse(link);
intent.setData(uri);
InstanceInfoActivity.this.startActivity(intent);
});
}
@Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
builder.linkColor(linkColor);
}
};
mPostDetailMarkwon = MarkdownUtils.createFullRedditMarkwon(this,
miscPlugin, markdownColor, postSpoilerBackgroundColor, null, mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_IMAGE_PREVIEW, false));
mMarkwonAdapter = MarkdownUtils.createTablesAdapter();
mContentMarkdownView.setAdapter(mMarkwonAdapter);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
mContentMarkdownView.setLayoutManager(linearLayoutManager);
mAdminAdapter = new AdminRecyclerViewAdapter(InstanceInfoActivity.this, customThemeWrapper);
mAdminsRecyclerView.setLayoutManager(new LinearLayoutManagerBugFixed(InstanceInfoActivity.this));
mAdminsRecyclerView.setAdapter(mAdminAdapter);
fetchInstanceInfo();
}
@Override
protected void onStart() {
super.onStart();
fetchInstanceInfo();
}
private void fetchInstanceInfo() {
FetchSiteInfo.fetchSiteInfo(mRetorifitHolder.getRetrofit(), null, new FetchSiteInfo.FetchSiteInfoListener() {
@Override
public void onFetchSiteInfoSuccess(SiteInfo siteInfo) {
mLoadingConstraintLayout.setVisibility(View.GONE);
toolbar.setTitle(siteInfo.getName());
if (siteInfo.getSidebar() != null) {
mMarkwonAdapter.setMarkdown(mPostDetailMarkwon, siteInfo.getSidebar());
Log.i("SiteInfo", "onFetchSiteInfoSuccess: " + siteInfo.getSidebar());
// noinspection NotifyDataSetChanged
mMarkwonAdapter.notifyDataSetChanged();
mDescriptionCardView.setVisibility(View.VISIBLE);
}
List<BasicUserInfo> admins = siteInfo.getAdmins();
if (admins != null && !admins.isEmpty()) {
mAdminsCardView.setVisibility(View.VISIBLE);
mAdminAdapter.setUsers(admins);
}
SiteStatistics siteStatistics = siteInfo.getSiteStatistics();
if (siteStatistics != null) {
mStatisticsCardView.setVisibility(View.VISIBLE);
mUsersTextView.setText(getString(R.string.user_number_detail, siteStatistics.getUsers()));
mCommunitiesTextView.setText(getString(R.string.community_number_detail, siteStatistics.getCommunities()));
mPostsTextView.setText(getString(R.string.post_count_detail, siteStatistics.getPosts()));
mCommentsTextView.setText(getString(R.string.comment_count_detail, siteStatistics.getComments()));
mActiveUsersTextView.setText(getString(R.string.active_users_number_detail, siteStatistics.getUsers_active()));
}
}
@Override
public void onFetchSiteInfoFailed() {
}
});
}
protected void setUpBindings() {
coordinatorLayout = mInstanceInfoActivityViewBinding.coordinatorLayoutInstanceInfoActivity;
toolbar = mInstanceInfoActivityViewBinding.toolbarInstanceInfoActivity;
appBarLayout = mInstanceInfoActivityViewBinding.appbarLayoutInstanceInfoActivity;
mStatisticsCardView = mInstanceInfoActivityViewBinding.statisticsCardInstanceInfoActivity;
mDescriptionCardView = mInstanceInfoActivityViewBinding.descriptionCardInstanceInfoActivity;
mContentMarkdownView = mInstanceInfoActivityViewBinding.markdownRecyclerViewInstanceInfoActivity;
mAdminsCardView = mInstanceInfoActivityViewBinding.moderatorsCardInstanceInfoActivity;
mLoadingConstraintLayout = mInstanceInfoActivityViewBinding.loadingLayoutInstanceInfoActivity;
mAdminsRecyclerView = mInstanceInfoActivityViewBinding.recyclerViewAdminsInstanceInfoActivity;
mUsersTextView = mInstanceInfoActivityViewBinding.registeredUserCountTextViewInstanceInfoActivity;
mCommunitiesTextView = mInstanceInfoActivityViewBinding.communityCountInstanceInfoActivity;
mPostsTextView = mInstanceInfoActivityViewBinding.postCountTextViewInstanceInfoActivity;
mCommentsTextView = mInstanceInfoActivityViewBinding.commentCountTextViewInstanceInfoActivity;
mActiveUsersTextView = mInstanceInfoActivityViewBinding.activeUserCountTextViewInstanceInfoActivity;
mUsersImageView = mInstanceInfoActivityViewBinding.registeredUserCountImageViewInstanceInfoActivity;
mCommunitiesImageView = mInstanceInfoActivityViewBinding.communitiesIconImageViewInstanceInfoActivity;
mPostsImageView = mInstanceInfoActivityViewBinding.postCountImageViewInstanceInfoActivity;
mCommentsImageView = mInstanceInfoActivityViewBinding.commentCountImageViewInstanceInfoActivity;
mActiveUsersImageView = mInstanceInfoActivityViewBinding.activeUserCountImageViewInstanceInfoActivity;
}
@Override
protected SharedPreferences getDefaultSharedPreferences() {
return mSharedPreferences;
}
@Override
protected CustomThemeWrapper getCustomThemeWrapper() {
return mCustomThemeWrapper;
}
@Override
protected void applyCustomTheme() {
coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor());
applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, null, toolbar);
mStatisticsCardView.setCardBackgroundColor(mCustomThemeWrapper.getCardViewBackgroundColor());
mDescriptionCardView.setCardBackgroundColor(mCustomThemeWrapper.getCardViewBackgroundColor());
mAdminsCardView.setCardBackgroundColor(mCustomThemeWrapper.getCardViewBackgroundColor());
mUsersImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN);
mCommunitiesImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN);
mPostsImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN);
mCommentsImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN);
mActiveUsersImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN);
mUsersTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor());
mCommunitiesTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor());
mPostsTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor());
mCommentsTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor());
mActiveUsersTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor());
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
return true;
}
return false;
}
}

View File

@@ -7,6 +7,7 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.webkit.URLUtil;
import android.widget.Toast;
@@ -17,15 +18,25 @@ import androidx.browser.customtabs.CustomTabsService;
import org.apache.commons.io.FilenameUtils;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import javax.inject.Inject;
import javax.inject.Named;
import eu.toldi.infinityforlemmy.Infinity;
import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.RetrofitHolder;
import eu.toldi.infinityforlemmy.comment.Comment;
import eu.toldi.infinityforlemmy.comment.FetchComment;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.post.FetchPost;
import eu.toldi.infinityforlemmy.post.ObjectResolver;
import eu.toldi.infinityforlemmy.post.Post;
import eu.toldi.infinityforlemmy.post.enrich.PostEnricher;
import eu.toldi.infinityforlemmy.utils.LemmyUtils;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
@@ -35,10 +46,9 @@ public class LinkResolverActivity extends AppCompatActivity {
public static final String EXTRA_NEW_ACCOUNT_NAME = "ENAN";
public static final String EXTRA_IS_NSFW = "EIN";
private static final String POST_PATTERN = "/r/[\\w-]+/comments/\\w+/?\\w+/?";
private static final String POST_PATTERN_2 = "/(u|U|user)/[\\w-]+/comments/\\w+/?\\w+/?";
private static final String POST_PATTERN = "https?:\\/\\/\\S+\\/post\\/\\d+";
private static final String POST_PATTERN_3 = "/[\\w-]+$";
private static final String COMMENT_PATTERN = "/(r|u|U|user)/[\\w-]+/comments/\\w+/?[\\w-]+/\\w+/?";
private static final String COMMENT_PATTERN = "https?:\\/\\/\\S+\\/comment\\/\\d+";
private static final String SUBREDDIT_PATTERN = "(?:https?://[\\w.-]+)?/c/[\\w-]+(@[\\w.-]+)?";
private static final String USER_PATTERN = "(?:https?://[\\w.-]+)?/u(sers)?/[\\w-]+(@[\\w.-]+)?";
private static final String SIDEBAR_PATTERN = "/[rR]/[\\w-]+/about/sidebar";
@@ -60,11 +70,30 @@ public class LinkResolverActivity extends AppCompatActivity {
@Inject
CustomThemeWrapper mCustomThemeWrapper;
@Inject
ObjectResolver mObjectResolver;
@Inject
@Named("current_account")
SharedPreferences mCurrentAccountSharedPreferences;
@Inject
@Named("no_oauth")
RetrofitHolder mRetrofit;
@Inject
Executor mExecutor;
@Inject
PostEnricher postEnricher;
private String mAccessToken;
private Uri getRedditUriByPath(String path) {
if (path.charAt(0) != '/') {
return Uri.parse("https://www.reddit.com/" + path);
return Uri.parse(mRetrofit.getBaseURL() + path);
} else {
return Uri.parse("https://www.reddit.com" + path);
return Uri.parse(mRetrofit.getBaseURL() + path);
}
}
@@ -73,19 +102,27 @@ public class LinkResolverActivity extends AppCompatActivity {
super.onCreate(savedInstanceState);
((Infinity) getApplication()).getAppComponent().inject(this);
mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null);
if (mAccessToken != null) {
String instance = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_INSTANCE, null);
mRetrofit.setBaseURL(instance);
if (mCurrentAccountSharedPreferences.getBoolean(SharedPreferencesUtils.BEARER_TOKEN_AUTH, true)) {
mRetrofit.setAccessToken(mAccessToken);
}
}
Uri uri = getIntent().getData();
if (uri == null) {
String url = getIntent().getStringExtra(Intent.EXTRA_TEXT);
if (!URLUtil.isValidUrl(url)) {
Toast.makeText(this, R.string.invalid_link, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.invalid_link, Toast.LENGTH_SHORT).show();
finish();
return;
}
try {
uri = Uri.parse(url);
} catch (NullPointerException e) {
Toast.makeText(this, R.string.invalid_link, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.invalid_link, Toast.LENGTH_SHORT).show();
finish();
return;
}
@@ -93,7 +130,7 @@ public class LinkResolverActivity extends AppCompatActivity {
if (uri.getScheme() == null && uri.getHost() == null) {
if (uri.toString().isEmpty()) {
Toast.makeText(this, R.string.invalid_link, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.invalid_link, Toast.LENGTH_SHORT).show();
finish();
return;
}
@@ -105,7 +142,7 @@ public class LinkResolverActivity extends AppCompatActivity {
private void handleUri(Uri uri) {
if (uri == null) {
Toast.makeText(this, R.string.no_link_available, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.no_link_available, Toast.LENGTH_SHORT).show();
} else {
String path = uri.getPath();
if (path == null) {
@@ -169,92 +206,142 @@ public class LinkResolverActivity extends AppCompatActivity {
intent.putExtra(ViewUserDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname);
intent.putExtra(ViewUserDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName);
startActivity(intent);
} else if (uri.toString().matches(POST_PATTERN)) {
if (mAccessToken == null) {
// switch retrofit to use the current instance for anonymous requests
mRetrofit.setBaseURL(uri.getScheme() + "://" + uri.getHost() + "/");
Intent intent = new Intent(LinkResolverActivity.this, ViewPostDetailActivity.class);
intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, Integer.parseInt(segments.get(segments.size() - 1)));
intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname);
intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName);
startActivity(intent);
} else {
boolean local = false;
try {
URL baseURL = new URL(mRetrofit.getBaseURL());
if (baseURL.getHost().equalsIgnoreCase(uri.getHost())) {
local = true;
FetchPost.fetchPost(mExecutor, new Handler(), mRetrofit.getRetrofit(), segments.get(segments.size() - 1), mAccessToken, postEnricher, new FetchPost.FetchPostListener() {
@Override
public void fetchPostSuccess(Post post) {
Intent intent = new Intent(LinkResolverActivity.this, ViewPostDetailActivity.class);
intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, post.getId());
intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname);
intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName);
startActivity(intent);
}
@Override
public void fetchPostFailed() {
Toast.makeText(getApplicationContext(), R.string.could_not_resolve_link, Toast.LENGTH_SHORT).show();
finish();
}
});
}
} catch (MalformedURLException e) {
Toast.makeText(getApplicationContext(), R.string.could_not_resolve_link, Toast.LENGTH_SHORT).show();
finish();
}
if (!local) {
mObjectResolver.resolvePost(uri.toString(), mAccessToken, new ObjectResolver.ObjectResolverListener() {
@Override
public void onResolveObjectSuccess(Object p) {
Post post = (Post) p;
Intent intent = new Intent(LinkResolverActivity.this, ViewPostDetailActivity.class);
intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, post.getId());
intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname);
intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName);
startActivity(intent);
}
@Override
public void onResolveObjectFailed() {
Toast.makeText(getApplicationContext(), R.string.could_not_resolve_link, Toast.LENGTH_SHORT).show();
finish();
}
});
}
}
} else if (uri.toString().matches(COMMENT_PATTERN)) {
if (mAccessToken == null) {
mRetrofit.setBaseURL(uri.getScheme() + "://" + uri.getHost() + "/");
FetchComment.fetchSingleComment(mRetrofit.getRetrofit(), null, Integer.parseInt(segments.get(segments.size() - 1)), new FetchComment.FetchCommentListener() {
@Override
public void onFetchCommentSuccess(ArrayList<Comment> comments, Integer parentId, ArrayList<Integer> moreChildrenIds) {
Intent intent = new Intent(LinkResolverActivity.this, ViewPostDetailActivity.class);
Comment comment = comments.get(0);
intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, comment.getPostId());
intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname);
intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName);
intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_ID, comment.getId());
intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_PARENT_ID, comment.getParentId());
startActivity(intent);
}
@Override
public void onFetchCommentFailed() {
Toast.makeText(getApplicationContext(), R.string.could_not_resolve_link, Toast.LENGTH_SHORT).show();
finish();
}
});
} else {
boolean local = false;
try {
URL baseURL = new URL(mRetrofit.getBaseURL());
if (baseURL.getHost().equalsIgnoreCase(uri.getHost())) {
local = true;
FetchComment.fetchSingleComment(mRetrofit.getRetrofit(), mAccessToken, Integer.parseInt(segments.get(segments.size() - 1)), new FetchComment.FetchCommentListener() {
@Override
public void onFetchCommentSuccess(ArrayList<Comment> comments, Integer parentId, ArrayList<Integer> moreChildrenIds) {
Intent intent = new Intent(LinkResolverActivity.this, ViewPostDetailActivity.class);
Comment comment = comments.get(0);
intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, comment.getPostId());
intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname);
intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName);
intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_ID, comment.getId());
intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_PARENT_ID, comment.getParentId());
startActivity(intent);
}
@Override
public void onFetchCommentFailed() {
Toast.makeText(getApplicationContext(), R.string.could_not_resolve_link, Toast.LENGTH_SHORT).show();
finish();
}
});
}
} catch (MalformedURLException e) {
Toast.makeText(getApplicationContext(), R.string.could_not_resolve_link, Toast.LENGTH_SHORT).show();
finish();
}
if (!local) {
mObjectResolver.resolveComment(uri.toString(), mAccessToken, new ObjectResolver.ObjectResolverListener() {
@Override
public void onResolveObjectSuccess(Object c) {
Comment comment = (Comment) c;
Intent intent = new Intent(LinkResolverActivity.this, ViewPostDetailActivity.class);
intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, comment.getPostId());
intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname);
intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName);
intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_ID, comment.getId());
intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_PARENT_ID, comment.getParentId());
startActivity(intent);
}
@Override
public void onResolveObjectFailed() {
Toast.makeText(getApplicationContext(), R.string.could_not_resolve_link, Toast.LENGTH_SHORT).show();
finish();
}
});
}
}
} else if (authority.equals("v.redd.it")) {
Intent intent = new Intent(this, ViewVideoActivity.class);
intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_V_REDD_IT);
intent.putExtra(ViewVideoActivity.EXTRA_V_REDD_IT_URL, uri.toString());
startActivity(intent);
} else if (authority.contains("reddit.com") || authority.contains("redd.it") || authority.contains("reddit.app")) {
if (authority.equals("reddit.app.link") && path.isEmpty()) {
String redirect = uri.getQueryParameter("$og_redirect");
if (redirect != null) {
handleUri(Uri.parse(redirect));
} else {
deepLinkError(uri);
}
} else if (path.isEmpty()) {
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
} else if (path.equals("/report")) {
openInWebView(uri);
} else if (path.matches(POST_PATTERN) || path.matches(POST_PATTERN_2)) {
int commentsIndex = segments.lastIndexOf("comments");
if (commentsIndex >= 0 && commentsIndex < segments.size() - 1) {
Intent intent = new Intent(this, ViewPostDetailActivity.class);
intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, segments.get(commentsIndex + 1));
intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname);
intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName);
startActivity(intent);
} else {
deepLinkError(uri);
}
} else if (path.matches(POST_PATTERN_3)) {
Intent intent = new Intent(this, ViewPostDetailActivity.class);
intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, path.substring(1));
intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname);
intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName);
startActivity(intent);
} else if (path.matches(COMMENT_PATTERN)) {
int commentsIndex = segments.lastIndexOf("comments");
if (commentsIndex >= 0 && commentsIndex < segments.size() - 1) {
Intent intent = new Intent(this, ViewPostDetailActivity.class);
intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, segments.get(commentsIndex + 1));
intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_ID, segments.get(segments.size() - 1));
intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname);
intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName);
startActivity(intent);
} else {
deepLinkError(uri);
}
} else if (path.matches(WIKI_PATTERN)) {
String[] pathSegments = path.split("/");
String wikiPage;
if (pathSegments.length == 4) {
wikiPage = "index";
} else {
int lengthThroughWiki = 0;
for (int i = 1; i <= 3; ++i) {
lengthThroughWiki += pathSegments[i].length() + 1;
}
wikiPage = path.substring(lengthThroughWiki);
}
Intent intent = new Intent(this, WikiActivity.class);
intent.putExtra(WikiActivity.EXTRA_SUBREDDIT_NAME, segments.get(1));
intent.putExtra(WikiActivity.EXTRA_WIKI_PATH, wikiPage);
startActivity(intent);
} else if (path.matches(SIDEBAR_PATTERN)) {
Intent intent = new Intent(this, ViewSubredditDetailActivity.class);
intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, path.substring(3, path.length() - 14));
intent.putExtra(ViewSubredditDetailActivity.EXTRA_VIEW_SIDEBAR, true);
startActivity(intent);
} else if (path.matches(MULTIREDDIT_PATTERN)) {
Intent intent = new Intent(this, ViewMultiRedditDetailActivity.class);
intent.putExtra(ViewMultiRedditDetailActivity.EXTRA_MULTIREDDIT_PATH, path);
startActivity(intent);
} else if (path.matches(MULTIREDDIT_PATTERN_2)) {
String subredditName = path.substring(3);
Intent intent = new Intent(this, ViewSubredditDetailActivity.class);
intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, subredditName);
intent.putExtra(ViewSubredditDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname);
intent.putExtra(ViewSubredditDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName);
startActivity(intent);
} else if (authority.equals("redd.it") && path.matches(REDD_IT_POST_PATTERN)) {
Intent intent = new Intent(this, ViewPostDetailActivity.class);
intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, path.substring(1));
startActivity(intent);
} else {
deepLinkError(uri);
}
} else if (authority.equals("click.redditmail.com")) {
if (path.startsWith("/CL0/")) {
handleUri(Uri.parse(path.substring("/CL0/".length())));
@@ -343,7 +430,7 @@ public class LinkResolverActivity extends AppCompatActivity {
String authority = uri.getAuthority();
if(authority != null && (authority.contains("reddit.com") || authority.contains("redd.it") || authority.contains("reddit.app.link"))) {
openInCustomTabs(uri, pm, false);
openInBrowser(uri, pm, false);
return;
}

View File

@@ -6,16 +6,18 @@ import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.util.Log;
import android.util.Patterns;
import android.view.InflateException;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.AppCompatAutoCompleteTextView;
import androidx.appcompat.widget.Toolbar;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
@@ -26,6 +28,10 @@ import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import javax.inject.Inject;
@@ -38,11 +44,17 @@ import eu.toldi.infinityforlemmy.Infinity;
import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.RedditDataRoomDatabase;
import eu.toldi.infinityforlemmy.RetrofitHolder;
import eu.toldi.infinityforlemmy.adapters.CustomArrayAdapter;
import eu.toldi.infinityforlemmy.apis.LemmyAPI;
import eu.toldi.infinityforlemmy.asynctasks.ParseAndInsertNewAccount;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.customviews.slidr.Slidr;
import eu.toldi.infinityforlemmy.dto.AccountLoginDTO;
import eu.toldi.infinityforlemmy.lemmyverse.FetchInstancesListener;
import eu.toldi.infinityforlemmy.lemmyverse.LemmyInstance;
import eu.toldi.infinityforlemmy.lemmyverse.LemmyVerseFetchInstances;
import eu.toldi.infinityforlemmy.site.FetchSiteInfo;
import eu.toldi.infinityforlemmy.site.SiteInfo;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import eu.toldi.infinityforlemmy.utils.Utils;
import retrofit2.Call;
@@ -55,6 +67,9 @@ public class LoginActivity extends BaseActivity {
private static final String ENABLE_DOM_STATE = "EDS";
private static final String IS_AGREE_TO_USER_AGGREMENT_STATE = "IATUAS";
public static final String EXTRA_INPUT_USERNAME = "INPUT_USERNAME";
public static final String EXTRA_INPUT_INSTANCE = "INPUT_INSTANCE";
@BindView(R.id.coordinator_layout_login_activity)
CoordinatorLayout coordinatorLayout;
@BindView(R.id.appbar_layout_login_activity)
@@ -65,7 +80,7 @@ public class LoginActivity extends BaseActivity {
TextView twoFAInfoTextView;
@BindView(R.id.instance_url_input)
TextInputEditText instance_input;
AppCompatAutoCompleteTextView instance_input;
@BindView(R.id.username_input)
TextInputEditText username_input;
@BindView(R.id.user_password_input)
@@ -82,9 +97,11 @@ public class LoginActivity extends BaseActivity {
@Inject
@Named("no_oauth")
RetrofitHolder mRetrofit;
@Inject
@Named("oauth")
Retrofit mOauthRetrofit;
@Named("lemmyVerse")
Retrofit mLemmyVerseRetrofit;
@Inject
RedditDataRoomDatabase mRedditDataRoomDatabase;
@Inject
@@ -135,17 +152,45 @@ public class LoginActivity extends BaseActivity {
isAgreeToUserAgreement = savedInstanceState.getBoolean(IS_AGREE_TO_USER_AGGREMENT_STATE);
}
// Get username and instance from intent
Intent intent = getIntent();
String username_intent = intent.getStringExtra(EXTRA_INPUT_USERNAME);
String instance_intent = intent.getStringExtra(EXTRA_INPUT_INSTANCE);
if (username_intent != null) {
username_input.setText(username_intent);
}
if (instance_intent != null) {
instance_input.setText(instance_intent);
}
LemmyVerseFetchInstances.INSTANCE.fetchInstances(mLemmyVerseRetrofit, new FetchInstancesListener() {
@Override
public void onFetchInstancesSuccess(@NonNull List<LemmyInstance> instances) {
ArrayList<String> instanceNames = new ArrayList<>();
for (LemmyInstance instance : instances) {
instanceNames.add(instance.getFqdn());
}
ArrayAdapter<String> adapter = new CustomArrayAdapter(LoginActivity.this, android.R.layout.simple_dropdown_item_1line, instanceNames, mCustomThemeWrapper);
instance_input.setAdapter(adapter);
}
});
loginButton.setOnClickListener(view -> {
Log.i("LoginActivity", "Login button clicked");
if (!checkFields())
return;
loginButton.setEnabled(false);
progressBar.setVisibility(ProgressBar.VISIBLE);
String username = username_input.getText().toString().trim();
String instance = correctURL(instance_input.getText().toString().trim());
if (!Patterns.WEB_URL.matcher(instance).matches()) {
instance_input.setError("Invalid instance URL");
try {
URL urlObj = new URL(instance);
instance = urlObj.getProtocol() + "://" + urlObj.getHost() + "/";
} catch (MalformedURLException e) {
instance_input.setError("Invalid URL");
Toast.makeText(LoginActivity.this, "Invalid instance URL", Toast.LENGTH_SHORT).show();
loginButton.setEnabled(true);
progressBar.setVisibility(ProgressBar.GONE);
return;
}
Log.i("LoginActivity", "Instance: " + instance);
@@ -153,6 +198,7 @@ public class LoginActivity extends BaseActivity {
mRetrofit.setBaseURL(instance);
LemmyAPI api = mRetrofit.getRetrofit().create(LemmyAPI.class);
Call<String> accessTokenCall = api.userLogin(accountLoginDTO);
String finalInstance = instance;
accessTokenCall.enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
@@ -171,22 +217,51 @@ public class LoginActivity extends BaseActivity {
try {
JSONObject responseJSON = new JSONObject(accountResponse);
String accessToken = responseJSON.getString("jwt");
mRetrofit.setAccessToken(null);
FetchMyInfo.fetchAccountInfo(mRetrofit.getRetrofit(), mRedditDataRoomDatabase, username,
accessToken, new FetchMyInfo.FetchMyInfoListener() {
@Override
public void onFetchMyInfoSuccess(String name, String display_name, String profileImageUrl, String bannerImageUrl) {
FetchSiteInfo.fetchSiteInfo(mRetrofit.getRetrofit(), accessToken, new FetchSiteInfo.FetchSiteInfoListener() {
@Override
public void onFetchSiteInfoSuccess(SiteInfo siteInfo) {
boolean canDownvote = siteInfo.isEnable_downvotes();
ParseAndInsertNewAccount.parseAndInsertNewAccount(mExecutor, new Handler(), name, display_name, accessToken, profileImageUrl, bannerImageUrl, authCode, finalInstance, canDownvote, mRedditDataRoomDatabase.accountDao(),
() -> {
Intent resultIntent = new Intent();
setResult(Activity.RESULT_OK, resultIntent);
finish();
});
mCurrentAccountSharedPreferences.edit().putBoolean(SharedPreferencesUtils.CAN_DOWNVOTE, canDownvote).apply();
String[] version = siteInfo.getVersion().split("\\.");
if (version.length > 0) {
Log.d("SwitchAccount", "Lemmy Version: " + version[0] + "." + version[1]);
int majorVersion = Integer.parseInt(version[0]);
int minorVersion = Integer.parseInt(version[1]);
if (majorVersion > 0 || (majorVersion == 0 && minorVersion >= 19)) {
mRetrofit.setAccessToken(accessToken);
mCurrentAccountSharedPreferences.edit().putBoolean(SharedPreferencesUtils.BEARER_TOKEN_AUTH, true).apply();
}
}
}
@Override
public void onFetchSiteInfoFailed() {
ParseAndInsertNewAccount.parseAndInsertNewAccount(mExecutor, new Handler(), name,display_name, accessToken, profileImageUrl, bannerImageUrl, authCode, finalInstance,true, mRedditDataRoomDatabase.accountDao(),
() -> {
Intent resultIntent = new Intent();
setResult(Activity.RESULT_OK, resultIntent);
finish();
});
mCurrentAccountSharedPreferences.edit().putBoolean(SharedPreferencesUtils.CAN_DOWNVOTE, true).apply();
}
});
mCurrentAccountSharedPreferences.edit().putString(SharedPreferencesUtils.ACCESS_TOKEN, accessToken)
.putString(SharedPreferencesUtils.ACCOUNT_NAME, display_name)
.putString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, name)
.putString(SharedPreferencesUtils.ACCOUNT_INSTANCE,instance)
.putString(SharedPreferencesUtils.ACCOUNT_INSTANCE,finalInstance)
.putString(SharedPreferencesUtils.ACCOUNT_IMAGE_URL, profileImageUrl).apply();
ParseAndInsertNewAccount.parseAndInsertNewAccount(mExecutor, new Handler(), name,display_name, accessToken, profileImageUrl, bannerImageUrl, authCode,instance, mRedditDataRoomDatabase.accountDao(),
() -> {
Intent resultIntent = new Intent();
setResult(Activity.RESULT_OK, resultIntent);
finish();
});
}
@Override
@@ -240,6 +315,26 @@ public class LoginActivity extends BaseActivity {
});
}
private boolean checkFields() {
boolean result = true;
Editable username = username_input.getText();
Editable password = password_input.getText();
Editable instance = instance_input.getText();
if(instance == null || instance.toString().isEmpty()) {
instance_input.setError(getString(R.string.instance_cannot_be_empty));
result = false;
}
if(username == null || username.toString().isEmpty()) {
username_input.setError(getString(R.string.username_cannot_be_empty));
result = false;
}
if(password == null || password.toString().isEmpty()) {
password_input.setError(getString(R.string.password_cannot_be_empty));
result = false;
}
return result;
}
private static String correctURL(String url) {
if (url == null || url.isEmpty()) {
throw new IllegalArgumentException("URL cannot be null or empty");
@@ -281,6 +376,7 @@ public class LoginActivity extends BaseActivity {
if (typeface != null) {
twoFAInfoTextView.setTypeface(typeface);
}
instance_input.setTextColor(mCustomThemeWrapper.getPrimaryTextColor());
}
@Override

View File

@@ -33,6 +33,7 @@ import androidx.appcompat.app.AppCompatDelegate;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.splashscreen.SplashScreen;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
@@ -107,12 +108,14 @@ import eu.toldi.infinityforlemmy.events.ChangeLockBottomAppBarEvent;
import eu.toldi.infinityforlemmy.events.ChangeNSFWEvent;
import eu.toldi.infinityforlemmy.events.ChangeRequireAuthToAccountSectionEvent;
import eu.toldi.infinityforlemmy.events.ChangeShowAvatarOnTheRightInTheNavigationDrawerEvent;
import eu.toldi.infinityforlemmy.events.ChangeUseCircularFabEvent;
import eu.toldi.infinityforlemmy.events.RecreateActivityEvent;
import eu.toldi.infinityforlemmy.events.SwitchAccountEvent;
import eu.toldi.infinityforlemmy.fragments.PostFragment;
import eu.toldi.infinityforlemmy.message.ReadMessage;
import eu.toldi.infinityforlemmy.multireddit.MultiReddit;
import eu.toldi.infinityforlemmy.multireddit.MultiRedditViewModel;
import eu.toldi.infinityforlemmy.post.MarkPostAsRead;
import eu.toldi.infinityforlemmy.post.Post;
import eu.toldi.infinityforlemmy.post.PostPagingSource;
import eu.toldi.infinityforlemmy.readpost.InsertReadPost;
@@ -213,6 +216,10 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
CustomThemeWrapper mCustomThemeWrapper;
@Inject
Executor mExecutor;
@Inject
MarkPostAsRead markPostAsRead;
private FragmentManager fragmentManager;
private SectionsPagerAdapter sectionsPagerAdapter;
private NavigationDrawerRecyclerViewMergedAdapter adapter;
@@ -225,9 +232,11 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
private boolean mFetchUserInfoSuccess = false;
private boolean mFetchSubscriptionsSuccess = false;
private boolean mDrawerOnAccountSwitch = false;
private String mMessageFullname;
private int mMessageFullname;
private String mNewAccountName;
private boolean hideFab;
private boolean useCircularFab;
private boolean showBottomAppBar;
private int mBackButtonAction;
private boolean mLockBottomAppBar;
@@ -239,8 +248,12 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
private int fabOption;
private int inboxCount;
private boolean mBearerTokenUsed = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
SplashScreen.installSplashScreen(this);
((Infinity) getApplication()).getAppComponent().inject(this);
setTheme(R.style.AppTheme_NoActionBarWithTransparentStatusBar);
@@ -254,6 +267,7 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
ButterKnife.bind(this);
hideFab = mSharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_FAB_IN_POST_FEED, false);
useCircularFab = mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false);
showBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.BOTTOM_APP_BAR_KEY, false);
navigationWrapper = new NavigationWrapper(findViewById(R.id.bottom_app_bar_bottom_app_bar), findViewById(R.id.linear_layout_bottom_app_bar),
@@ -327,11 +341,13 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
fragmentManager = getSupportFragmentManager();
mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null);
mRetrofit.setAccessToken(mAccessToken);
mBearerTokenUsed = mCurrentAccountSharedPreferences.getBoolean(SharedPreferencesUtils.BEARER_TOKEN_AUTH, true);
mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null);
mAccountQualifiedName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, null);
String instance = (mAccessToken == null) ? mSharedPreferences.getString(SharedPreferencesUtils.ANONYMOUS_ACCOUNT_INSTANCE, APIUtils.API_BASE_URI) : mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_INSTANCE, null);
if(instance != null) {
if (instance != null) {
mRetrofit.setBaseURL(instance);
}
@@ -339,11 +355,11 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
mFetchUserInfoSuccess = savedInstanceState.getBoolean(FETCH_USER_INFO_STATE);
mFetchSubscriptionsSuccess = savedInstanceState.getBoolean(FETCH_SUBSCRIPTIONS_STATE);
mDrawerOnAccountSwitch = savedInstanceState.getBoolean(DRAWER_ON_ACCOUNT_SWITCH_STATE);
mMessageFullname = savedInstanceState.getString(MESSAGE_FULLNAME_STATE);
mMessageFullname = savedInstanceState.getInt(MESSAGE_FULLNAME_STATE);
mNewAccountName = savedInstanceState.getString(NEW_ACCOUNT_NAME_STATE);
inboxCount = savedInstanceState.getInt(INBOX_COUNT_STATE);
} else {
mMessageFullname = getIntent().getStringExtra(EXTRA_MESSSAGE_FULLNAME);
mMessageFullname = getIntent().getIntExtra(EXTRA_MESSSAGE_FULLNAME, 0);
mNewAccountName = getIntent().getStringExtra(EXTRA_NEW_ACCOUNT_NAME);
}
@@ -356,9 +372,12 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
super.onResume();
if (mAccessToken == null) {
String instancePreference = mSharedPreferences.getString(SharedPreferencesUtils.ANONYMOUS_ACCOUNT_INSTANCE, APIUtils.API_BASE_URI);
if (!mRetrofit.getBaseURL().equalsIgnoreCase(instancePreference)) {
if (!instancePreference.startsWith(mRetrofit.getBaseURL())) {
mRetrofit.setBaseURL(instancePreference);
this.recreate();
}
} else {
checkUserToken();
}
}
@@ -380,7 +399,7 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
navigationView.setBackgroundColor(backgroundColor);
applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, collapsingToolbarLayout, toolbar);
applyTabLayoutTheme(tabLayout);
applyFABTheme(navigationWrapper.floatingActionButton);
applyFABTheme(navigationWrapper.floatingActionButton, useCircularFab);
}
private void initializeNotificationAndBindView() {
@@ -472,7 +491,6 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
Intent intent = new Intent(this, ViewUserDetailActivity.class);
intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mAccountName);
intent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, mAccountQualifiedName);
intent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, mAccountName);
startActivity(intent);
break;
}
@@ -799,21 +817,19 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
adapter = new NavigationDrawerRecyclerViewMergedAdapter(this, mSharedPreferences,
mNsfwAndSpoilerSharedPreferences, mNavigationDrawerSharedPreferences, mSecuritySharedPreferences,
mCustomThemeWrapper, mAccountName, new NavigationDrawerRecyclerViewMergedAdapter.ItemClickListener() {
@Override
public void onMenuClick(int stringId) {
Intent intent = null;
if (stringId == R.string.profile) {
intent = new Intent(MainActivity.this, ViewUserDetailActivity.class);
intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mAccountName);
intent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, mAccountQualifiedName);
} else if (stringId == R.string.subscriptions) {
intent = new Intent(MainActivity.this, SubscribedThingListingActivity.class);
} else if (stringId == R.string.multi_reddit) {
mCustomThemeWrapper, mAccountName, mAccountQualifiedName, new NavigationDrawerRecyclerViewMergedAdapter.ItemClickListener() {
@Override
public void onMenuClick(int stringId) {
Intent intent = null;
if (stringId == R.string.profile) {
intent = new Intent(MainActivity.this, ViewUserDetailActivity.class);
intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mAccountName);
intent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, mAccountQualifiedName);
} else if (stringId == R.string.subscriptions) {
intent = new Intent(MainActivity.this, SubscribedThingListingActivity.class);
} else if (stringId == R.string.multi_reddit) {
intent = new Intent(MainActivity.this, SubscribedThingListingActivity.class);
intent.putExtra(SubscribedThingListingActivity.EXTRA_SHOW_MULTIREDDITS, true);
} else if (stringId == R.string.history) {
intent = new Intent(MainActivity.this, HistoryActivity.class);
} else if (stringId == R.string.trending) {
intent = new Intent(MainActivity.this, TrendingActivity.class);
} else if (stringId == R.string.upvoted) {
@@ -874,7 +890,11 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
});
} else if (stringId == R.string.anonymous_account_instance) {
changeAnonymousAccountInstance();
}
} else if (stringId == R.string.blocks) {
intent = new Intent(MainActivity.this, BlockedThingListingActivity.class);
} else if (stringId == R.string.instance_info) {
intent = new Intent(MainActivity.this, InstanceInfoActivity.class);
}
if (intent != null) {
startActivity(intent);
}
@@ -911,7 +931,7 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
sectionsPagerAdapter = new SectionsPagerAdapter(this, tabCount, mShowFavoriteMultiReddits,
mShowMultiReddits, mShowFavoriteSubscribedSubreddits, mShowSubscribedSubreddits);
viewPager2.setAdapter(sectionsPagerAdapter);
viewPager2.setOffscreenPageLimit(1);
viewPager2.setOffscreenPageLimit(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT);
viewPager2.setUserInputEnabled(!mDisableSwipingBetweenTabs);
if (mMainActivityTabsSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_TAB_NAMES, true)) {
if (mShowFavoriteMultiReddits || mShowMultiReddits || mShowFavoriteSubscribedSubreddits || mShowSubscribedSubreddits) {
@@ -922,7 +942,7 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> {
switch (position) {
case 0:
Utils.setTitleWithCustomFontToTab(typeface, tab, mMainActivityTabsSharedPreferences.getString((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_1_TITLE, getString(R.string.home)));
Utils.setTitleWithCustomFontToTab(typeface, tab, mMainActivityTabsSharedPreferences.getString((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_1_TITLE, getString(R.string.subscribed_feed)));
break;
case 1:
Utils.setTitleWithCustomFontToTab(typeface, tab, mMainActivityTabsSharedPreferences.getString((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_2_TITLE, getString(R.string.local)));
@@ -1001,12 +1021,12 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
sectionsPagerAdapter.setSubscribedSubreddits(subscribedSubredditData);
}
});
/*subscribedSubredditViewModel.getAllFavoriteSubscribedSubreddits().observe(this, subscribedSubredditData -> {
subscribedSubredditViewModel.getAllFavoriteSubscribedSubreddits().observe(this, subscribedSubredditData -> {
adapter.setFavoriteSubscribedSubreddits(subscribedSubredditData);
if (mShowFavoriteSubscribedSubreddits && sectionsPagerAdapter != null) {
sectionsPagerAdapter.setFavoriteSubscribedSubreddits(subscribedSubredditData);
}
});*/
});
accountViewModel = new ViewModelProvider(this,
new AccountViewModel.Factory(mRedditDataRoomDatabase)).get(AccountViewModel.class);
@@ -1020,11 +1040,11 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
loadUserData();
if (mAccessToken != null) {
if (mMessageFullname != null) {
if (mMessageFullname != 0) {
ReadMessage.readMessage(mOauthRetrofit, mAccessToken, mMessageFullname, new ReadMessage.ReadMessageListener() {
@Override
public void readSuccess() {
mMessageFullname = null;
mMessageFullname = 0;
}
@Override
@@ -1065,22 +1085,59 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
}
}
private void checkUserToken() {
if (mBearerTokenUsed) {
FetchUserData.validateAuthToken(mRetrofit.getRetrofit(), new FetchUserData.ValidateAuthTokenListener() {
@Override
public void onValidateAuthTokenSuccess() {
}
@Override
public void onValidateAuthTokenFailed() {
// Alert user that the token is invalid and they need to re-login
new MaterialAlertDialogBuilder(MainActivity.this, R.style.MaterialAlertDialogTheme)
.setTitle(R.string.token_expired)
.setMessage(R.string.token_expired_message)
.setPositiveButton(R.string.ok, (dialogInterface, i) -> {
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
// Username without instance
String username = mAccountName.substring(0, mAccountQualifiedName.indexOf("@"));
intent.putExtra(LoginActivity.EXTRA_INPUT_USERNAME, username);
intent.putExtra(LoginActivity.EXTRA_INPUT_INSTANCE, mRetrofit.getBaseURL());
startActivity(intent);
})
.setCancelable(false)
.show();
}
});
}
}
private void loadUserData() {
if (!mFetchUserInfoSuccess) {
FetchUserData.fetchUserData(mRedditDataRoomDatabase, mRetrofit.getRetrofit(), mAccessToken,
mAccountName, new FetchUserData.FetchUserDataListener() {
FetchUserData.fetchUnreadCount(mRetrofit.getRetrofit(), mAccessToken, new FetchUserData.FetchUserUnreadCountListener() {
@Override
public void onFetchUserDataSuccess(UserData userData, int inboxCount) {
public void onFetchUserUnreadCountSuccess(int inboxCount) {
MainActivity.this.inboxCount = inboxCount;
mAccountName = userData.getName();
mFetchUserInfoSuccess = true;
if (adapter != null) {
adapter.setInboxCount(inboxCount);
}
}
@Override
public void onFetchUserDataFailed() {
public void onFetchUserUnreadCountFailed() {
}
});
FetchUserData.fetchUserData(mRedditDataRoomDatabase, mRetrofit.getRetrofit(), mAccessToken,
mAccountName, new FetchUserData.FetchUserDataListener() {
@Override
public void onFetchUserDataSuccess(UserData userData, int inboxCount) {
mAccountName = userData.getName();
mFetchUserInfoSuccess = true;
}
@Override
public void onFetchUserDataFailed() {
mFetchUserInfoSuccess = false;
}
});
@@ -1172,7 +1229,7 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
outState.putBoolean(FETCH_USER_INFO_STATE, mFetchUserInfoSuccess);
outState.putBoolean(FETCH_SUBSCRIPTIONS_STATE, mFetchSubscriptionsSuccess);
outState.putBoolean(DRAWER_ON_ACCOUNT_SWITCH_STATE, mDrawerOnAccountSwitch);
outState.putString(MESSAGE_FULLNAME_STATE, mMessageFullname);
outState.putInt(MESSAGE_FULLNAME_STATE, mMessageFullname);
outState.putString(NEW_ACCOUNT_NAME_STATE, mNewAccountName);
outState.putInt(INBOX_COUNT_STATE, inboxCount);
}
@@ -1331,6 +1388,12 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
navigationWrapper.floatingActionButton.setVisibility(hideFab ? View.GONE : View.VISIBLE);
}
@Subscribe
public void onChangeUseCircularFab(ChangeUseCircularFabEvent event) {
useCircularFab = event.isUseCircularFab();
applyFABTheme(navigationWrapper.floatingActionButton, useCircularFab);
}
@Override
public void onLongPress() {
if (sectionsPagerAdapter != null) {
@@ -1376,10 +1439,6 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
goToUser();
break;
}
case FABMoreOptionsBottomSheetFragment.FAB_RANDOM: {
randomThing();
break;
}
case FABMoreOptionsBottomSheetFragment.FAB_HIDE_READ_POSTS: {
if (sectionsPagerAdapter != null) {
sectionsPagerAdapter.hideReadPosts();
@@ -1487,7 +1546,12 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
if (i == EditorInfo.IME_ACTION_DONE) {
Utils.hideKeyboard(this);
Intent subredditIntent = new Intent(this, ViewSubredditDetailActivity.class);
subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_COMMUNITY_FULL_NAME_KEY, thingEditText.getText().toString());
String communityName = thingEditText.getText().toString();
if (communityName.startsWith("!")) {
communityName = communityName.substring(1);
}
subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_COMMUNITY_FULL_NAME_KEY, communityName);
startActivity(subredditIntent);
return true;
}
@@ -1545,7 +1609,11 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
-> {
Utils.hideKeyboard(this);
Intent subredditIntent = new Intent(this, ViewSubredditDetailActivity.class);
subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_COMMUNITY_FULL_NAME_KEY, thingEditText.getText().toString());
String communityName = thingEditText.getText().toString();
if (communityName.startsWith("!")) {
communityName = communityName.substring(1);
}
subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_COMMUNITY_FULL_NAME_KEY, communityName);
startActivity(subredditIntent);
})
.setNegativeButton(R.string.cancel, (dialogInterface, i) -> {
@@ -1566,7 +1634,11 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
if (i == EditorInfo.IME_ACTION_DONE) {
Utils.hideKeyboard(this);
Intent userIntent = new Intent(this, ViewUserDetailActivity.class);
userIntent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, thingEditText.getText().toString());
String qualifiedName = thingEditText.getText().toString();
if (qualifiedName.startsWith("@")) {
qualifiedName = qualifiedName.substring(1);
}
userIntent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, qualifiedName);
startActivity(userIntent);
return true;
}
@@ -1579,7 +1651,11 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
-> {
Utils.hideKeyboard(this);
Intent userIntent = new Intent(this, ViewUserDetailActivity.class);
userIntent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, thingEditText.getText().toString());
String qualifiedName = thingEditText.getText().toString();
if (qualifiedName.startsWith("@")) {
qualifiedName = qualifiedName.substring(1);
}
userIntent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, qualifiedName);
startActivity(userIntent);
})
.setNegativeButton(R.string.cancel, (dialogInterface, i) -> {
@@ -1608,11 +1684,21 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
@Override
public void markPostAsRead(Post post) {
InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, mAccountName, post.getId());
markPostAsRead.markPostAsRead(post.getId(), mAccessToken, new MarkPostAsRead.MarkPostAsReadListener() {
@Override
public void onMarkPostAsReadSuccess() {
InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, mAccountQualifiedName, post.getId());
}
@Override
public void onMarkPostAsReadFailed() {
Toast.makeText(MainActivity.this, R.string.mark_post_as_read_failed, Toast.LENGTH_SHORT).show();
}
});
}
public void doNotShowRedditAPIInfoAgain() {
mInternalSharedPreferences.edit().putBoolean(SharedPreferencesUtils.DO_NOT_SHOW_REDDIT_API_INFO_AGAIN, true).apply();
mInternalSharedPreferences.edit().putBoolean(SharedPreferencesUtils.DO_NOT_SHOW_REDDIT_API_INFO_V2_AGAIN, true).apply();
}
private class SectionsPagerAdapter extends FragmentStateAdapter {

View File

@@ -8,6 +8,7 @@ import android.view.MenuItem;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.RecyclerView;
@@ -16,6 +17,7 @@ import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.List;
import java.util.concurrent.Executor;
import javax.inject.Inject;
@@ -26,13 +28,15 @@ import butterknife.ButterKnife;
import eu.toldi.infinityforlemmy.Infinity;
import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.RedditDataRoomDatabase;
import eu.toldi.infinityforlemmy.adapters.PostFilterRecyclerViewAdapter;
import eu.toldi.infinityforlemmy.adapters.PostFilterWithUsageRecyclerViewAdapter;
import eu.toldi.infinityforlemmy.bottomsheetfragments.PostFilterOptionsBottomSheetFragment;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.post.Post;
import eu.toldi.infinityforlemmy.postfilter.DeletePostFilter;
import eu.toldi.infinityforlemmy.postfilter.PostFilter;
import eu.toldi.infinityforlemmy.postfilter.PostFilterViewModel;
import eu.toldi.infinityforlemmy.postfilter.PostFilterWithUsageViewModel;
import eu.toldi.infinityforlemmy.postfilter.PostFilterWithUsage;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
public class PostFilterPreferenceActivity extends BaseActivity {
@@ -61,8 +65,8 @@ public class PostFilterPreferenceActivity extends BaseActivity {
CustomThemeWrapper customThemeWrapper;
@Inject
Executor executor;
public PostFilterViewModel postFilterViewModel;
private PostFilterRecyclerViewAdapter adapter;
public PostFilterWithUsageViewModel postFilterWithUsageViewModel;
private PostFilterWithUsageRecyclerViewAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -98,7 +102,7 @@ public class PostFilterPreferenceActivity extends BaseActivity {
}
});
adapter = new PostFilterRecyclerViewAdapter(this, customThemeWrapper, postFilter -> {
adapter = new PostFilterWithUsageRecyclerViewAdapter(this, customThemeWrapper, postFilter -> {
if (post != null) {
showPostFilterOptions(post, postFilter);
} else if (subredditName != null) {
@@ -116,10 +120,15 @@ public class PostFilterPreferenceActivity extends BaseActivity {
recyclerView.setAdapter(adapter);
postFilterViewModel = new ViewModelProvider(this,
new PostFilterViewModel.Factory(redditDataRoomDatabase)).get(PostFilterViewModel.class);
postFilterWithUsageViewModel = new ViewModelProvider(this,
new PostFilterWithUsageViewModel.Factory(redditDataRoomDatabase)).get(PostFilterWithUsageViewModel.class);
postFilterViewModel.getPostFilterListLiveData().observe(this, postFilters -> adapter.setPostFilterList(postFilters));
postFilterWithUsageViewModel.getPostFilterWithUsageListLiveData().observe(this, new Observer<List<PostFilterWithUsage>>() {
@Override
public void onChanged(List<PostFilterWithUsage> postFilterWithUsages) {
adapter.setPostFilterWithUsageList(postFilterWithUsages);
}
});
}
public void showPostFilterOptions(Post post, PostFilter postFilter) {
@@ -205,7 +214,7 @@ public class PostFilterPreferenceActivity extends BaseActivity {
@Override
protected void applyCustomTheme() {
applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, collapsingToolbarLayout, toolbar);
applyFABTheme(fab);
applyFABTheme(fab, sharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false));
coordinatorLayout.setBackgroundColor(customThemeWrapper.getBackgroundColor());
}

View File

@@ -39,6 +39,7 @@ import eu.toldi.infinityforlemmy.postfilter.PostFilter;
import eu.toldi.infinityforlemmy.postfilter.PostFilterUsage;
import eu.toldi.infinityforlemmy.postfilter.PostFilterUsageViewModel;
import eu.toldi.infinityforlemmy.postfilter.SavePostFilterUsage;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import eu.toldi.infinityforlemmy.utils.Utils;
public class PostFilterUsageListingActivity extends BaseActivity {
@@ -125,9 +126,9 @@ public class PostFilterUsageListingActivity extends BaseActivity {
}
private void editAndPostFilterUsageNameOfUsage(int type, String nameOfUsage) {
View dialogView = getLayoutInflater().inflate(R.layout.dialog_edit_post_filter_name_of_usage, null);
TextInputLayout textInputLayout = dialogView.findViewById(R.id.text_input_layout_edit_post_filter_name_of_usage_dialog);
TextInputEditText textInputEditText = dialogView.findViewById(R.id.text_input_edit_text_edit_post_filter_name_of_usage_dialog);
View dialogView = getLayoutInflater().inflate(R.layout.dialog_edit_post_or_comment_filter_name_of_usage, null);
TextInputLayout textInputLayout = dialogView.findViewById(R.id.text_input_layout_edit_post_or_comment_filter_name_of_usage_dialog);
TextInputEditText textInputEditText = dialogView.findViewById(R.id.text_input_edit_text_edit_post_or_comment_filter_name_of_usage_dialog);
int primaryTextColor = customThemeWrapper.getPrimaryTextColor();
textInputLayout.setBoxStrokeColor(primaryTextColor);
textInputLayout.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor));
@@ -206,7 +207,7 @@ public class PostFilterUsageListingActivity extends BaseActivity {
@Override
protected void applyCustomTheme() {
applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, collapsingToolbarLayout, toolbar);
applyFABTheme(fab);
applyFABTheme(fab, sharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false));
coordinatorLayout.setBackgroundColor(customThemeWrapper.getBackgroundColor());
}
}

View File

@@ -214,7 +214,7 @@ public class PostGalleryActivity extends BaseActivity implements FlairBottomShee
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mGlide = Glide.with(this);
mGlide = Glide.with(getApplication());
mPostingSnackbar = Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_INDEFINITE);
@@ -504,7 +504,7 @@ public class PostGalleryActivity extends BaseActivity implements FlairBottomShee
}
private void loadSubredditIcon() {
LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, subredditName, mAccessToken, mOauthRetrofit, mRetrofit.getRetrofit(), iconImageUrl -> {
LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, subredditName, mAccessToken, mRetrofit.getRetrofit(), iconImageUrl -> {
iconUrl = iconImageUrl;
displaySubredditIcon();
loadSubredditIconSuccessful = true;

View File

@@ -17,6 +17,7 @@ import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -25,6 +26,8 @@ import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;
@@ -43,6 +46,7 @@ import org.greenrobot.eventbus.Subscribe;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.Executor;
import javax.inject.Inject;
@@ -55,11 +59,16 @@ import eu.toldi.infinityforlemmy.Infinity;
import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.RedditDataRoomDatabase;
import eu.toldi.infinityforlemmy.RetrofitHolder;
import eu.toldi.infinityforlemmy.UploadImageEnabledActivity;
import eu.toldi.infinityforlemmy.UploadedImage;
import eu.toldi.infinityforlemmy.account.Account;
import eu.toldi.infinityforlemmy.adapters.MarkdownBottomBarRecyclerViewAdapter;
import eu.toldi.infinityforlemmy.asynctasks.LoadSubredditIcon;
import eu.toldi.infinityforlemmy.bottomsheetfragments.AccountChooserBottomSheetFragment;
import eu.toldi.infinityforlemmy.bottomsheetfragments.FlairBottomSheetFragment;
import eu.toldi.infinityforlemmy.bottomsheetfragments.UploadedImagesBottomSheetFragment;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed;
import eu.toldi.infinityforlemmy.events.SubmitImagePostEvent;
import eu.toldi.infinityforlemmy.events.SubmitVideoOrGifPostEvent;
import eu.toldi.infinityforlemmy.events.SwitchAccountEvent;
@@ -68,12 +77,13 @@ import eu.toldi.infinityforlemmy.subreddit.FetchSubredditData;
import eu.toldi.infinityforlemmy.subreddit.SubredditData;
import eu.toldi.infinityforlemmy.subscribedsubreddit.SubscribedSubredditData;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import eu.toldi.infinityforlemmy.utils.Utils;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
import pl.droidsonroids.gif.GifImageView;
import retrofit2.Retrofit;
public class PostImageActivity extends BaseActivity implements FlairBottomSheetFragment.FlairSelectionCallback,
AccountChooserBottomSheetFragment.AccountChooserListener {
UploadImageEnabledActivity, AccountChooserBottomSheetFragment.AccountChooserListener {
static final String EXTRA_SUBREDDIT_NAME = "ESN";
@@ -92,6 +102,9 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF
private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 0;
private static final int PICK_IMAGE_REQUEST_CODE = 1;
private static final int CAPTURE_IMAGE_REQUEST_CODE = 2;
private static final int PICK_IMAGE_REQUEST_CODE_2 = 100;
private static final int CAPTURE_IMAGE_REQUEST_CODE_2 = 200;
private static final String COMMUNITY_DATA_STATE = "CDS";
@BindView(R.id.coordinator_layout_post_image_activity)
@@ -153,6 +166,11 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF
@Inject
@Named("current_account")
SharedPreferences mCurrentAccountSharedPreferences;
@BindView(R.id.post_text_content_edit_text_post_text_activity)
EditText contentEditText;
@BindView(R.id.markdown_bottom_bar_recycler_view_post_text_activity)
RecyclerView markdownBottomBarRecyclerView;
@Inject
CustomThemeWrapper mCustomThemeWrapper;
@Inject
@@ -184,6 +202,9 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF
private FlairBottomSheetFragment flairSelectionBottomSheetFragment;
private Snackbar mPostingSnackbar;
private Uri capturedImageUri;
private ArrayList<UploadedImage> uploadedImages = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
((Infinity) getApplication()).getAppComponent().inject(this);
@@ -207,7 +228,7 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mGlide = Glide.with(this);
mGlide = Glide.with(getApplication());
mPostingSnackbar = Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_INDEFINITE);
@@ -376,6 +397,30 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF
imageView.setVisibility(View.GONE);
constraintLayout.setVisibility(View.VISIBLE);
});
MarkdownBottomBarRecyclerViewAdapter adapter = new MarkdownBottomBarRecyclerViewAdapter(
mCustomThemeWrapper, new MarkdownBottomBarRecyclerViewAdapter.ItemClickListener() {
@Override
public void onClick(int item) {
MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener(
PostImageActivity.this, contentEditText, item);
}
@Override
public void onUploadImage() {
Utils.hideKeyboard(PostImageActivity.this);
UploadedImagesBottomSheetFragment fragment = new UploadedImagesBottomSheetFragment();
Bundle arguments = new Bundle();
arguments.putParcelableArrayList(UploadedImagesBottomSheetFragment.EXTRA_UPLOADED_IMAGES,
uploadedImages);
fragment.setArguments(arguments);
fragment.show(getSupportFragmentManager(), fragment.getTag());
}
});
markdownBottomBarRecyclerView.setLayoutManager(new LinearLayoutManagerBugFixed(this,
LinearLayoutManager.HORIZONTAL, false));
markdownBottomBarRecyclerView.setAdapter(adapter);
}
private void loadCurrentAccount() {
@@ -430,8 +475,11 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF
nsfwTextView.setTextColor(primaryTextColor);
titleEditText.setTextColor(primaryTextColor);
titleEditText.setHintTextColor(secondaryTextColor);
applyFABTheme(captureFab);
applyFABTheme(selectFromLibraryFab);
contentEditText.setTextColor(primaryTextColor);
contentEditText.setHintTextColor(secondaryTextColor);
boolean circleFab = mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false);
applyFABTheme(captureFab, circleFab);
applyFABTheme(selectFromLibraryFab, circleFab);
selectAgainTextView.setTextColor(mCustomThemeWrapper.getColorAccent());
if (typeface != null) {
subredditNameTextView.setTypeface(typeface);
@@ -441,6 +489,10 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF
titleEditText.setTypeface(typeface);
selectAgainTextView.setTypeface(typeface);
}
if (contentTypeface != null) {
contentEditText.setTypeface(contentTypeface);
}
}
private void loadImage() {
@@ -465,7 +517,7 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF
}
private void loadSubredditIcon() {
LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, subredditName, mAccessToken, mOauthRetrofit, mRetrofit.getRetrofit(), iconImageUrl -> {
LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, communityData.getQualified_name(), mAccessToken, mRetrofit.getRetrofit(), iconImageUrl -> {
iconUrl = iconImageUrl;
displaySubredditIcon();
loadSubredditIconSuccessful = true;
@@ -544,6 +596,7 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF
intent.putExtra(SubmitPostService.EXTRA_ACCOUNT, selectedAccount);
intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, communityData.getId());
intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString());
intent.putExtra(SubmitPostService.EXTRA_BODY, contentEditText.getText().toString());
intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair);
intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler);
intent.putExtra(SubmitPostService.EXTRA_IS_NSFW, isNSFW);
@@ -626,6 +679,16 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF
if (resultCode == RESULT_OK) {
loadImage();
}
} else if (requestCode == PICK_IMAGE_REQUEST_CODE_2) {
if (data == null) {
Toast.makeText(PostImageActivity.this, R.string.error_getting_image, Toast.LENGTH_LONG).show();
return;
}
Utils.uploadImageToReddit(this, mExecutor, mRetrofit,
mAccessToken, contentEditText, coordinatorLayout, data.getData(), uploadedImages);
} else if (requestCode == CAPTURE_IMAGE_REQUEST_CODE_2) {
Utils.uploadImageToReddit(this, mExecutor, mRetrofit,
mAccessToken, contentEditText, coordinatorLayout, capturedImageUri, uploadedImages);
}
}
@@ -705,4 +768,37 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF
}
}
}
@Override
public void uploadImage() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
getResources().getString(R.string.select_from_gallery)), PICK_IMAGE_REQUEST_CODE_2);
}
@Override
public void captureImage() {
Intent pictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
capturedImageUri = FileProvider.getUriForFile(this, "eu.toldi.infinityforlemmy.provider",
File.createTempFile("captured_image", ".jpg", getExternalFilesDir(Environment.DIRECTORY_PICTURES)));
pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, capturedImageUri);
startActivityForResult(pictureIntent, CAPTURE_IMAGE_REQUEST_CODE_2);
} catch (IOException ex) {
Toast.makeText(this, R.string.error_creating_temp_file, Toast.LENGTH_SHORT).show();
} catch (ActivityNotFoundException e) {
Toast.makeText(this, R.string.no_camera_available, Toast.LENGTH_SHORT).show();
}
}
@Override
public void insertImageUrl(UploadedImage uploadedImage) {
int start = Math.max(contentEditText.getSelectionStart(), 0);
int end = Math.max(contentEditText.getSelectionEnd(), 0);
contentEditText.getText().replace(Math.min(start, end), Math.max(start, end),
"![" + uploadedImage.imageName + "](" + uploadedImage.imageUrl + ")",
0, "![]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length());
}
}

View File

@@ -1,11 +1,15 @@
package eu.toldi.infinityforlemmy.activities;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore;
import android.view.Menu;
import android.view.MenuItem;
import android.webkit.URLUtil;
@@ -19,6 +23,9 @@ import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;
@@ -34,6 +41,9 @@ import com.libRG.CustomTextView;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.Executor;
import javax.inject.Inject;
@@ -46,12 +56,17 @@ import eu.toldi.infinityforlemmy.Infinity;
import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.RedditDataRoomDatabase;
import eu.toldi.infinityforlemmy.RetrofitHolder;
import eu.toldi.infinityforlemmy.UploadImageEnabledActivity;
import eu.toldi.infinityforlemmy.UploadedImage;
import eu.toldi.infinityforlemmy.account.Account;
import eu.toldi.infinityforlemmy.adapters.MarkdownBottomBarRecyclerViewAdapter;
import eu.toldi.infinityforlemmy.apis.TitleSuggestion;
import eu.toldi.infinityforlemmy.asynctasks.LoadSubredditIcon;
import eu.toldi.infinityforlemmy.bottomsheetfragments.AccountChooserBottomSheetFragment;
import eu.toldi.infinityforlemmy.bottomsheetfragments.FlairBottomSheetFragment;
import eu.toldi.infinityforlemmy.bottomsheetfragments.UploadedImagesBottomSheetFragment;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed;
import eu.toldi.infinityforlemmy.events.SubmitTextOrLinkPostEvent;
import eu.toldi.infinityforlemmy.events.SwitchAccountEvent;
import eu.toldi.infinityforlemmy.services.SubmitPostService;
@@ -60,6 +75,7 @@ import eu.toldi.infinityforlemmy.subreddit.SubredditData;
import eu.toldi.infinityforlemmy.subscribedsubreddit.SubscribedSubredditData;
import eu.toldi.infinityforlemmy.utils.APIUtils;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import eu.toldi.infinityforlemmy.utils.Utils;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
import pl.droidsonroids.gif.GifImageView;
import retrofit2.Call;
@@ -69,7 +85,7 @@ import retrofit2.Retrofit;
import retrofit2.converter.scalars.ScalarsConverterFactory;
public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFragment.FlairSelectionCallback,
AccountChooserBottomSheetFragment.AccountChooserListener {
UploadImageEnabledActivity, AccountChooserBottomSheetFragment.AccountChooserListener {
static final String EXTRA_SUBREDDIT_NAME = "ESN";
static final String EXTRA_LINK = "EL";
@@ -87,6 +103,9 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr
private static final String IS_NSFW_STATE = "INS";
private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 0;
private static final int PICK_IMAGE_REQUEST_CODE = 100;
private static final int CAPTURE_IMAGE_REQUEST_CODE = 200;
private static final int MARKDOWN_PREVIEW_REQUEST_CODE = 300;
@BindView(R.id.coordinator_layout_post_link_activity)
CoordinatorLayout coordinatorLayout;
@@ -124,6 +143,11 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr
MaterialButton suggestTitleButton;
@BindView(R.id.post_link_edit_text_post_link_activity)
EditText linkEditText;
@BindView(R.id.post_text_content_edit_text_post_text_activity)
EditText contentEditText;
@BindView(R.id.markdown_bottom_bar_recycler_view_post_text_activity)
RecyclerView markdownBottomBarRecyclerView;
@Inject
@Named("no_oauth")
RetrofitHolder mRetrofit;
@@ -167,6 +191,9 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr
private FlairBottomSheetFragment flairSelectionBottomSheetFragment;
private Snackbar mPostingSnackbar;
private Uri capturedImageUri;
private ArrayList<UploadedImage> uploadedImages = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
((Infinity) getApplication()).getAppComponent().inject(this);
@@ -190,7 +217,7 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mGlide = Glide.with(this);
mGlide = Glide.with(getApplication());
mPostingSnackbar = Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_INDEFINITE);
@@ -335,21 +362,46 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr
.baseUrl("http://localhost/")
.addConverterFactory(ScalarsConverterFactory.create())
.build().create(TitleSuggestion.class).getHtml(url).enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
if (response.isSuccessful()) {
titleEditText.setText(response.body().substring(response.body().indexOf("<title>") + 7, response.body().indexOf("</title>")));
} else {
Toast.makeText(PostLinkActivity.this, R.string.suggest_title_failed, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
if (response.isSuccessful()) {
titleEditText.setText(response.body().substring(response.body().indexOf("<title>") + 7, response.body().indexOf("</title>")));
} else {
Toast.makeText(PostLinkActivity.this, R.string.suggest_title_failed, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
Toast.makeText(PostLinkActivity.this, R.string.suggest_title_failed, Toast.LENGTH_SHORT).show();
}
});
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
Toast.makeText(PostLinkActivity.this, R.string.suggest_title_failed, Toast.LENGTH_SHORT).show();
}
});
});
MarkdownBottomBarRecyclerViewAdapter adapter = new MarkdownBottomBarRecyclerViewAdapter(
mCustomThemeWrapper, new MarkdownBottomBarRecyclerViewAdapter.ItemClickListener() {
@Override
public void onClick(int item) {
MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener(
PostLinkActivity.this, contentEditText, item);
}
@Override
public void onUploadImage() {
Utils.hideKeyboard(PostLinkActivity.this);
UploadedImagesBottomSheetFragment fragment = new UploadedImagesBottomSheetFragment();
Bundle arguments = new Bundle();
arguments.putParcelableArrayList(UploadedImagesBottomSheetFragment.EXTRA_UPLOADED_IMAGES,
uploadedImages);
fragment.setArguments(arguments);
fragment.show(getSupportFragmentManager(), fragment.getTag());
}
});
markdownBottomBarRecyclerView.setLayoutManager(new LinearLayoutManagerBugFixed(this,
LinearLayoutManager.HORIZONTAL, false));
markdownBottomBarRecyclerView.setAdapter(adapter);
}
private void loadCurrentAccount() {
@@ -406,6 +458,8 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr
titleEditText.setHintTextColor(secondaryTextColor);
suggestTitleButton.setBackgroundColor(mCustomThemeWrapper.getColorPrimaryLightTheme());
suggestTitleButton.setTextColor(mCustomThemeWrapper.getButtonTextColor());
contentEditText.setTextColor(primaryTextColor);
contentEditText.setHintTextColor(secondaryTextColor);
linkEditText.setTextColor(primaryTextColor);
linkEditText.setHintTextColor(secondaryTextColor);
if (typeface != null) {
@@ -418,6 +472,7 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr
}
if (contentTypeface != null) {
linkEditText.setTypeface(contentTypeface);
contentEditText.setTypeface(contentTypeface);
}
}
@@ -436,12 +491,12 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr
}
private void loadSubredditIcon() {
LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, subredditName,
mAccessToken, mOauthRetrofit, mRetrofit.getRetrofit(), iconImageUrl -> {
iconUrl = iconImageUrl;
displaySubredditIcon();
loadSubredditIconSuccessful = true;
});
LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, communityData.getQualified_name(),
mAccessToken, mRetrofit.getRetrofit(), iconImageUrl -> {
iconUrl = iconImageUrl;
displaySubredditIcon();
loadSubredditIconSuccessful = true;
});
}
private void promptAlertDialog(int titleResId, int messageResId) {
@@ -514,7 +569,8 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr
intent.putExtra(SubmitPostService.EXTRA_ACCOUNT, selectedAccount);
intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, communityData.getId());
intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString());
intent.putExtra(SubmitPostService.EXTRA_CONTENT, linkEditText.getText().toString());
intent.putExtra(SubmitPostService.EXTRA_BODY, contentEditText.getText().toString());
intent.putExtra(SubmitPostService.EXTRA_URL, linkEditText.getText().toString());
intent.putExtra(SubmitPostService.EXTRA_KIND, APIUtils.KIND_LINK);
intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair);
intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler);
@@ -561,8 +617,8 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
if (resultCode == RESULT_OK) {
if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE) {
communityData = data.getExtras().getParcelable(SubredditSelectionActivity.EXTRA_RETURN_COMMUNITY_DATA);
subredditName = communityData.getName();
iconUrl = communityData.getIconUrl();
@@ -574,6 +630,16 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr
displaySubredditIcon();
flair = null;
} else if (requestCode == PICK_IMAGE_REQUEST_CODE) {
if (data == null) {
Toast.makeText(PostLinkActivity.this, R.string.error_getting_image, Toast.LENGTH_LONG).show();
return;
}
Utils.uploadImageToReddit(this, mExecutor, mRetrofit,
mAccessToken, contentEditText, coordinatorLayout, data.getData(), uploadedImages);
} else if (requestCode == CAPTURE_IMAGE_REQUEST_CODE) {
Utils.uploadImageToReddit(this, mExecutor, mRetrofit,
mAccessToken, contentEditText, coordinatorLayout, capturedImageUri, uploadedImages);
}
}
}
@@ -629,4 +695,37 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr
}
}
}
@Override
public void uploadImage() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
getResources().getString(R.string.select_from_gallery)), PICK_IMAGE_REQUEST_CODE);
}
@Override
public void captureImage() {
Intent pictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
capturedImageUri = FileProvider.getUriForFile(this, "eu.toldi.infinityforlemmy.provider",
File.createTempFile("captured_image", ".jpg", getExternalFilesDir(Environment.DIRECTORY_PICTURES)));
pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, capturedImageUri);
startActivityForResult(pictureIntent, CAPTURE_IMAGE_REQUEST_CODE);
} catch (IOException ex) {
Toast.makeText(this, R.string.error_creating_temp_file, Toast.LENGTH_SHORT).show();
} catch (ActivityNotFoundException e) {
Toast.makeText(this, R.string.no_camera_available, Toast.LENGTH_SHORT).show();
}
}
@Override
public void insertImageUrl(UploadedImage uploadedImage) {
int start = Math.max(contentEditText.getSelectionStart(), 0);
int end = Math.max(contentEditText.getSelectionEnd(), 0);
contentEditText.getText().replace(Math.min(start, end), Math.max(start, end),
"![" + uploadedImage.imageName + "](" + uploadedImage.imageUrl + ")",
0, "![]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length());
}
}

View File

@@ -219,7 +219,7 @@ public class PostPollActivity extends BaseActivity implements FlairBottomSheetFr
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mGlide = Glide.with(this);
mGlide = Glide.with(getApplication());
mPostingSnackbar = Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_INDEFINITE);
@@ -500,7 +500,7 @@ public class PostPollActivity extends BaseActivity implements FlairBottomSheetFr
}
private void loadSubredditIcon() {
LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, subredditName, mAccessToken, mOauthRetrofit, mRetrofit.getRetrofit(), iconImageUrl -> {
LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, subredditName, mAccessToken, mRetrofit.getRetrofit(), iconImageUrl -> {
iconUrl = iconImageUrl;
displaySubredditIcon();
loadSubredditIconSuccessful = true;

View File

@@ -208,7 +208,7 @@ public class PostTextActivity extends BaseActivity implements FlairBottomSheetFr
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mGlide = Glide.with(this);
mGlide = Glide.with(getApplication());
mPostingSnackbar = Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_INDEFINITE);
@@ -450,12 +450,12 @@ public class PostTextActivity extends BaseActivity implements FlairBottomSheetFr
}
private void loadSubredditIcon() {
LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, subredditName,
mAccessToken, mOauthRetrofit, mRetrofit.getRetrofit(), iconImageUrl -> {
iconUrl = iconImageUrl;
displaySubredditIcon();
loadSubredditIconSuccessful = true;
});
LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, communityData.getQualified_name(),
mAccessToken, mRetrofit.getRetrofit(), iconImageUrl -> {
iconUrl = iconImageUrl;
displaySubredditIcon();
loadSubredditIconSuccessful = true;
});
}
private void promptAlertDialog(int titleResId, int messageResId) {
@@ -533,7 +533,7 @@ public class PostTextActivity extends BaseActivity implements FlairBottomSheetFr
intent.putExtra(SubmitPostService.EXTRA_ACCOUNT, selectedAccount);
intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, communityData.getId());
intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString());
intent.putExtra(SubmitPostService.EXTRA_CONTENT, contentEditText.getText().toString());
intent.putExtra(SubmitPostService.EXTRA_BODY, contentEditText.getText().toString());
intent.putExtra(SubmitPostService.EXTRA_KIND, APIUtils.KIND_SELF);
intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair);
intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler);
@@ -673,8 +673,8 @@ public class PostTextActivity extends BaseActivity implements FlairBottomSheetFr
int start = Math.max(contentEditText.getSelectionStart(), 0);
int end = Math.max(contentEditText.getSelectionEnd(), 0);
contentEditText.getText().replace(Math.min(start, end), Math.max(start, end),
"[" + uploadedImage.imageName + "](" + uploadedImage.imageUrl + ")",
0, "[]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length());
"![" + uploadedImage.imageName + "](" + uploadedImage.imageUrl + ")",
0, "![]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length());
}
@Override

View File

@@ -216,7 +216,7 @@ public class PostVideoActivity extends BaseActivity implements FlairBottomSheetF
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mGlide = Glide.with(this);
mGlide = Glide.with(getApplication());
player = new ExoPlayer.Builder(this).build();
videoPlayerView.setPlayer(player);
@@ -447,8 +447,9 @@ public class PostVideoActivity extends BaseActivity implements FlairBottomSheetF
nsfwTextView.setTextColor(primaryTextColor);
titleEditText.setTextColor(primaryTextColor);
titleEditText.setHintTextColor(secondaryTextColor);
applyFABTheme(captureFab);
applyFABTheme(selectFromLibraryFab);
boolean circularFab = mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false);
applyFABTheme(captureFab, circularFab);
applyFABTheme(selectFromLibraryFab, circularFab);
selectAgainTextView.setTextColor(mCustomThemeWrapper.getColorAccent());
if (typeface != null) {
subredditNameTextView.setTypeface(typeface);
@@ -485,11 +486,11 @@ public class PostVideoActivity extends BaseActivity implements FlairBottomSheetF
private void loadSubredditIcon() {
LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, subredditName,
mAccessToken, mOauthRetrofit, mRetrofit.getRetrofit(), iconImageUrl -> {
iconUrl = iconImageUrl;
displaySubredditIcon();
loadSubredditIconSuccessful = true;
});
mAccessToken, mRetrofit.getRetrofit(), iconImageUrl -> {
iconUrl = iconImageUrl;
displaySubredditIcon();
loadSubredditIconSuccessful = true;
});
}
private void promptAlertDialog(int titleResId, int messageResId) {

View File

@@ -132,7 +132,7 @@ public class RulesActivity extends BaseActivity {
mSubredditName = getIntent().getExtras().getString(EXTRA_SUBREDDIT_NAME);
mAdapter = new RulesRecyclerViewAdapter(this, mCustomThemeWrapper, sliderPanel);
mAdapter = new RulesRecyclerViewAdapter(this, mCustomThemeWrapper, sliderPanel, mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_IMAGE_PREVIEW, false));
recyclerView.setAdapter(mAdapter);
FetchSubredditData.fetchSubredditData(mRetrofit.getRetrofit(), mSubredditName, mAccessToken, new FetchSubredditData.FetchSubredditDataListener() {
@Override

View File

@@ -3,6 +3,7 @@ package eu.toldi.infinityforlemmy.activities;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.ColorStateList;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@@ -27,11 +28,14 @@ import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import java.util.ArrayList;
import java.util.concurrent.Executor;
import javax.inject.Inject;
import javax.inject.Named;
@@ -47,7 +51,6 @@ import eu.toldi.infinityforlemmy.apis.RedditAPI;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.customviews.slidr.Slidr;
import eu.toldi.infinityforlemmy.events.SwitchAccountEvent;
import eu.toldi.infinityforlemmy.recentsearchquery.DeleteRecentSearchQuery;
import eu.toldi.infinityforlemmy.recentsearchquery.RecentSearchQuery;
import eu.toldi.infinityforlemmy.recentsearchquery.RecentSearchQueryViewModel;
import eu.toldi.infinityforlemmy.subreddit.ParseSubredditData;
@@ -98,6 +101,8 @@ public class SearchActivity extends BaseActivity {
ImageView clearSearchTextImageView;
@BindView(R.id.link_handler_image_view_search_activity)
ImageView linkHandlerImageView;
@BindView(R.id.delete_all_recent_searches_button_search_activity)
MaterialButton deleteAllSearchesButton;
@BindView(R.id.subreddit_name_relative_layout_search_activity)
RelativeLayout subredditNameRelativeLayout;
@BindView(R.id.search_in_text_view_search_activity)
@@ -124,6 +129,8 @@ public class SearchActivity extends BaseActivity {
SharedPreferences mNsfwAndSpoilerSharedPreferences;
@Inject
CustomThemeWrapper mCustomThemeWrapper;
@Inject
Executor executor;
private String mAccountName;
private String mAccessToken;
private String query;
@@ -163,6 +170,7 @@ public class SearchActivity extends BaseActivity {
setSupportActionBar(toolbar);
clearSearchTextImageView.setVisibility(View.GONE);
deleteAllSearchesButton.setVisibility(View.GONE);
searchOnlySubreddits = getIntent().getBooleanExtra(EXTRA_SEARCH_ONLY_SUBREDDITS, false);
searchOnlyUsers = getIntent().getBooleanExtra(EXTRA_SEARCH_ONLY_USERS, false);
@@ -276,6 +284,17 @@ public class SearchActivity extends BaseActivity {
}
});
deleteAllSearchesButton.setOnClickListener(view -> {
new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme)
.setTitle(R.string.confirm)
.setMessage(R.string.confirm_delete_all_recent_searches)
.setPositiveButton(R.string.yes, (dialogInterface, i) -> {
executor.execute(() -> mRedditDataRoomDatabase.recentSearchQueryDao().deleteAllRecentSearchQueries(mAccountName));
})
.setNegativeButton(R.string.no, null)
.show();
});
if (savedInstanceState != null) {
subredditName = savedInstanceState.getString(SUBREDDIT_NAME_STATE);
subredditIsUser = savedInstanceState.getBoolean(SUBREDDIT_IS_USER_STATE);
@@ -319,7 +338,7 @@ public class SearchActivity extends BaseActivity {
@Override
public void onDelete(RecentSearchQuery recentSearchQuery) {
DeleteRecentSearchQuery.deleteRecentSearchQueryListener(mRedditDataRoomDatabase, recentSearchQuery, () -> {});
executor.execute(() -> mRedditDataRoomDatabase.recentSearchQueryDao().deleteRecentSearchQueries(recentSearchQuery));
}
});
recyclerView.setVisibility(View.VISIBLE);
@@ -334,8 +353,10 @@ public class SearchActivity extends BaseActivity {
mRecentSearchQueryViewModel.getAllRecentSearchQueries().observe(this, recentSearchQueries -> {
if (recentSearchQueries != null && !recentSearchQueries.isEmpty()) {
divider.setVisibility(View.VISIBLE);
deleteAllSearchesButton.setVisibility(View.VISIBLE);
} else {
divider.setVisibility(View.GONE);
deleteAllSearchesButton.setVisibility(View.GONE);
}
adapter.setRecentSearchQueries(recentSearchQueries);
});
@@ -401,6 +422,7 @@ public class SearchActivity extends BaseActivity {
linkHandlerImageView.setColorFilter(mCustomThemeWrapper.getToolbarPrimaryTextAndIconColor(), android.graphics.PorterDuff.Mode.SRC_IN);
int colorAccent = mCustomThemeWrapper.getColorAccent();
searchInTextView.setTextColor(colorAccent);
deleteAllSearchesButton.setIconTint(ColorStateList.valueOf(mCustomThemeWrapper.getPrimaryIconColor()));
subredditNameTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor());
divider.setBackgroundColor(mCustomThemeWrapper.getDividerColor());
if (typeface != null) {
@@ -433,12 +455,14 @@ public class SearchActivity extends BaseActivity {
if (resultCode == RESULT_OK && data != null) {
if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE) {
communityData = data.getParcelableExtra(SubredditSelectionActivity.EXTRA_RETURN_COMMUNITY_DATA);
subredditName = communityData.getName();
subredditIsUser = false;
if (subredditName == null) {
if (communityData == null) {
subredditNameTextView.setText(R.string.all_communities);
} else {
subredditName = communityData.getName();
communityQualifiedName = communityData.getQualified_name();
subredditNameTextView.setText(subredditName);
}
} else if (requestCode == SUBREDDIT_SEARCH_REQUEST_CODE) {

View File

@@ -38,6 +38,7 @@ import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import java.util.ArrayList;
import java.util.concurrent.Executor;
import javax.inject.Inject;
import javax.inject.Named;
@@ -130,10 +131,11 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect
SharedPreferences mCurrentAccountSharedPreferences;
@Inject
CustomThemeWrapper mCustomThemeWrapper;
@Inject
Executor executor;
private Call<String> subredditAutocompleteCall;
private String mAccessToken;
private String mAccountName;
private String mAccountQualifiedName;
private String mQuery;
private String mSubredditName;
@@ -238,13 +240,13 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect
coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor());
applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, collapsingToolbarLayout, toolbar);
applyTabLayoutTheme(tabLayout);
applyFABTheme(fab);
applyFABTheme(fab, mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false));
}
private void bindView(Bundle savedInstanceState) {
sectionsPagerAdapter = new SectionsPagerAdapter(this);
viewPager2.setAdapter(sectionsPagerAdapter);
viewPager2.setOffscreenPageLimit(3);
viewPager2.setOffscreenPageLimit(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT);
viewPager2.setUserInputEnabled(!mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS, false));
viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
@@ -392,8 +394,8 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect
});
if (mAccountName != null && mSharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_SEARCH_HISTORY, true) && !mInsertSearchQuerySuccess && mQuery != null) {
InsertRecentSearchQuery.insertRecentSearchQueryListener(mRedditDataRoomDatabase, mAccountQualifiedName,
mQuery, () -> mInsertSearchQuerySuccess = true);
InsertRecentSearchQuery.insertRecentSearchQueryListener(executor, new Handler(getMainLooper()),
mRedditDataRoomDatabase, mAccountQualifiedName, mQuery, () -> mInsertSearchQuerySuccess = true);
}
}
@@ -558,10 +560,6 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect
goToUser();
break;
}
case FABMoreOptionsBottomSheetFragment.FAB_RANDOM: {
random();
break;
}
case FABMoreOptionsBottomSheetFragment.FAB_HIDE_READ_POSTS: {
if (sectionsPagerAdapter != null) {
sectionsPagerAdapter.hideReadPosts();
@@ -788,7 +786,8 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect
bundle.putString(SubredditListingFragment.EXTRA_QUERY, mQuery);
bundle.putBoolean(SubredditListingFragment.EXTRA_IS_GETTING_SUBREDDIT_INFO, false);
bundle.putString(SubredditListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken);
bundle.putString(SubredditListingFragment.EXTRA_ACCOUNT_NAME, mAccountQualifiedName);
bundle.putString(SubredditListingFragment.EXTRA_ACCOUNT_NAME, mAccountName);
bundle.putString(SubredditListingFragment.EXTRA_ACCOUNT_QUALIFIED_NAME, mAccountQualifiedName);
mFragment.setArguments(bundle);
return mFragment;
}

View File

@@ -119,7 +119,8 @@ public class SearchSubredditsResultActivity extends BaseActivity implements Acti
bundle.putString(SubredditListingFragment.EXTRA_QUERY, query);
bundle.putBoolean(SubredditListingFragment.EXTRA_IS_GETTING_SUBREDDIT_INFO, true);
bundle.putString(SubredditListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken);
bundle.putString(SubredditListingFragment.EXTRA_ACCOUNT_NAME, mAccountQualifiedName);
bundle.putString(SubredditListingFragment.EXTRA_ACCOUNT_NAME, mAccountName);
bundle.putString(SubredditListingFragment.EXTRA_ACCOUNT_QUALIFIED_NAME, mAccountQualifiedName);
bundle.putBoolean(SubredditListingFragment.EXTRA_IS_MULTI_SELECTION, getIntent().getBooleanExtra(EXTRA_IS_MULTI_SELECTION, false));
mFragment.setArguments(bundle);
} else {

View File

@@ -194,7 +194,7 @@ public class SelectedSubredditsAndUsersActivity extends BaseActivity implements
protected void applyCustomTheme() {
coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor());
applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, collapsingToolbarLayout, toolbar);
applyFABTheme(fab);
applyFABTheme(fab, mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false));
}
@Override

View File

@@ -1,8 +1,13 @@
package eu.toldi.infinityforlemmy.activities;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@@ -10,12 +15,20 @@ import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.core.content.FileProvider;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.snackbar.Snackbar;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.Executor;
import javax.inject.Inject;
import javax.inject.Named;
@@ -23,13 +36,24 @@ import butterknife.BindView;
import butterknife.ButterKnife;
import eu.toldi.infinityforlemmy.Infinity;
import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.RetrofitHolder;
import eu.toldi.infinityforlemmy.UploadImageEnabledActivity;
import eu.toldi.infinityforlemmy.UploadedImage;
import eu.toldi.infinityforlemmy.adapters.MarkdownBottomBarRecyclerViewAdapter;
import eu.toldi.infinityforlemmy.bottomsheetfragments.UploadedImagesBottomSheetFragment;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.message.ComposeMessage;
import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed;
import eu.toldi.infinityforlemmy.privatemessage.LemmyPrivateMessageAPI;
import eu.toldi.infinityforlemmy.privatemessage.PrivateMessage;
import eu.toldi.infinityforlemmy.user.BasicUserInfo;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import retrofit2.Retrofit;
import eu.toldi.infinityforlemmy.utils.Utils;
public class SendPrivateMessageActivity extends BaseActivity {
public static final String EXTRA_RECIPIENT_USERNAME = "ERU";
public class SendPrivateMessageActivity extends BaseActivity implements UploadImageEnabledActivity {
public static final String EXTRA_RECIPIENT_USER_INFO = "ERUI";
private static final int PICK_IMAGE_REQUEST_CODE = 100;
private static final int CAPTURE_IMAGE_REQUEST_CODE = 200;
@BindView(R.id.coordinator_layout_send_private_message_activity)
CoordinatorLayout coordinatorLayout;
@BindView(R.id.appbar_layout_send_private_message_activity)
@@ -40,15 +64,20 @@ public class SendPrivateMessageActivity extends BaseActivity {
EditText usernameEditText;
@BindView(R.id.divider_1_send_private_message_activity)
View divider1;
@BindView(R.id.subjet_edit_text_send_private_message_activity)
EditText subjectEditText;
@BindView(R.id.divider_2_send_private_message_activity)
View divider2;
@BindView(R.id.content_edit_text_send_private_message_activity)
EditText messageEditText;
@BindView(R.id.markdown_bottom_bar_recycler_view_send_private_message_activity)
RecyclerView markdownBottomBarRecyclerView;
@Inject
@Named("oauth")
Retrofit mOauthRetrofit;
@Named("no_oauth")
RetrofitHolder mRetrofit;
@Inject
Executor mExecutor;
@Inject
@Named("default")
SharedPreferences mSharedPreferences;
@@ -57,15 +86,24 @@ public class SendPrivateMessageActivity extends BaseActivity {
SharedPreferences mCurrentAccountSharedPreferences;
@Inject
CustomThemeWrapper mCustomThemeWrapper;
@Inject
LemmyPrivateMessageAPI mLemmyPrivateMessageAPI;
private String mAccessToken;
private BasicUserInfo mRecipientBasicUserInfo;
private boolean isSubmitting = false;
private ArrayList<UploadedImage> uploadedImages = new ArrayList<>();
private Uri capturedImageUri;
@Override
protected void onCreate(Bundle savedInstanceState) {
((Infinity) getApplication()).getAppComponent().inject(this);
setImmersiveModeNotApplicable();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_send_private_message);
@@ -77,14 +115,66 @@ public class SendPrivateMessageActivity extends BaseActivity {
addOnOffsetChangedListener(appBarLayout);
}
MarkdownBottomBarRecyclerViewAdapter adapter = new MarkdownBottomBarRecyclerViewAdapter(
mCustomThemeWrapper, new MarkdownBottomBarRecyclerViewAdapter.ItemClickListener() {
@Override
public void onClick(int item) {
MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener(
SendPrivateMessageActivity.this, messageEditText, item);
}
@Override
public void onUploadImage() {
Utils.hideKeyboard(SendPrivateMessageActivity.this);
UploadedImagesBottomSheetFragment fragment = new UploadedImagesBottomSheetFragment();
Bundle arguments = new Bundle();
arguments.putParcelableArrayList(UploadedImagesBottomSheetFragment.EXTRA_UPLOADED_IMAGES,
uploadedImages);
fragment.setArguments(arguments);
fragment.show(getSupportFragmentManager(), fragment.getTag());
}
});
markdownBottomBarRecyclerView.setLayoutManager(new LinearLayoutManagerBugFixed(this,
LinearLayoutManagerBugFixed.HORIZONTAL, false));
markdownBottomBarRecyclerView.setAdapter(adapter);
mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null);
setSupportActionBar(toolbar);
String username = getIntent().getStringExtra(EXTRA_RECIPIENT_USERNAME);
if (username != null) {
usernameEditText.setText(username);
if (savedInstanceState != null) {
mRecipientBasicUserInfo = savedInstanceState.getParcelable(EXTRA_RECIPIENT_USER_INFO);
} else {
mRecipientBasicUserInfo = getIntent().getParcelableExtra(EXTRA_RECIPIENT_USER_INFO);
}
if (mRecipientBasicUserInfo != null) {
usernameEditText.setText(mRecipientBasicUserInfo.getQualifiedName());
usernameEditText.setEnabled(false);
} else {
finish();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == PICK_IMAGE_REQUEST_CODE) {
if (data == null) {
Toast.makeText(SendPrivateMessageActivity.this, R.string.error_getting_image, Toast.LENGTH_LONG).show();
return;
}
Utils.uploadImageToReddit(this, mExecutor, mRetrofit,
mAccessToken, messageEditText, coordinatorLayout, data.getData(), uploadedImages);
} else if (requestCode == CAPTURE_IMAGE_REQUEST_CODE) {
Utils.uploadImageToReddit(this, mExecutor, mRetrofit,
mAccessToken, messageEditText, coordinatorLayout, capturedImageUri, uploadedImages);
}
}
}
@Override
@@ -108,12 +198,6 @@ public class SendPrivateMessageActivity extends BaseActivity {
return true;
}
if (subjectEditText.getText() == null || subjectEditText.getText().toString().equals("")) {
isSubmitting = false;
Snackbar.make(coordinatorLayout, R.string.message_subject_required, Snackbar.LENGTH_LONG).show();
return true;
}
if (messageEditText.getText() == null || messageEditText.getText().toString().equals("")) {
isSubmitting = false;
Snackbar.make(coordinatorLayout, R.string.message_content_required, Snackbar.LENGTH_LONG).show();
@@ -125,32 +209,26 @@ public class SendPrivateMessageActivity extends BaseActivity {
Snackbar sendingSnackbar = Snackbar.make(coordinatorLayout, R.string.sending_message, Snackbar.LENGTH_INDEFINITE);
sendingSnackbar.show();
ComposeMessage.composeMessage(mOauthRetrofit, mAccessToken, getResources().getConfiguration().locale,
usernameEditText.getText().toString(), subjectEditText.getText().toString(),
messageEditText.getText().toString(), new ComposeMessage.ComposeMessageListener() {
@Override
public void composeMessageSuccess() {
isSubmitting = false;
item.setEnabled(true);
item.getIcon().setAlpha(255);
Toast.makeText(SendPrivateMessageActivity.this, R.string.send_message_success, Toast.LENGTH_SHORT).show();
finish();
}
mLemmyPrivateMessageAPI.sendPrivateMessage(mAccessToken, mRecipientBasicUserInfo.getId(), messageEditText.getText().toString(), new LemmyPrivateMessageAPI.PrivateMessageSentListener() {
@Override
public void onPrivateMessageSentSuccess(@NonNull PrivateMessage privateMessage) {
isSubmitting = false;
item.setEnabled(true);
item.getIcon().setAlpha(255);
Toast.makeText(SendPrivateMessageActivity.this, R.string.send_message_success, Toast.LENGTH_SHORT).show();
finish();
}
@Override
public void composeMessageFailed(String errorMessage) {
isSubmitting = false;
sendingSnackbar.dismiss();
item.setEnabled(true);
item.getIcon().setAlpha(255);
@Override
public void onPrivateMessageSentError() {
isSubmitting = false;
sendingSnackbar.dismiss();
item.setEnabled(true);
item.getIcon().setAlpha(255);
if (errorMessage == null || errorMessage.equals("")) {
Snackbar.make(coordinatorLayout, R.string.send_message_failed, Snackbar.LENGTH_LONG).show();
} else {
Snackbar.make(coordinatorLayout, errorMessage, Snackbar.LENGTH_LONG).show();
}
}
});
Snackbar.make(coordinatorLayout, R.string.send_message_failed, Snackbar.LENGTH_LONG).show();
}
});
}
}
return false;
@@ -159,6 +237,7 @@ public class SendPrivateMessageActivity extends BaseActivity {
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable(EXTRA_RECIPIENT_USER_INFO, mRecipientBasicUserInfo);
}
@Override
@@ -177,19 +256,49 @@ public class SendPrivateMessageActivity extends BaseActivity {
applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, null, toolbar);
int primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor();
usernameEditText.setTextColor(primaryTextColor);
subjectEditText.setTextColor(primaryTextColor);
messageEditText.setTextColor(primaryTextColor);
int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor();
usernameEditText.setHintTextColor(secondaryTextColor);
subjectEditText.setHintTextColor(secondaryTextColor);
messageEditText.setHintTextColor(secondaryTextColor);
int dividerColor = mCustomThemeWrapper.getDividerColor();
divider1.setBackgroundColor(dividerColor);
divider2.setBackgroundColor(dividerColor);
if (typeface != null) {
usernameEditText.setTypeface(typeface);
subjectEditText.setTypeface(typeface);
messageEditText.setTypeface(typeface);
}
}
@Override
public void uploadImage() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
getResources().getString(R.string.select_from_gallery)), PICK_IMAGE_REQUEST_CODE);
}
@Override
public void captureImage() {
Intent pictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
capturedImageUri = FileProvider.getUriForFile(this, "eu.toldi.infinityforlemmy.provider",
File.createTempFile("captured_image", ".jpg", getExternalFilesDir(Environment.DIRECTORY_PICTURES)));
pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, capturedImageUri);
startActivityForResult(pictureIntent, CAPTURE_IMAGE_REQUEST_CODE);
} catch (IOException ex) {
Toast.makeText(this, R.string.error_creating_temp_file, Toast.LENGTH_SHORT).show();
} catch (ActivityNotFoundException e) {
Toast.makeText(this, R.string.no_camera_available, Toast.LENGTH_SHORT).show();
}
}
@Override
public void insertImageUrl(UploadedImage uploadedImage) {
int start = Math.max(messageEditText.getSelectionStart(), 0);
int end = Math.max(messageEditText.getSelectionEnd(), 0);
messageEditText.getText().replace(Math.min(start, end), Math.max(start, end),
"![" + uploadedImage.imageName + "](" + uploadedImage.imageUrl + ")",
0, "![]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length());
}
}

View File

@@ -112,8 +112,6 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom
View divider1;
@BindView(R.id.flair_custom_text_view_submit_crosspost_activity)
CustomTextView flairTextView;
@BindView(R.id.spoiler_custom_text_view_submit_crosspost_activity)
CustomTextView spoilerTextView;
@BindView(R.id.nsfw_custom_text_view_submit_crosspost_activity)
CustomTextView nsfwTextView;
@BindView(R.id.divider_2_submit_crosspost_activity)
@@ -204,7 +202,7 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mGlide = Glide.with(this);
mGlide = Glide.with(getApplication());
mPostingSnackbar = Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_INDEFINITE);
@@ -259,11 +257,6 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom
flairTextView.setBorderColor(flairBackgroundColor);
flairTextView.setTextColor(flairTextColor);
}
if (isSpoiler) {
spoilerTextView.setBackgroundColor(spoilerBackgroundColor);
spoilerTextView.setBorderColor(spoilerBackgroundColor);
spoilerTextView.setTextColor(spoilerTextColor);
}
if (isNSFW) {
nsfwTextView.setBackgroundColor(nsfwBackgroundColor);
nsfwTextView.setBorderColor(nsfwBackgroundColor);
@@ -287,13 +280,14 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom
titleEditText.setText(post.getTitle());
}
if (post.getPostType() == Post.TEXT_TYPE) {
if (post.getPostType() == Post.TEXT_TYPE || post.getPostType() == Post.LINK_TYPE || post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) {
contentTextView.setVisibility(View.VISIBLE);
contentTextView.setText(post.getSelfTextPlain());
} else if (post.getPostType() == Post.LINK_TYPE || post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) {
contentTextView.setVisibility(View.VISIBLE);
contentTextView.setText(post.getUrl());
contentTextView.setText(generateCrossPostText(post));
} else {
if (post.getSelfTextPlain() != null && !post.getSelfTextPlain().equals("")) {
contentTextView.setVisibility(View.VISIBLE);
contentTextView.setText(generateCrossPostText(post));
}
Post.Preview preview = getPreview(post);
if (preview != null) {
frameLayout.setVisibility(View.VISIBLE);
@@ -368,18 +362,6 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom
}
});
spoilerTextView.setOnClickListener(view -> {
if (!isSpoiler) {
spoilerTextView.setBackgroundColor(spoilerBackgroundColor);
spoilerTextView.setBorderColor(spoilerBackgroundColor);
spoilerTextView.setTextColor(spoilerTextColor);
isSpoiler = true;
} else {
spoilerTextView.setBackgroundColor(resources.getColor(android.R.color.transparent));
spoilerTextView.setTextColor(primaryTextColor);
isSpoiler = false;
}
});
nsfwTextView.setOnClickListener(view -> {
if (!isNSFW) {
@@ -461,7 +443,6 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom
nsfwBackgroundColor = mCustomThemeWrapper.getNsfwBackgroundColor();
nsfwTextColor = mCustomThemeWrapper.getNsfwTextColor();
flairTextView.setTextColor(primaryTextColor);
spoilerTextView.setTextColor(primaryTextColor);
nsfwTextView.setTextColor(primaryTextColor);
titleEditText.setTextColor(primaryTextColor);
titleEditText.setHintTextColor(secondaryTextColor);
@@ -474,7 +455,6 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom
rulesButton.setTypeface(typeface);
receivePostReplyNotificationsTextView.setTypeface(typeface);
flairTextView.setTypeface(typeface);
spoilerTextView.setTypeface(typeface);
nsfwTextView.setTypeface(typeface);
titleEditText.setTypeface(typeface);
}
@@ -499,11 +479,11 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom
private void loadSubredditIcon() {
LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, subredditName,
mAccessToken, mOauthRetrofit, mRetrofit.getRetrofit(), iconImageUrl -> {
iconUrl = iconImageUrl;
displaySubredditIcon();
loadSubredditIconSuccessful = true;
});
mAccessToken, mRetrofit.getRetrofit(), iconImageUrl -> {
iconUrl = iconImageUrl;
displaySubredditIcon();
loadSubredditIconSuccessful = true;
});
}
private void promptAlertDialog(int titleResId, int messageResId) {
@@ -561,22 +541,19 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom
mPostingSnackbar.show();
String subredditName;
if (subredditIsUser) {
subredditName = "u_" + subredditNameTextView.getText().toString();
} else {
subredditName = subredditNameTextView.getText().toString();
}
String subredditName = subredditNameTextView.getText().toString();
Intent intent = new Intent(this, SubmitPostService.class);
intent.putExtra(SubmitPostService.EXTRA_ACCOUNT, selectedAccount);
intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, communityData.getId());
intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString());
if (post.isCrosspost()) {
intent.putExtra(SubmitPostService.EXTRA_CONTENT, "t3_" + post.getCrosspostParentId());
} else {
intent.putExtra(SubmitPostService.EXTRA_CONTENT, post.getFullName());
intent.putExtra(SubmitPostService.EXTRA_BODY, generateCrossPostText(post));
if (post.getUrl() != null && !post.getUrl().equals("")) {
intent.putExtra(SubmitPostService.EXTRA_URL, post.getUrl());
}
intent.putExtra(SubmitPostService.EXTRA_KIND, APIUtils.KIND_CROSSPOST);
intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair);
intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler);
@@ -699,4 +676,15 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom
}
}
}
private static String generateCrossPostText(Post post) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("cross-posted from: ").append(post.getPermalink()).append("\n");
String[] lines = post.getSelfTextPlain().split("\n");
for (String line : lines) {
stringBuilder.append("> ").append(line).append("\n");
}
return stringBuilder.toString();
}
}

View File

@@ -127,7 +127,7 @@ public class SubredditMultiselectionActivity extends BaseActivity implements Act
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mGlide = Glide.with(this);
mGlide = Glide.with(getApplication());
mSwipeRefreshLayout.setEnabled(false);

View File

@@ -73,7 +73,6 @@ import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import eu.toldi.infinityforlemmy.utils.Utils;
import retrofit2.Retrofit;
;
public class SubscribedThingListingActivity extends BaseActivity implements ActivityToolbarInterface {
@@ -113,6 +112,9 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti
@Named("current_account")
SharedPreferences mCurrentAccountSharedPreferences;
@Inject
@Named("internal")
SharedPreferences mInternalSharedPreferences;
@Inject
CustomThemeWrapper mCustomThemeWrapper;
@Inject
Executor mExecutor;
@@ -221,7 +223,7 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti
coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor());
applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, collapsingToolbarLayout, toolbar);
applyTabLayoutTheme(tabLayout);
applyFABTheme(fab);
applyFABTheme(fab, mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false));
searchEditText.setTextColor(mCustomThemeWrapper.getToolbarPrimaryTextAndIconColor());
searchEditText.setHintTextColor(mCustomThemeWrapper.getToolbarSecondaryTextColor());
}
@@ -233,7 +235,7 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti
});
sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(sectionsPagerAdapter);
viewPager.setOffscreenPageLimit(3);
viewPager.setOffscreenPageLimit(1);
if (viewPager.getCurrentItem() != 2) {
fab.hide();
}
@@ -324,6 +326,10 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti
}
public void loadSubscriptions(boolean forceLoad) {
if (!forceLoad && System.currentTimeMillis() - mInternalSharedPreferences.getLong(SharedPreferencesUtils.SUBSCRIBED_THINGS_SYNC_TIME, 0L) < 24 * 60 * 60 * 1000) {
return;
}
if (mAccessToken != null && !(!forceLoad && mInsertSuccess)) {
FetchSubscribedThing.fetchSubscribedThing(mRetrofit.getRetrofit(), mAccessToken, mAccountQualifiedName, null,
new ArrayList<>(), new ArrayList<>(),
@@ -333,6 +339,7 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti
public void onFetchSubscribedThingSuccess(ArrayList<SubscribedSubredditData> subscribedSubredditData,
ArrayList<SubscribedUserData> subscribedUserData,
ArrayList<SubredditData> subredditData) {
mInternalSharedPreferences.edit().putLong(SharedPreferencesUtils.SUBSCRIBED_THINGS_SYNC_TIME, System.currentTimeMillis()).apply();
InsertSubscribedThings.insertSubscribedThings(
mExecutor,
new Handler(),
@@ -358,7 +365,7 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti
}
if (!(!forceLoad && mInsertMultiredditSuccess)) {
loadMultiReddits();
//loadMultiReddits();
}
}
@@ -412,7 +419,7 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti
public void success() {
Toast.makeText(SubscribedThingListingActivity.this,
R.string.delete_multi_reddit_success, Toast.LENGTH_SHORT).show();
loadMultiReddits();
//loadMultiReddits();
}
@Override
@@ -439,7 +446,7 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti
@Subscribe
public void onRefreshMultiRedditsEvent(RefreshMultiRedditsEvent event) {
loadMultiReddits();
//loadMultiReddits();
}
@Override
@@ -477,6 +484,7 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti
@Override
public Fragment getItem(int position) {
switch (position) {
default:
case 0: {
SubscribedSubredditsListingFragment fragment = new SubscribedSubredditsListingFragment();
Bundle bundle = new Bundle();
@@ -487,28 +495,12 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti
fragment.setArguments(bundle);
return fragment;
}
case 1: {
FollowedUsersListingFragment fragment = new FollowedUsersListingFragment();
Bundle bundle = new Bundle();
bundle.putString(FollowedUsersListingFragment.EXTRA_ACCOUNT_NAME, mAccountName == null ? "-" : mAccountName);
bundle.putString(FollowedUsersListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken);
fragment.setArguments(bundle);
return fragment;
}
default: {
MultiRedditListingFragment fragment = new MultiRedditListingFragment();
Bundle bundle = new Bundle();
bundle.putString(MultiRedditListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken);
bundle.putString(MultiRedditListingFragment.EXTRA_ACCOUNT_NAME, mAccountName == null ? "-" : mAccountName);
fragment.setArguments(bundle);
return fragment;
}
}
}
@Override
public int getCount() {
return 3;
return 1;
}
@Override

View File

@@ -152,7 +152,7 @@ public class TrendingActivity extends BaseActivity {
mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null);
mGlide = Glide.with(this);
mGlide = Glide.with(getApplication());
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
@@ -201,7 +201,7 @@ public class TrendingActivity extends BaseActivity {
isRefreshing = true;
errorLinearLayout.setVisibility(View.GONE);
Glide.with(this).clear(errorImageView);
Glide.with(getApplication()).clear(errorImageView);
swipeRefreshLayout.setRefreshing(true);
trendingSearches = null;
adapter.setTrendingSearches(null);

View File

@@ -78,6 +78,7 @@ import eu.toldi.infinityforlemmy.font.TitleFontStyle;
import eu.toldi.infinityforlemmy.services.DownloadMediaService;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import eu.toldi.infinityforlemmy.utils.Utils;
import okhttp3.OkHttpClient;
public class ViewImageOrGifActivity extends AppCompatActivity implements SetAsWallpaperCallback, CustomFontReceiver {
@@ -108,6 +109,9 @@ public class ViewImageOrGifActivity extends AppCompatActivity implements SetAsWa
@Named("default")
SharedPreferences mSharedPreferences;
@Inject
@Named("glide")
OkHttpClient okHttpClient;
@Inject
Executor mExecutor;
private boolean isActionBarHidden = false;
private boolean isDownloading = false;
@@ -146,7 +150,7 @@ public class ViewImageOrGifActivity extends AppCompatActivity implements SetAsWa
getTheme().applyStyle(ContentFontFamily.valueOf(mSharedPreferences
.getString(SharedPreferencesUtils.CONTENT_FONT_FAMILY_KEY, ContentFontFamily.Default.name())).getResId(), true);
BigImageViewer.initialize(GlideImageLoader.with(this.getApplicationContext()));
BigImageViewer.initialize(GlideImageLoader.with(this.getApplicationContext(), okHttpClient));
setContentView(R.layout.activity_view_image_or_gif);
@@ -161,7 +165,7 @@ public class ViewImageOrGifActivity extends AppCompatActivity implements SetAsWa
Slidr.attach(this, new SlidrConfig.Builder().position(SlidrPosition.VERTICAL).distanceThreshold(0.125f).build());
}
glide = Glide.with(this);
glide = Glide.with(getApplication());
handler = new Handler();

View File

@@ -67,6 +67,7 @@ import eu.toldi.infinityforlemmy.events.SwitchAccountEvent;
import eu.toldi.infinityforlemmy.fragments.PostFragment;
import eu.toldi.infinityforlemmy.multireddit.DeleteMultiReddit;
import eu.toldi.infinityforlemmy.multireddit.MultiReddit;
import eu.toldi.infinityforlemmy.post.MarkPostAsRead;
import eu.toldi.infinityforlemmy.post.Post;
import eu.toldi.infinityforlemmy.post.PostPagingSource;
import eu.toldi.infinityforlemmy.readpost.InsertReadPost;
@@ -131,8 +132,11 @@ public class ViewMultiRedditDetailActivity extends BaseActivity implements SortT
CustomThemeWrapper mCustomThemeWrapper;
@Inject
Executor mExecutor;
@Inject
MarkPostAsRead markPostAsRead;
private String mAccessToken;
private String mAccountName;
private String mAccountQualifiedName;
private String multiPath;
private Fragment mFragment;
private int fabOption;
@@ -221,6 +225,7 @@ public class ViewMultiRedditDetailActivity extends BaseActivity implements SortT
mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null);
mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null);
mAccountQualifiedName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, null);
lockBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.LOCK_BOTTOM_APP_BAR, false);
if (savedInstanceState != null) {
@@ -848,7 +853,7 @@ public class ViewMultiRedditDetailActivity extends BaseActivity implements SortT
coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor());
applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, collapsingToolbarLayout, toolbar);
navigationWrapper.applyCustomTheme(mCustomThemeWrapper.getBottomAppBarIconColor(), mCustomThemeWrapper.getBottomAppBarBackgroundColor());
applyFABTheme(navigationWrapper.floatingActionButton);
applyFABTheme(navigationWrapper.floatingActionButton, mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false));
}
@Override
@@ -868,7 +873,17 @@ public class ViewMultiRedditDetailActivity extends BaseActivity implements SortT
@Override
public void markPostAsRead(Post post) {
InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, mAccountName, post.getId());
markPostAsRead.markPostAsRead(post.getId(), mAccessToken, new MarkPostAsRead.MarkPostAsReadListener() {
@Override
public void onMarkPostAsReadSuccess() {
InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, mAccountQualifiedName, post.getId());
}
@Override
public void onMarkPostAsReadFailed() {
Toast.makeText(ViewMultiRedditDetailActivity.this, R.string.mark_post_as_read_failed, Toast.LENGTH_SHORT).show();
}
});
}
@Override
@@ -931,10 +946,6 @@ public class ViewMultiRedditDetailActivity extends BaseActivity implements SortT
goToUser();
break;
}
case FABMoreOptionsBottomSheetFragment.FAB_RANDOM: {
random();
break;
}
case FABMoreOptionsBottomSheetFragment.FAB_HIDE_READ_POSTS: {
if (mFragment instanceof PostFragment) {
((PostFragment) mFragment).hideReadPosts();

View File

@@ -67,6 +67,7 @@ import eu.toldi.infinityforlemmy.SaveComment;
import eu.toldi.infinityforlemmy.SaveThing;
import eu.toldi.infinityforlemmy.SortType;
import eu.toldi.infinityforlemmy.SortTypeSelectionCallback;
import eu.toldi.infinityforlemmy.apis.LemmyAPI;
import eu.toldi.infinityforlemmy.apis.RedditAPI;
import eu.toldi.infinityforlemmy.asynctasks.SwitchAccount;
import eu.toldi.infinityforlemmy.comment.Comment;
@@ -81,10 +82,12 @@ import eu.toldi.infinityforlemmy.post.HistoryPostPagingSource;
import eu.toldi.infinityforlemmy.post.ParsePost;
import eu.toldi.infinityforlemmy.post.Post;
import eu.toldi.infinityforlemmy.post.PostPagingSource;
import eu.toldi.infinityforlemmy.post.enrich.PostEnricher;
import eu.toldi.infinityforlemmy.postfilter.PostFilter;
import eu.toldi.infinityforlemmy.readpost.ReadPost;
import eu.toldi.infinityforlemmy.utils.APIUtils;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import okhttp3.OkHttpClient;
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;
@@ -95,6 +98,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele
public static final String EXTRA_POST_ID = "EPI";
public static final String EXTRA_POST_LIST_POSITION = "EPLP";
public static final String EXTRA_SINGLE_COMMENT_ID = "ESCI";
public static final String EXTRA_SINGLE_COMMENT_PARENT_ID = "ESCPI";
public static final String EXTRA_CONTEXT_NUMBER = "ECN";
public static final String EXTRA_MESSAGE_FULLNAME = "ENI";
public static final String EXTRA_NEW_ACCOUNT_NAME = "ENAN";
@@ -146,6 +150,11 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele
CustomThemeWrapper mCustomThemeWrapper;
@Inject
Executor mExecutor;
@Inject
@Named("glide")
OkHttpClient okHttpClient;
@Inject
PostEnricher postEnricher;
@State
ArrayList<Post> posts;
@State
@@ -180,6 +189,8 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele
private SectionsPagerAdapter sectionsPagerAdapter;
private String mAccessToken;
private String mAccountName;
private String mAccountQalifiedName;
private long postFragmentId;
private int postListPosition;
private int orientation;
@@ -192,7 +203,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele
super.onCreate(savedInstanceState);
BigImageViewer.initialize(GlideImageLoader.with(this.getApplicationContext()));
BigImageViewer.initialize(GlideImageLoader.with(this.getApplicationContext(), okHttpClient));
setContentView(R.layout.activity_view_post_detail);
@@ -268,6 +279,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele
mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null);
mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null);
mAccountQalifiedName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, null);
mVolumeKeysNavigateComments = mSharedPreferences.getBoolean(SharedPreferencesUtils.VOLUME_KEYS_NAVIGATE_COMMENTS, false);
@@ -335,7 +347,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele
protected void applyCustomTheme() {
mCoordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor());
applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(mAppBarLayout, mCollapsingToolbarLayout, mToolbar);
applyFABTheme(fab);
applyFABTheme(fab, mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false));
searchPanelMaterialCardView.setBackgroundTintList(ColorStateList.valueOf(mCustomThemeWrapper.getColorPrimary()));
int searchPanelTextAndIconColor = mCustomThemeWrapper.getToolbarPrimaryTextAndIconColor();
searchTextInputLayout.setBoxStrokeColor(searchPanelTextAndIconColor);
@@ -352,8 +364,8 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele
private void checkNewAccountAndBindView(Bundle savedInstanceState) {
if (mNewAccountName != null) {
if (mAccountName == null || !mAccountName.equals(mNewAccountName)) {
SwitchAccount.switchAccount(mRedditDataRoomDatabase,mRetrofit, mCurrentAccountSharedPreferences,
if (mAccountName == null || !mAccountQalifiedName.equals(mNewAccountName)) {
SwitchAccount.switchAccount(mRedditDataRoomDatabase, mRetrofit, mCurrentAccountSharedPreferences,
mExecutor, new Handler(), mNewAccountName, newAccount -> {
EventBus.getDefault().post(new SwitchAccountEvent(getClass().getName()));
Toast.makeText(this, R.string.account_switched, Toast.LENGTH_SHORT).show();
@@ -425,11 +437,11 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele
}
public void deleteComment(String fullName, int position) {
public void deleteComment(int comment_id, int position) {
if (sectionsPagerAdapter != null) {
ViewPostDetailFragment fragment = sectionsPagerAdapter.getCurrentFragment();
if (fragment != null) {
fragment.deleteComment(fullName, position);
fragment.deleteComment(comment_id, position);
}
}
}
@@ -522,69 +534,38 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele
Handler handler = new Handler(Looper.getMainLooper());
if (postType != HistoryPostPagingSource.TYPE_READ_POSTS) {
int nextPage = posts.size() / 25 + 1;
mExecutor.execute(() -> {
RedditAPI api = (mAccessToken == null ? mRetrofit.getRetrofit() : mOauthRetrofit).create(RedditAPI.class);
LemmyAPI api = mRetrofit.getRetrofit().create(LemmyAPI.class);
Call<String> call;
String afterKey = posts.isEmpty() ? null : posts.get(posts.size() - 1).getFullName();
switch (postType) {
case PostPagingSource.TYPE_SUBREDDIT:
if (mAccessToken == null) {
call = api.getSubredditBestPosts(subredditName, sortType, sortTime, afterKey);
} else {
call = api.getSubredditBestPostsOauth(subredditName, sortType,
sortTime, afterKey, APIUtils.getOAuthHeader(mAccessToken));
}
call = api.getPosts(null, sortType.value, nextPage, 25, null, post.getSubredditNamePrefixed(), false, mAccessToken);
break;
case PostPagingSource.TYPE_USER:
if (mAccessToken == null) {
call = api.getUserPosts(username, afterKey, sortType, sortTime);
} else {
call = api.getUserPostsOauth(username, userWhere, afterKey, sortType,
sortTime, APIUtils.getOAuthHeader(mAccessToken));
}
call = api.getUserPosts(username, sortType.value, nextPage, 25, false, mAccessToken);
break;
case PostPagingSource.TYPE_SEARCH:
if (subredditName == null) {
if (mAccessToken == null) {
call = api.searchPosts(query, afterKey, sortType, sortTime,
trendingSource);
} else {
call = api.searchPostsOauth(query, afterKey, sortType,
sortTime, trendingSource, APIUtils.getOAuthHeader(mAccessToken));
}
} else {
if (mAccessToken == null) {
call = api.searchPostsInSpecificSubreddit(subredditName, query,
sortType, sortTime, afterKey);
} else {
call = api.searchPostsInSpecificSubredditOauth(subredditName, query,
sortType, sortTime, afterKey,
APIUtils.getOAuthHeader(mAccessToken));
}
}
call = api.search(query, null, subredditName, null, "Post", sortType.value, "All", nextPage, 25, mAccessToken);
break;
case PostPagingSource.TYPE_MULTI_REDDIT:
if (mAccessToken == null) {
call = api.getMultiRedditPosts(multiPath, afterKey, sortTime);
} else {
call = api.getMultiRedditPostsOauth(multiPath, afterKey,
sortTime, APIUtils.getOAuthHeader(mAccessToken));
}
break;
// TODO: Implement multi community
case PostPagingSource.TYPE_ANONYMOUS_FRONT_PAGE:
//case PostPagingSource.TYPE_ANONYMOUS_MULTIREDDIT
call = api.getSubredditBestPosts(subredditName, sortType, sortTime, afterKey);
break;
// TODO: Implement anonymous front page
default:
call = api.getBestPosts(sortType, sortTime, afterKey,
APIUtils.getOAuthHeader(mAccessToken));
String type = (subredditName == null) ? "Subscribed" : (subredditName.equals("all")) ? "All" : "Local";
call = api.getPosts(type, sortType.value, nextPage, 25, null, null, false, mAccessToken);
}
try {
Response<String> response = call.execute();
if (response.isSuccessful()) {
String responseString = response.body();
LinkedHashSet<Post> newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, readPostList);
LinkedHashSet<Post> newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, readPostList, postEnricher);
if (newPosts == null) {
handler.post(() -> {
loadingMorePostsStatus = LoadingMorePostsStatus.NO_MORE_POSTS;
@@ -666,7 +647,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele
Response<String> response = historyPosts.execute();
if (response.isSuccessful()) {
String responseString = response.body();
LinkedHashSet<Post> newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, null);
LinkedHashSet<Post> newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, null, postEnricher);
if (newPosts == null || newPosts.isEmpty()) {
handler.post(() -> {
loadingMorePostsStatus = LoadingMorePostsStatus.NO_MORE_POSTS;
@@ -870,6 +851,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele
bundle.putParcelable(ViewPostDetailFragment.EXTRA_POST_DATA, post);
bundle.putInt(ViewPostDetailFragment.EXTRA_POST_LIST_POSITION, position);
bundle.putInt(ViewPostDetailFragment.EXTRA_SINGLE_COMMENT_ID, getIntent().getIntExtra(EXTRA_SINGLE_COMMENT_ID, 0));
bundle.putInt(ViewPostDetailFragment.EXTRA_SINGLE_COMMENT_PARENT_ID, getIntent().getIntExtra(EXTRA_SINGLE_COMMENT_PARENT_ID, 0));
bundle.putString(ViewPostDetailFragment.EXTRA_CONTEXT_NUMBER, getIntent().getStringExtra(EXTRA_CONTEXT_NUMBER));
bundle.putString(ViewPostDetailFragment.EXTRA_MESSAGE_FULLNAME, getIntent().getStringExtra(EXTRA_MESSAGE_FULLNAME));
} else {
@@ -891,6 +873,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele
bundle.putInt(ViewPostDetailFragment.EXTRA_POST_LIST_POSITION, postListPosition);
}
bundle.putInt(ViewPostDetailFragment.EXTRA_SINGLE_COMMENT_ID, getIntent().getIntExtra(EXTRA_SINGLE_COMMENT_ID, 0));
bundle.putInt(ViewPostDetailFragment.EXTRA_SINGLE_COMMENT_PARENT_ID, getIntent().getIntExtra(EXTRA_SINGLE_COMMENT_PARENT_ID, 0));
bundle.putString(ViewPostDetailFragment.EXTRA_CONTEXT_NUMBER, getIntent().getStringExtra(EXTRA_CONTEXT_NUMBER));
bundle.putString(ViewPostDetailFragment.EXTRA_MESSAGE_FULLNAME, getIntent().getStringExtra(EXTRA_MESSAGE_FULLNAME));
}

View File

@@ -5,6 +5,7 @@ import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
@@ -27,6 +28,7 @@ import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import javax.inject.Inject;
@@ -46,14 +48,15 @@ import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed;
import eu.toldi.infinityforlemmy.events.PassPrivateMessageEvent;
import eu.toldi.infinityforlemmy.events.PassPrivateMessageIndexEvent;
import eu.toldi.infinityforlemmy.events.RepliedToPrivateMessageEvent;
import eu.toldi.infinityforlemmy.message.Message;
import eu.toldi.infinityforlemmy.message.ReadMessage;
import eu.toldi.infinityforlemmy.message.ReplyMessage;
import eu.toldi.infinityforlemmy.privatemessage.LemmyPrivateMessageAPI;
import eu.toldi.infinityforlemmy.privatemessage.PrivateMessage;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import retrofit2.Retrofit;
public class ViewPrivateMessagesActivity extends BaseActivity implements ActivityToolbarInterface {
public static final String EXTRA_PRIVATE_MESSAGE = "EPM";
public static final String EXTRA_PRIVATE_MESSAGE_INDEX = "EPM";
public static final String EXTRA_MESSAGE_POSITION = "EMP";
private static final String USER_AVATAR_STATE = "UAS";
@@ -91,14 +94,19 @@ public class ViewPrivateMessagesActivity extends BaseActivity implements Activit
CustomThemeWrapper mCustomThemeWrapper;
@Inject
Executor mExecutor;
@Inject
LemmyPrivateMessageAPI mLemmyPrivateMessageAPI;
private LinearLayoutManagerBugFixed mLinearLayoutManager;
private PrivateMessagesDetailRecyclerViewAdapter mAdapter;
@State
Message privateMessage;
PrivateMessage privateMessage;
@State
Message replyTo;
PrivateMessage replyTo;
private String mAccessToken;
private String mAccountName;
private String mAccountQualifiedName;
private String mUserAvatar;
private ArrayList<ProvideUserAvatarCallback> mProvideUserAvatarCallbacks;
private boolean isLoadingUserAvatar = false;
@@ -128,6 +136,11 @@ public class ViewPrivateMessagesActivity extends BaseActivity implements Activit
addOnOffsetChangedListener(mAppBarLayout);
}
Intent intent = getIntent();
privateMessage = intent.getParcelableExtra(EXTRA_PRIVATE_MESSAGE);
Log.i("ViewPrivate", "privateMessage: " + privateMessage);
setSupportActionBar(mToolbar);
setToolbarGoToTop(mToolbar);
@@ -135,6 +148,7 @@ public class ViewPrivateMessagesActivity extends BaseActivity implements Activit
mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null);
mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null);
mAccountQualifiedName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, null);
if (savedInstanceState != null) {
mUserAvatar = savedInstanceState.getString(USER_AVATAR_STATE);
@@ -144,36 +158,37 @@ public class ViewPrivateMessagesActivity extends BaseActivity implements Activit
bindView();
}
} else {
if (privateMessage != null) {
bindView();
}
EventBus.getDefault().post(new PassPrivateMessageIndexEvent(getIntent().getIntExtra(EXTRA_PRIVATE_MESSAGE_INDEX, -1)));
}
}
private void bindView() {
if (privateMessage != null) {
if (privateMessage.getAuthor().equals(mAccountName)) {
setTitle(privateMessage.getDestination());
if (privateMessage.getCreatorQualifiedName().equals(mAccountQualifiedName)) {
setTitle(privateMessage.getRecipientName());
mToolbar.setOnClickListener(view -> {
if (privateMessage.isDestinationDeleted()) {
return;
}
Intent intent = new Intent(this, ViewUserDetailActivity.class);
intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, privateMessage.getDestination());
intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, privateMessage.getRecipientName());
intent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, privateMessage.getRecipientQualifiedName());
startActivity(intent);
});
} else {
setTitle(privateMessage.getAuthor());
setTitle(privateMessage.getCreatorName());
mToolbar.setOnClickListener(view -> {
if (privateMessage.isAuthorDeleted()) {
return;
}
Intent intent = new Intent(this, ViewUserDetailActivity.class);
intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, privateMessage.getAuthor());
intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, privateMessage.getCreatorName());
intent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, privateMessage.getCreatorQualifiedName());
startActivity(intent);
});
}
}
mAdapter = new PrivateMessagesDetailRecyclerViewAdapter(this, mSharedPreferences,
getResources().getConfiguration().locale, privateMessage, mAccountName, mCustomThemeWrapper);
getResources().getConfiguration().locale, privateMessage, mAccountQualifiedName, mCustomThemeWrapper);
mLinearLayoutManager = new LinearLayoutManagerBugFixed(this);
mLinearLayoutManager.setStackFromEnd(true);
mRecyclerView.setLayoutManager(mLinearLayoutManager);
@@ -184,58 +199,55 @@ public class ViewPrivateMessagesActivity extends BaseActivity implements Activit
if (!mEditText.getText().toString().equals("")) {
//Send Message
if (privateMessage != null) {
ArrayList<Message> replies = privateMessage.getReplies();
List<PrivateMessage> replies = privateMessage.getReplies();
if (replyTo == null) {
replyTo = privateMessage;
}
isSendingMessage = true;
mSendImageView.setColorFilter(mSecondaryTextColor, android.graphics.PorterDuff.Mode.SRC_IN);
ReplyMessage.replyMessage(mEditText.getText().toString(), replyTo.getFullname(),
getResources().getConfiguration().locale, mOauthRetrofit, mAccessToken,
new ReplyMessage.ReplyMessageListener() {
@Override
public void replyMessageSuccess(Message message) {
if (mAdapter != null) {
mAdapter.addReply(message);
}
goToBottom();
mEditText.setText("");
mSendImageView.setColorFilter(mSendMessageIconColor, android.graphics.PorterDuff.Mode.SRC_IN);
isSendingMessage = false;
EventBus.getDefault().post(new RepliedToPrivateMessageEvent(message, getIntent().getIntExtra(EXTRA_MESSAGE_POSITION, -1)));
}
@Override
public void replyMessageFailed(String errorMessage) {
if (errorMessage != null && !errorMessage.equals("")) {
Snackbar.make(mCoordinatorLayout, errorMessage, Snackbar.LENGTH_LONG).show();
} else {
Snackbar.make(mCoordinatorLayout, R.string.reply_message_failed, Snackbar.LENGTH_LONG).show();
}
mSendImageView.setColorFilter(mSendMessageIconColor, android.graphics.PorterDuff.Mode.SRC_IN);
isSendingMessage = false;
}
});
mLemmyPrivateMessageAPI.sendPrivateMessage(mAccessToken, replyTo.getCreatorId(), mEditText.getText().toString(), new LemmyPrivateMessageAPI.PrivateMessageSentListener() {
@Override
public void onPrivateMessageSentSuccess(@NonNull PrivateMessage privateMessage) {
if (mAdapter != null) {
mAdapter.addReply(privateMessage);
}
goToBottom();
mEditText.setText("");
isSendingMessage = false;
EventBus.getDefault().post(new RepliedToPrivateMessageEvent(privateMessage, getIntent().getIntExtra(EXTRA_MESSAGE_POSITION, -1)));
}
@Override
public void onPrivateMessageSentError() {
Snackbar.make(mCoordinatorLayout, R.string.reply_message_failed, Snackbar.LENGTH_LONG).show();
mSendImageView.setColorFilter(mSendMessageIconColor, android.graphics.PorterDuff.Mode.SRC_IN);
isSendingMessage = false;
}
});
StringBuilder fullnames = new StringBuilder();
if (privateMessage.isNew()) {
fullnames.append(privateMessage.getFullname()).append(",");
}
if (replies != null && !replies.isEmpty()) {
for (Message m : replies) {
if (m.isNew()) {
for (PrivateMessage m : replies) {
if (!m.getRead()) {
fullnames.append(m).append(",");
}
}
}
if (fullnames.length() > 0) {
fullnames.deleteCharAt(fullnames.length() - 1);
ReadMessage.readMessage(mOauthRetrofit, mAccessToken, fullnames.toString(),
ReadMessage.readMessage(mOauthRetrofit, mAccessToken, 0,
new ReadMessage.ReadMessageListener() {
@Override
public void readSuccess() {}
public void readSuccess() {
}
@Override
public void readFailed() {}
public void readFailed() {
}
});
}
}
@@ -332,7 +344,7 @@ public class ViewPrivateMessagesActivity extends BaseActivity implements Activit
@Subscribe
public void onPassPrivateMessageEvent(PassPrivateMessageEvent passPrivateMessageEvent) {
privateMessage = passPrivateMessageEvent.message;
/* privateMessage = passPrivateMessageEvent.message;
if (privateMessage != null) {
if (privateMessage.getAuthor().equals(mAccountName)) {
if (privateMessage.getReplies() != null) {
@@ -351,7 +363,7 @@ public class ViewPrivateMessagesActivity extends BaseActivity implements Activit
}
bindView();
}
}*/
}
public interface ProvideUserAvatarCallback {

View File

@@ -1,14 +1,20 @@
package eu.toldi.infinityforlemmy.activities;
import static android.graphics.BitmapFactory.decodeResource;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
@@ -18,12 +24,14 @@ import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
@@ -36,6 +44,9 @@ import androidx.viewpager2.widget.ViewPager2;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;
import com.evernote.android.state.State;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.android.material.appbar.MaterialToolbar;
@@ -82,6 +93,8 @@ import eu.toldi.infinityforlemmy.bottomsheetfragments.RandomBottomSheetFragment;
import eu.toldi.infinityforlemmy.bottomsheetfragments.SortTimeBottomSheetFragment;
import eu.toldi.infinityforlemmy.bottomsheetfragments.SortTypeBottomSheetFragment;
import eu.toldi.infinityforlemmy.bottomsheetfragments.UrlMenuBottomSheetFragment;
import eu.toldi.infinityforlemmy.community.BlockCommunity;
import eu.toldi.infinityforlemmy.community.CommunityStats;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.customviews.NavigationWrapper;
import eu.toldi.infinityforlemmy.customviews.slidr.Slidr;
@@ -93,9 +106,11 @@ import eu.toldi.infinityforlemmy.fragments.SidebarFragment;
import eu.toldi.infinityforlemmy.markdown.MarkdownUtils;
import eu.toldi.infinityforlemmy.message.ReadMessage;
import eu.toldi.infinityforlemmy.multireddit.MultiReddit;
import eu.toldi.infinityforlemmy.post.MarkPostAsRead;
import eu.toldi.infinityforlemmy.post.Post;
import eu.toldi.infinityforlemmy.post.PostPagingSource;
import eu.toldi.infinityforlemmy.readpost.InsertReadPost;
import eu.toldi.infinityforlemmy.shortcut.ShortcutManager;
import eu.toldi.infinityforlemmy.subreddit.CommunitySubscription;
import eu.toldi.infinityforlemmy.subreddit.FetchSubredditData;
import eu.toldi.infinityforlemmy.subreddit.ParseSubredditData;
@@ -161,12 +176,26 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
TextView communityFullNameTextView;
@BindView(R.id.subscriber_count_text_view_view_subreddit_detail_activity)
TextView nSubscribersTextView;
@BindView(R.id.online_subscriber_count_text_view_view_subreddit_detail_activity)
TextView nOnlineSubscribersTextView;
@BindView(R.id.since_text_view_view_subreddit_detail_activity)
TextView sinceTextView;
@BindView(R.id.creation_time_text_view_view_subreddit_detail_activity)
TextView creationTimeTextView;
@BindView(R.id.active_user_count_text_view_view_subreddit_detail_activity)
TextView nActiveUsersTextView;
@BindView(R.id.post_count_text_view_view_subreddit_detail_activity)
TextView nPostsTextView;
@BindView(R.id.comment_count_text_view_view_subreddit_detail_activity)
TextView nCommentsTextView;
@BindView(R.id.subscriber_count_image_view_view_subreddit_detail_activity)
ImageView nSubscribersImageView;
@BindView(R.id.active_user_count_image_view_view_subreddit_detail_activity)
ImageView nActiveUsersImageView;
@BindView(R.id.post_count_image_view_view_subreddit_detail_activity)
ImageView nPostsImageView;
@BindView(R.id.comment_count_image_view_view_subreddit_detail_activity)
ImageView nCommentsImageView;
@BindView(R.id.community_statistics_block_view_subreddit_detail_activity)
ConstraintLayout communityStatisticsBlock;
@BindView(R.id.description_text_view_view_subreddit_detail_activity)
TextView descriptionTextView;
@Inject
@@ -196,6 +225,9 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
CustomThemeWrapper mCustomThemeWrapper;
@Inject
Executor mExecutor;
@Inject
MarkPostAsRead markPostAsRead;
private FragmentManager fragmentManager;
private SectionsPagerAdapter sectionsPagerAdapter;
private NavigationWrapper navigationWrapper;
@@ -206,6 +238,11 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
private String communityName;
private int communityId;
@State
SubredditData communityData;
@State
CommunityStats mCommunityStats;
private String description;
private String qualifiedName;
@@ -217,7 +254,7 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
private boolean hideFab;
private boolean showBottomAppBar;
private boolean lockBottomAppBar;
private String mMessageFullname;
private int mMessageFullname;
private String mNewAccountName;
private RequestManager glide;
private int expandedTabTextColor;
@@ -230,8 +267,14 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
private int subscribedColor;
private int fabOption;
private MaterialAlertDialogBuilder nsfwWarningBuilder;
private Bitmap subredditIconBitmap;
private boolean showStatistics;
private boolean disableImagePreview;
private boolean hideSubredditDescription;
private boolean isKbinMagazine = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -244,6 +287,8 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
ButterKnife.bind(this);
hideFab = mSharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_FAB_IN_POST_FEED, false);
showStatistics = mSharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_STATISTICS, true);
disableImagePreview = mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_IMAGE_PREVIEW, false);
showBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.BOTTOM_APP_BAR_KEY, false);
navigationWrapper = new NavigationWrapper(findViewById(R.id.bottom_app_bar_bottom_app_bar), findViewById(R.id.linear_layout_bottom_app_bar),
findViewById(R.id.option_1_bottom_app_bar), findViewById(R.id.option_2_bottom_app_bar),
@@ -348,27 +393,41 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
mAccountQualifiedName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, null);
if (savedInstanceState == null) {
mMessageFullname = getIntent().getStringExtra(EXTRA_MESSAGE_FULLNAME);
mMessageFullname = getIntent().getIntExtra(EXTRA_MESSAGE_FULLNAME, 0);
mNewAccountName = getIntent().getStringExtra(EXTRA_NEW_ACCOUNT_NAME);
} else {
mFetchSubredditInfoSuccess = savedInstanceState.getBoolean(FETCH_SUBREDDIT_INFO_STATE);
mNCurrentOnlineSubscribers = savedInstanceState.getInt(CURRENT_ONLINE_SUBSCRIBERS_STATE);
mMessageFullname = savedInstanceState.getString(MESSAGE_FULLNAME_STATE);
mMessageFullname = savedInstanceState.getInt(MESSAGE_FULLNAME_STATE);
mNewAccountName = savedInstanceState.getString(NEW_ACCOUNT_NAME_STATE);
if (mFetchSubredditInfoSuccess) {
nOnlineSubscribersTextView.setText(getString(R.string.online_subscribers_number_detail, mNCurrentOnlineSubscribers));
}
}
checkNewAccountAndBindView();
fetchSubredditData();
if (communityName != null) {
if (communityData != null) {
setupVisibleElements();
}
}
@Override
protected void onStart() {
super.onStart();
Log.e("ViewSubredditDetail", "onStart");
if (communityData != null) {
setupVisibleElements();
} else {
fetchSubredditData();
}
}
@Override
protected void onStop() {
super.onStop();
mFetchSubredditInfoSuccess = false;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (sectionsPagerAdapter != null) {
@@ -410,20 +469,24 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
subscribeSubredditChip.setTextColor(mCustomThemeWrapper.getChipTextColor());
int primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor();
nSubscribersTextView.setTextColor(primaryTextColor);
nOnlineSubscribersTextView.setTextColor(primaryTextColor);
sinceTextView.setTextColor(primaryTextColor);
creationTimeTextView.setTextColor(primaryTextColor);
nActiveUsersTextView.setTextColor(primaryTextColor);
nPostsTextView.setTextColor(primaryTextColor);
nCommentsTextView.setTextColor(primaryTextColor);
nSubscribersImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN);
nActiveUsersImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN);
nPostsImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN);
nCommentsImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN);
descriptionTextView.setTextColor(primaryTextColor);
navigationWrapper.applyCustomTheme(mCustomThemeWrapper.getBottomAppBarIconColor(), mCustomThemeWrapper.getBottomAppBarBackgroundColor());
applyTabLayoutTheme(tabLayout);
applyFABTheme(navigationWrapper.floatingActionButton);
applyFABTheme(navigationWrapper.floatingActionButton, mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false));
if (typeface != null) {
subredditNameTextView.setTypeface(typeface);
subscribeSubredditChip.setTypeface(typeface);
nSubscribersTextView.setTypeface(typeface);
nOnlineSubscribersTextView.setTypeface(typeface);
sinceTextView.setTypeface(typeface);
creationTimeTextView.setTypeface(typeface);
nActiveUsersTextView.setTypeface(typeface);
nPostsTextView.setTypeface(typeface);
nCommentsTextView.setTypeface(typeface);
descriptionTextView.setTypeface(typeface);
}
unsubscribedColor = mCustomThemeWrapper.getUnsubscribed();
@@ -462,7 +525,7 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
setSupportActionBar(toolbar);
setToolbarGoToTop(toolbar);
glide = Glide.with(this);
glide = Glide.with(getApplication());
Locale locale = getResources().getConfiguration().locale;
MarkwonPlugin miscPlugin = new AbstractMarkwonPlugin() {
@@ -487,7 +550,7 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
return true;
};
Markwon markwon = MarkdownUtils.createDescriptionMarkwon(this, miscPlugin, onLinkLongClickListener);
Markwon markwon = MarkdownUtils.createDescriptionMarkwon(this, miscPlugin, onLinkLongClickListener, mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_IMAGE_PREVIEW, false));
descriptionTextView.setOnLongClickListener(view -> {
if (description != null && !description.equals("") && descriptionTextView.getSelectionStart() == -1 && descriptionTextView.getSelectionEnd() == -1) {
@@ -495,10 +558,14 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
}
return true;
});
String actorID = (!isKbinMagazine) ? LemmyUtils.qualifiedCommunityName2ActorId(qualifiedName) : LemmyUtils.qualifiedMagazineName2ActorId(qualifiedName);
mSubredditViewModel = new ViewModelProvider(this,
new SubredditViewModel.Factory(getApplication(), mRedditDataRoomDatabase, LemmyUtils.qualifiedCommunityName2ActorId(qualifiedName)))
new SubredditViewModel.Factory(getApplication(), mRedditDataRoomDatabase, actorID))
.get(SubredditViewModel.class);
addObserverToLiveData();
}
private void addObserverToLiveData() {
mSubredditViewModel.getSubredditLiveData().observe(this, subredditData -> {
if (subredditData != null) {
isNsfwSubreddit = subredditData.isNSFW();
@@ -524,11 +591,23 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
.into(iconGifImageView);
iconGifImageView.setOnClickListener(null);
} else {
glide.load(subredditData.getIconUrl())
glide.asBitmap()
.load(subredditData.getIconUrl())
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(216, 0)))
.error(glide.load(R.drawable.subreddit_default_icon)
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(216, 0))))
.into(iconGifImageView);
.into(new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
subredditIconBitmap = resource;
iconGifImageView.setImageBitmap(resource);
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
subredditIconBitmap = null;
}
});
iconGifImageView.setOnClickListener(view -> {
Intent intent = new Intent(ViewSubredditDetailActivity.this, ViewImageOrGifActivity.class);
intent.putExtra(ViewImageOrGifActivity.EXTRA_IMAGE_URL_KEY, subredditData.getIconUrl());
@@ -547,15 +626,18 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
communityFullNameTextView.setText(qualifiedName);
String nSubscribers = getString(R.string.subscribers_number_detail, subredditData.getNSubscribers());
nSubscribersTextView.setText(nSubscribers);
creationTimeTextView.setText(subredditData.getCreatedUTC());
if (mCommunityStats != null && showStatistics) {
communityStatisticsBlock.setVisibility(View.VISIBLE);
nActiveUsersTextView.setText(getString(R.string.active_users_number_detail, mCommunityStats.getActiveUsers()));
nPostsTextView.setText(getString(R.string.post_count_detail, mCommunityStats.getPosts()));
nCommentsTextView.setText(getString(R.string.comment_count_detail, mCommunityStats.getComments()));
}
description = subredditData.getDescription();
if (hideSubredditDescription || description.equals("")) {
descriptionTextView.setVisibility(View.GONE);
} else {
descriptionTextView.setVisibility(View.VISIBLE);
markwon.setMarkdown(descriptionTextView, description);
}
descriptionTextView.setVisibility(View.GONE);
if (subredditData.isNSFW()) {
if (nsfwWarningBuilder == null
@@ -689,14 +771,23 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
qualifiedName = LemmyUtils.actorID2FullName(communityData.getActorId());
if (communityName == null) {
communityName = communityData.getTitle();
setupVisibleElements();
}
mCommunityStats = communityData.getCommunityStats();
if (communityData.getActorId().contains("/m/")) {
isKbinMagazine = true;
if (mSubredditViewModel != null) {
// Remove current observer
mSubredditViewModel.getSubredditLiveData().removeObservers(ViewSubredditDetailActivity.this);
addObserverToLiveData();
}
}
setupVisibleElements();
communityId = communityData.getId();
ViewSubredditDetailActivity.this.communityData = communityData;
setupSubscribeChip();
mNCurrentOnlineSubscribers = nCurrentOnlineSubscribers;
nOnlineSubscribersTextView.setText(getString(R.string.online_subscribers_number_detail, nCurrentOnlineSubscribers));
InsertSubredditData.insertSubredditData(mExecutor, new Handler(), mRedditDataRoomDatabase,
communityData, () -> mFetchSubredditInfoSuccess = true);
}
@@ -729,6 +820,7 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_PROFILE: {
Intent intent = new Intent(this, ViewUserDetailActivity.class);
intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mAccountName);
intent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, mAccountQualifiedName);
startActivity(intent);
break;
}
@@ -868,11 +960,11 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
}
private void bindView() {
if (mMessageFullname != null) {
if (mMessageFullname != 0) {
ReadMessage.readMessage(mRetrofit.getRetrofit(), mAccessToken, mMessageFullname, new ReadMessage.ReadMessageListener() {
@Override
public void readSuccess() {
mMessageFullname = null;
mMessageFullname = 0;
}
@Override
@@ -1092,7 +1184,7 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
}
});
viewPager2.setAdapter(sectionsPagerAdapter);
viewPager2.setOffscreenPageLimit(2);
viewPager2.setOffscreenPageLimit(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT);
viewPager2.setUserInputEnabled(!mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS, false));
new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> {
switch (position) {
@@ -1122,6 +1214,11 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.view_subreddit_detail_activity, menu);
if (communityData != null && communityData.isBlocked()) {
menu.findItem(R.id.block_community_view_subreddit_detail_activity).setVisible(false);
} else {
menu.findItem(R.id.unblock_community_view_subreddit_detail_activity).setVisible(false);
}
applyMenuItemTheme(menu);
return true;
}
@@ -1150,22 +1247,6 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
PostLayoutBottomSheetFragment postLayoutBottomSheetFragment = new PostLayoutBottomSheetFragment();
postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag());
return true;
} else if (itemId == R.id.action_select_user_flair_view_subreddit_detail_activity) {
if (mAccessToken == null) {
Toast.makeText(this, R.string.login_first, Toast.LENGTH_SHORT).show();
return true;
}
Intent selectUserFlairIntent = new Intent(this, SelectUserFlairActivity.class);
selectUserFlairIntent.putExtra(SelectUserFlairActivity.EXTRA_SUBREDDIT_NAME, communityName);
startActivity(selectUserFlairIntent);
return true;
} else if (itemId == R.id.action_add_to_multireddit_view_subreddit_detail_activity) {
if (mAccessToken == null) {
Toast.makeText(this, R.string.login_first, Toast.LENGTH_SHORT).show();
return true;
}
Intent intent = new Intent(this, MultiredditSelectionActivity.class);
startActivityForResult(intent, ADD_TO_MULTIREDDIT_REQUEST_CODE);
} else if (itemId == R.id.action_add_to_post_filter_view_subreddit_detail_activity) {
Intent intent = new Intent(this, PostFilterPreferenceActivity.class);
intent.putExtra(PostFilterPreferenceActivity.EXTRA_SUBREDDIT_NAME, communityName);
@@ -1175,24 +1256,63 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
String baseURL = mRetrofit.getBaseURL().endsWith("/") ? mRetrofit.getBaseURL() : mRetrofit.getBaseURL() + "/";
shareIntent.putExtra(Intent.EXTRA_TEXT, baseURL + "/" + qualifiedName);
shareIntent.putExtra(Intent.EXTRA_TEXT, baseURL + "c/" + qualifiedName);
if (shareIntent.resolveActivity(getPackageManager()) != null) {
startActivity(Intent.createChooser(shareIntent, getString(R.string.share)));
} else {
Toast.makeText(this, R.string.no_app, Toast.LENGTH_SHORT).show();
}
return true;
} else if (itemId == R.id.action_go_to_wiki_view_subreddit_detail_activity) {
Intent wikiIntent = new Intent(this, WikiActivity.class);
wikiIntent.putExtra(WikiActivity.EXTRA_SUBREDDIT_NAME, communityName);
wikiIntent.putExtra(WikiActivity.EXTRA_WIKI_PATH, "index");
startActivity(wikiIntent);
return true;
} else if (itemId == R.id.action_contact_mods_view_subreddit_detail_activity) {
Intent intent = new Intent(this, SendPrivateMessageActivity.class);
intent.putExtra(SendPrivateMessageActivity.EXTRA_RECIPIENT_USERNAME, "r/" + communityName);
startActivity(intent);
/* Intent intent = new Intent(this, SendPrivateMessageActivity.class);
intent.putExtra(SendPrivateMessageActivity.EXTRA_RECIPIENT_USERNAME, "r/" + communityName);*/
//startActivity(intent);
return true;
} else if (itemId == R.id.block_community_view_subreddit_detail_activity) {
if (mAccessToken == null) {
Toast.makeText(this, R.string.login_first, Toast.LENGTH_SHORT).show();
return true;
}
new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme)
.setTitle(R.string.block_community)
.setMessage(R.string.are_you_sure)
.setPositiveButton(R.string.yes, (dialogInterface, i)
-> BlockCommunity.INSTANCE.blockCommunity(mRetrofit.getRetrofit(), communityId, mAccessToken, new BlockCommunity.BlockCommunityListener() {
@Override
public void onBlockCommunitySuccess() {
communityData.setBlocked(true);
Toast.makeText(ViewSubredditDetailActivity.this, R.string.block_community_success, Toast.LENGTH_SHORT).show();
ViewSubredditDetailActivity.this.invalidateOptionsMenu();
sectionsPagerAdapter.refresh(false);
}
@Override
public void onBlockCommunityError() {
Toast.makeText(ViewSubredditDetailActivity.this, R.string.block_community_failed, Toast.LENGTH_SHORT).show();
}
}))
.setNegativeButton(R.string.no, null)
.show();
return true;
} else if (itemId == R.id.unblock_community_view_subreddit_detail_activity) {
BlockCommunity.INSTANCE.unBlockCommunity(mRetrofit.getRetrofit(), communityId, mAccessToken, new BlockCommunity.BlockCommunityListener() {
@Override
public void onBlockCommunitySuccess() {
communityData.setBlocked(false);
Toast.makeText(ViewSubredditDetailActivity.this, R.string.unblock_community_success, Toast.LENGTH_SHORT).show();
ViewSubredditDetailActivity.this.invalidateOptionsMenu();
sectionsPagerAdapter.refresh(false);
}
@Override
public void onBlockCommunityError() {
Toast.makeText(ViewSubredditDetailActivity.this, R.string.unblock_community_failed, Toast.LENGTH_SHORT).show();
}
});
return true;
} else if (itemId == R.id.action_add_to_home_screen_view_subreddit_detail_activity) {
Bitmap icon = subredditIconBitmap == null ? decodeResource(getResources(), R.drawable.subreddit_default_icon) : subredditIconBitmap;
return ShortcutManager.requestPinShortcut(this, qualifiedName, icon);
}
return false;
}
@@ -1230,7 +1350,7 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
super.onSaveInstanceState(outState);
outState.putBoolean(FETCH_SUBREDDIT_INFO_STATE, mFetchSubredditInfoSuccess);
outState.putInt(CURRENT_ONLINE_SUBSCRIBERS_STATE, mNCurrentOnlineSubscribers);
outState.putString(MESSAGE_FULLNAME_STATE, mMessageFullname);
outState.putInt(MESSAGE_FULLNAME_STATE, mMessageFullname);
outState.putString(NEW_ACCOUNT_NAME_STATE, mNewAccountName);
}
@@ -1284,27 +1404,27 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
break;
case PostTypeBottomSheetFragment.TYPE_LINK:
intent = new Intent(this, PostLinkActivity.class);
intent.putExtra(PostLinkActivity.EXTRA_SUBREDDIT_NAME, communityName);
intent.putExtra(PostLinkActivity.EXTRA_SUBREDDIT_NAME, qualifiedName);
startActivity(intent);
break;
case PostTypeBottomSheetFragment.TYPE_IMAGE:
intent = new Intent(this, PostImageActivity.class);
intent.putExtra(PostImageActivity.EXTRA_SUBREDDIT_NAME, communityName);
intent.putExtra(PostImageActivity.EXTRA_SUBREDDIT_NAME, qualifiedName);
startActivity(intent);
break;
case PostTypeBottomSheetFragment.TYPE_VIDEO:
intent = new Intent(this, PostVideoActivity.class);
intent.putExtra(PostVideoActivity.EXTRA_SUBREDDIT_NAME, communityName);
intent.putExtra(PostVideoActivity.EXTRA_SUBREDDIT_NAME, qualifiedName);
startActivity(intent);
break;
case PostTypeBottomSheetFragment.TYPE_GALLERY:
intent = new Intent(this, PostGalleryActivity.class);
intent.putExtra(PostGalleryActivity.EXTRA_SUBREDDIT_NAME, communityName);
intent.putExtra(PostGalleryActivity.EXTRA_SUBREDDIT_NAME, qualifiedName);
startActivity(intent);
break;
case PostTypeBottomSheetFragment.TYPE_POLL:
intent = new Intent(this, PostPollActivity.class);
intent.putExtra(PostPollActivity.EXTRA_SUBREDDIT_NAME, communityName);
intent.putExtra(PostPollActivity.EXTRA_SUBREDDIT_NAME, qualifiedName);
startActivity(intent);
}
}
@@ -1398,10 +1518,6 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
goToUser();
break;
}
case FABMoreOptionsBottomSheetFragment.FAB_RANDOM: {
random();
break;
}
case FABMoreOptionsBottomSheetFragment.FAB_HIDE_READ_POSTS: {
if (sectionsPagerAdapter != null) {
sectionsPagerAdapter.hideReadPosts();
@@ -1441,7 +1557,11 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
if (i == EditorInfo.IME_ACTION_DONE) {
Utils.hideKeyboard(this);
Intent subredditIntent = new Intent(this, ViewSubredditDetailActivity.class);
subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, thingEditText.getText().toString());
String communityName = thingEditText.getText().toString();
if (communityName.startsWith("!")) {
communityName = communityName.substring(1);
}
subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_COMMUNITY_FULL_NAME_KEY, communityName);
startActivity(subredditIntent);
return true;
}
@@ -1499,7 +1619,11 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
-> {
Utils.hideKeyboard(this);
Intent subredditIntent = new Intent(this, ViewSubredditDetailActivity.class);
subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, thingEditText.getText().toString());
String communityName = thingEditText.getText().toString();
if (communityName.startsWith("!")) {
communityName = communityName.substring(1);
}
subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_COMMUNITY_FULL_NAME_KEY, communityName);
startActivity(subredditIntent);
})
.setNegativeButton(R.string.cancel, (dialogInterface, i) -> {
@@ -1520,7 +1644,11 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
if (i == EditorInfo.IME_ACTION_DONE) {
Utils.hideKeyboard(this);
Intent userIntent = new Intent(this, ViewUserDetailActivity.class);
userIntent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, thingEditText.getText().toString());
String qualifiedName = thingEditText.getText().toString();
if (qualifiedName.startsWith("@")) {
qualifiedName = qualifiedName.substring(1);
}
userIntent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, qualifiedName);
startActivity(userIntent);
return true;
}
@@ -1533,7 +1661,11 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
-> {
Utils.hideKeyboard(this);
Intent userIntent = new Intent(this, ViewUserDetailActivity.class);
userIntent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, thingEditText.getText().toString());
String qualifiedName = thingEditText.getText().toString();
if (qualifiedName.startsWith("@")) {
qualifiedName = qualifiedName.substring(1);
}
userIntent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, qualifiedName);
startActivity(userIntent);
})
.setNegativeButton(R.string.cancel, (dialogInterface, i) -> {
@@ -1562,7 +1694,18 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
@Override
public void markPostAsRead(Post post) {
InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, mAccountName, post.getId());
markPostAsRead.markPostAsRead(post.getId(), mAccessToken, new MarkPostAsRead.MarkPostAsReadListener() {
@Override
public void onMarkPostAsReadSuccess() {
InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, mAccountQualifiedName, post.getId());
}
@Override
public void onMarkPostAsReadFailed() {
Toast.makeText(ViewSubredditDetailActivity.this, R.string.mark_post_as_read_failed, Toast.LENGTH_SHORT).show();
}
});
}
@Override
@@ -1603,6 +1746,8 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
bundle.putString(SidebarFragment.EXTRA_ACCESS_TOKEN, mAccessToken);
bundle.putString(SidebarFragment.EXTRA_SUBREDDIT_NAME, communityName);
bundle.putString(SidebarFragment.EXTRA_COMMUNITY_QUALIFIED_NAME, qualifiedName);
bundle.putBoolean(SidebarFragment.EXTRA_SHOW_STATISTICS, !showStatistics);
bundle.putBoolean(SidebarFragment.EXTRA_DISABLE_IMAGE_PREVIEW, disableImagePreview);
fragment.setArguments(bundle);
return fragment;
}

View File

@@ -4,6 +4,7 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.PorterDuff;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
@@ -20,12 +21,15 @@ import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
@@ -52,6 +56,7 @@ import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.Executor;
@@ -71,11 +76,14 @@ import eu.toldi.infinityforlemmy.RedditDataRoomDatabase;
import eu.toldi.infinityforlemmy.RetrofitHolder;
import eu.toldi.infinityforlemmy.SortType;
import eu.toldi.infinityforlemmy.SortTypeSelectionCallback;
import eu.toldi.infinityforlemmy.account.FetchBlockedThings;
import eu.toldi.infinityforlemmy.adapters.SubredditAutocompleteRecyclerViewAdapter;
import eu.toldi.infinityforlemmy.apis.RedditAPI;
import eu.toldi.infinityforlemmy.asynctasks.AddSubredditOrUserToMultiReddit;
import eu.toldi.infinityforlemmy.asynctasks.CheckIsFollowingUser;
import eu.toldi.infinityforlemmy.asynctasks.SwitchAccount;
import eu.toldi.infinityforlemmy.blockedcommunity.BlockedCommunityData;
import eu.toldi.infinityforlemmy.blockeduser.BlockedUserData;
import eu.toldi.infinityforlemmy.bottomsheetfragments.CopyTextBottomSheetFragment;
import eu.toldi.infinityforlemmy.bottomsheetfragments.FABMoreOptionsBottomSheetFragment;
import eu.toldi.infinityforlemmy.bottomsheetfragments.PostLayoutBottomSheetFragment;
@@ -95,16 +103,19 @@ import eu.toldi.infinityforlemmy.fragments.PostFragment;
import eu.toldi.infinityforlemmy.markdown.MarkdownUtils;
import eu.toldi.infinityforlemmy.message.ReadMessage;
import eu.toldi.infinityforlemmy.multireddit.MultiReddit;
import eu.toldi.infinityforlemmy.post.MarkPostAsRead;
import eu.toldi.infinityforlemmy.post.Post;
import eu.toldi.infinityforlemmy.post.PostPagingSource;
import eu.toldi.infinityforlemmy.readpost.InsertReadPost;
import eu.toldi.infinityforlemmy.subreddit.ParseSubredditData;
import eu.toldi.infinityforlemmy.subreddit.SubredditData;
import eu.toldi.infinityforlemmy.user.BasicUserInfo;
import eu.toldi.infinityforlemmy.user.BlockUser;
import eu.toldi.infinityforlemmy.user.FetchUserData;
import eu.toldi.infinityforlemmy.user.UserDao;
import eu.toldi.infinityforlemmy.user.UserData;
import eu.toldi.infinityforlemmy.user.UserFollowing;
import eu.toldi.infinityforlemmy.user.UserStats;
import eu.toldi.infinityforlemmy.user.UserViewModel;
import eu.toldi.infinityforlemmy.utils.APIUtils;
import eu.toldi.infinityforlemmy.utils.LemmyUtils;
@@ -140,6 +151,7 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
private static final String FETCH_USER_INFO_STATE = "FSIS";
private static final String MESSAGE_FULLNAME_STATE = "MFS";
private static final String NEW_ACCOUNT_NAME_STATE = "NANS";
private static final String NEW_ACCOUNT_QUALIFIED_NAME_STATE = "NAQNS";
@BindView(R.id.coordinator_layout_view_user_detail_activity)
CoordinatorLayout coordinatorLayout;
@@ -164,11 +176,40 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
@BindView(R.id.user_qualified_name_text_view_view_user_detail_activity)
TextView qualifiedNameTextView;
@BindView(R.id.loading_user_progress_indicator_view_user_detail_activity)
ProgressBar progressBar;
@BindView(R.id.subscribe_user_chip_view_user_detail_activity)
Chip subscribeUserChip;
@BindView(R.id.karma_text_view_view_user_detail_activity)
TextView karmaTextView;
@BindView(R.id.cakeday_text_view_view_user_detail_activity)
@BindView(R.id.post_count_text_view_view_user_detail_activity)
TextView postCountTextView;
@BindView(R.id.comment_count_text_view_view_user_detail_activity)
TextView commentCountTextView;
@BindView(R.id.upvote_count_post_text_view_view_user_detail_activity)
TextView upvoteCountPostTextView;
@BindView(R.id.upvote_count_comment_text_view_view_user_detail_activity)
TextView upvoteCountCommentTextView;
@BindView(R.id.posts_count_icon_image_view_view_user_detail_activity)
ImageView postsCountIconImageView;
@BindView(R.id.comments_count_icon_image_view_view_user_detail_activity)
ImageView commentsCountIconImageView;
@BindView(R.id.upvote_count_posts_icon_image_view_view_user_detail_activity)
ImageView postUpvoteCountIconImageView;
@BindView(R.id.upvote_count_comments_icon_image_view_view_user_detail_activity)
ImageView commentUpvoteCountIconImageView;
@BindView(R.id.account_created_cake_icon_image_view_view_user_detail_activity)
ImageView accountCreatedCakeIconImageView;
@BindView(R.id.user_statistics_block_view_user_detail_activity)
ConstraintLayout userStatisticsBlock;
@BindView(R.id.cake_day_text_view_view_user_detail_activity)
TextView cakedayTextView;
@BindView(R.id.description_text_view_view_user_detail_activity)
TextView descriptionTextView;
@@ -202,6 +243,9 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
CustomThemeWrapper mCustomThemeWrapper;
@Inject
Executor mExecutor;
@Inject
MarkPostAsRead markPostAsRead;
public UserViewModel userViewModel;
private FragmentManager fragmentManager;
private SectionsPagerAdapter sectionsPagerAdapter;
@@ -210,9 +254,14 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
private Call<String> subredditAutocompleteCall;
private String mAccessToken;
private String mAccountName;
private String mAccountQualifiedName;
private String username;
private String qualifiedName;
private String description;
private boolean showStatistics;
private boolean showScore;
private boolean subscriptionReady = false;
private boolean mFetchUserInfoSuccess = false;
private int expandedTabTextColor;
@@ -228,11 +277,13 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
private boolean hideFab;
private boolean showBottomAppBar;
private boolean lockBottomAppBar;
private String mMessageFullname;
private int mMessageId;
private String mNewAccountName;
private UserData mUserData;
private boolean isBlocked;
//private MaterialAlertDialogBuilder nsfwWarningBuilder;
@Override
@@ -272,16 +323,20 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null);
mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null);
mAccountQualifiedName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, null);
lockBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.LOCK_BOTTOM_APP_BAR, false);
showStatistics = mSharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_STATISTICS, true);
showScore = mSharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_POST_AND_COMMENT_SCORE, true);
if (savedInstanceState == null) {
mMessageFullname = getIntent().getStringExtra(EXTRA_MESSAGE_FULLNAME);
mMessageId = getIntent().getIntExtra(EXTRA_MESSAGE_FULLNAME, 0);
mNewAccountName = getIntent().getStringExtra(EXTRA_NEW_ACCOUNT_NAME);
} else {
mFetchUserInfoSuccess = savedInstanceState.getBoolean(FETCH_USER_INFO_STATE);
mMessageFullname = savedInstanceState.getString(MESSAGE_FULLNAME_STATE);
mMessageId = savedInstanceState.getInt(MESSAGE_FULLNAME_STATE);
mNewAccountName = savedInstanceState.getString(NEW_ACCOUNT_NAME_STATE);
qualifiedName = savedInstanceState.getString("qualified_name");
}
checkNewAccountAndInitializeViewPager();
@@ -293,9 +348,26 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
}
}
@Override
protected void onStart() {
super.onStart();
if (mUserData != null) {
setupVisibleElements();
} else {
fetchUserInfo();
}
}
@Override
protected void onStop() {
super.onStop();
mFetchUserInfoSuccess = false;
}
private void setupVisibleElements() {
Resources resources = getResources();
String title = username;
progressBar.setVisibility(View.GONE);
userNameTextView.setText(title);
qualifiedNameTextView.setText(qualifiedName);
toolbar.setTitle(title);
@@ -376,7 +448,7 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
});
}
glide = Glide.with(this);
glide = Glide.with(getApplication());
Locale locale = getResources().getConfiguration().locale;
MarkwonPlugin miscPlugin = new AbstractMarkwonPlugin() {
@@ -400,7 +472,7 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
urlMenuBottomSheetFragment.show(getSupportFragmentManager(), null);
return true;
};
Markwon markwon = MarkdownUtils.createDescriptionMarkwon(this, miscPlugin, onLinkLongClickListener);
Markwon markwon = MarkdownUtils.createDescriptionMarkwon(this, miscPlugin, onLinkLongClickListener, mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_IMAGE_PREVIEW, false));
descriptionTextView.setOnLongClickListener(view -> {
if (description != null && !description.equals("") && descriptionTextView.getSelectionStart() == -1 && descriptionTextView.getSelectionEnd() == -1) {
@@ -553,8 +625,23 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
getSupportActionBar().setTitle(userFullName);
}
String karma = "";//getString(R.string.karma_info_user_detail, userData.getTotalKarma(), userData.getLinkKarma(), userData.getCommentKarma());
karmaTextView.setText(karma);
cakedayTextView.setText(getString(R.string.cakeday_info, userData.getCakeday()));
cakedayTextView.setText((String) userData.getCakeday());
UserStats userStats = mUserData.getStats();
if (userStats != null && showStatistics) {
userStatisticsBlock.setVisibility(View.VISIBLE);
postCountTextView.setText(String.valueOf(userStats.getPostCount()));
commentCountTextView.setText(String.valueOf(userStats.getCommentCount()));
if (showScore) {
upvoteCountPostTextView.setText(String.valueOf(userStats.getPostScore()));
upvoteCountCommentTextView.setText(String.valueOf(userStats.getCommentScore()));
} else {
upvoteCountPostTextView.setVisibility(View.GONE);
upvoteCountCommentTextView.setVisibility(View.GONE);
postUpvoteCountIconImageView.setVisibility(View.GONE);
commentUpvoteCountIconImageView.setVisibility(View.GONE);
}
}
if (userData.getDescription() == null || userData.getDescription().equals("")) {
descriptionTextView.setVisibility(View.GONE);
@@ -622,16 +709,25 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
unsubscribedColor = mCustomThemeWrapper.getUnsubscribed();
subscribedColor = mCustomThemeWrapper.getSubscribed();
userNameTextView.setTextColor(mCustomThemeWrapper.getUsername());
karmaTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor());
postCountTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor());
upvoteCountPostTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor());
commentCountTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor());
upvoteCountCommentTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor());
postsCountIconImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN);
commentsCountIconImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN);
accountCreatedCakeIconImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN);
cakedayTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor());
navigationWrapper.applyCustomTheme(mCustomThemeWrapper.getBottomAppBarIconColor(), mCustomThemeWrapper.getBottomAppBarBackgroundColor());
applyFABTheme(navigationWrapper.floatingActionButton);
applyFABTheme(navigationWrapper.floatingActionButton, mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false));
descriptionTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor());
subscribeUserChip.setTextColor(mCustomThemeWrapper.getChipTextColor());
applyTabLayoutTheme(tabLayout);
if (typeface != null) {
userNameTextView.setTypeface(typeface);
karmaTextView.setTypeface(typeface);
postCountTextView.setTypeface(typeface);
upvoteCountPostTextView.setTypeface(typeface);
commentCountTextView.setTypeface(typeface);
upvoteCountCommentTextView.setTypeface(typeface);
cakedayTextView.setTypeface(typeface);
subscribeUserChip.setTypeface(typeface);
descriptionTextView.setTypeface(typeface);
@@ -665,7 +761,7 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
private void initializeViewPager() {
sectionsPagerAdapter = new SectionsPagerAdapter(this);
viewPager2.setAdapter(sectionsPagerAdapter);
viewPager2.setOffscreenPageLimit(2);
viewPager2.setOffscreenPageLimit(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT);
viewPager2.setUserInputEnabled(!mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS, false));
new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> {
switch (position) {
@@ -700,11 +796,11 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
fixViewPager2Sensitivity(viewPager2);
if (mMessageFullname != null) {
ReadMessage.readMessage(mOauthRetrofit, mAccessToken, mMessageFullname, new ReadMessage.ReadMessageListener() {
if (mMessageId != 0) {
ReadMessage.readMessage(mOauthRetrofit, mAccessToken, mMessageId, new ReadMessage.ReadMessageListener() {
@Override
public void readSuccess() {
mMessageFullname = null;
mMessageId = 0;
}
@Override
@@ -923,6 +1019,7 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_PROFILE: {
Intent intent = new Intent(this, ViewUserDetailActivity.class);
intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mAccountName);
intent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY,mAccountQualifiedName);
startActivity(intent);
break;
}
@@ -1077,8 +1174,27 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
@Override
public void onFetchUserDataSuccess(UserData userData, int inboxCount) {
mUserData = userData;
username = userData.getName();
username = userData.getDisplayName();
setupVisibleElements();
FetchBlockedThings.fetchBlockedThings(mRetrofit.getRetrofit(), mAccessToken, mAccountQualifiedName, new FetchBlockedThings.FetchBlockedThingsListener() {
@Override
public void onFetchBlockedThingsSuccess(List<BlockedUserData> blockedUsers, List<BlockedCommunityData> blockedCommunities) {
for (BlockedUserData blockedUserData : blockedUsers) {
if (blockedUserData.getQualifiedName().equals(qualifiedName)) {
isBlocked = true;
invalidateOptionsMenu();
return;
}
}
isBlocked = false;
invalidateOptionsMenu();
}
@Override
public void onFetchBlockedThingsFailure() {
}
});
new ViewUserDetailActivity.InsertUserDataAsyncTask(mRedditDataRoomDatabase.userDao(), userData,
() -> mFetchUserInfoSuccess = true).execute();
}
@@ -1092,12 +1208,12 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
}
}
public void deleteComment(String fullName) {
public void deleteComment(int commentId) {
new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme)
.setTitle(R.string.delete_this_comment)
.setMessage(R.string.are_you_sure)
.setPositiveButton(R.string.delete, (dialogInterface, i)
-> DeleteThing.delete(mOauthRetrofit, fullName, mAccessToken, new DeleteThing.DeleteThingListener() {
-> DeleteThing.deleteComment(mRetrofit.getRetrofit(), commentId, mAccessToken, new DeleteThing.DeleteThingListener() {
@Override
public void deleteSuccess() {
Toast.makeText(ViewUserDetailActivity.this, R.string.delete_post_success, Toast.LENGTH_SHORT).show();
@@ -1121,6 +1237,12 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
menu.findItem(R.id.action_block_user_view_user_detail_activity).setVisible(false);
} else {
menu.findItem(R.id.action_edit_profile_view_user_detail_activity).setVisible(false);
if (isBlocked) {
menu.findItem(R.id.action_block_user_view_user_detail_activity).setVisible(false);
menu.findItem(R.id.action_unblock_user_view_user_detail_activity).setVisible(true);
} else {
menu.findItem(R.id.action_unblock_user_view_user_detail_activity).setVisible(false);
}
}
applyMenuItemTheme(menu);
return true;
@@ -1155,7 +1277,7 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
String baseURL = mRetrofit.getBaseURL().endsWith("/") ? mRetrofit.getBaseURL() : mRetrofit.getBaseURL() + "/";
shareIntent.putExtra(Intent.EXTRA_TEXT, baseURL + qualifiedName);
shareIntent.putExtra(Intent.EXTRA_TEXT, baseURL + "u/" + qualifiedName);
if (shareIntent.resolveActivity(getPackageManager()) != null) {
startActivity(Intent.createChooser(shareIntent, getString(R.string.share)));
} else {
@@ -1169,16 +1291,9 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
}
Intent pmIntent = new Intent(this, SendPrivateMessageActivity.class);
pmIntent.putExtra(SendPrivateMessageActivity.EXTRA_RECIPIENT_USERNAME, username);
pmIntent.putExtra(SendPrivateMessageActivity.EXTRA_RECIPIENT_USER_INFO, new BasicUserInfo(mUserData.getId(), username, qualifiedName, mUserData.getAvatar(), mUserData.getDisplayName()));
startActivity(pmIntent);
return true;
} else if (itemId == R.id.action_add_to_multireddit_view_user_detail_activity) {
if (mAccessToken == null) {
Toast.makeText(this, R.string.login_first, Toast.LENGTH_SHORT).show();
return true;
}
Intent intent = new Intent(this, MultiredditSelectionActivity.class);
startActivityForResult(intent, ADD_TO_MULTIREDDIT_REQUEST_CODE);
} else if (itemId == R.id.action_add_to_post_filter_view_user_detail_activity) {
Intent intent = new Intent(this, PostFilterPreferenceActivity.class);
intent.putExtra(PostFilterPreferenceActivity.EXTRA_USER_NAME, username);
@@ -1199,10 +1314,13 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
.setTitle(R.string.block_user)
.setMessage(R.string.are_you_sure)
.setPositiveButton(R.string.yes, (dialogInterface, i)
-> BlockUser.blockUser(mOauthRetrofit, mAccessToken, username, new BlockUser.BlockUserListener() {
-> BlockUser.blockUser(mRetrofit.getRetrofit(), mAccessToken, mUserData.getId(), true, new BlockUser.BlockUserListener() {
@Override
public void success() {
Toast.makeText(ViewUserDetailActivity.this, R.string.block_user_success, Toast.LENGTH_SHORT).show();
isBlocked = true;
sectionsPagerAdapter.refresh();
invalidateOptionsMenu();
}
@Override
@@ -1216,6 +1334,25 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
} else if (itemId == R.id.action_edit_profile_view_user_detail_activity) {
startActivity(new Intent(this, EditProfileActivity.class));
return true;
} else if (itemId == R.id.action_unblock_user_view_user_detail_activity) {
if (mAccessToken == null) {
Toast.makeText(this, R.string.login_first, Toast.LENGTH_SHORT).show();
return true;
}
BlockUser.blockUser(mRetrofit.getRetrofit(), mAccessToken, mUserData.getId(), false, new BlockUser.BlockUserListener() {
@Override
public void success() {
isBlocked = false;
Toast.makeText(ViewUserDetailActivity.this, R.string.unblock_user_success, Toast.LENGTH_SHORT).show();
sectionsPagerAdapter.refresh();
invalidateOptionsMenu();
}
@Override
public void failed() {
Toast.makeText(ViewUserDetailActivity.this, R.string.unblock_user_failed, Toast.LENGTH_SHORT).show();
}
});
}
return false;
}
@@ -1262,8 +1399,10 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(FETCH_USER_INFO_STATE, mFetchUserInfoSuccess);
outState.putString(MESSAGE_FULLNAME_STATE, mMessageFullname);
outState.putInt(MESSAGE_FULLNAME_STATE, mMessageId);
outState.putString(NEW_ACCOUNT_NAME_STATE, mNewAccountName);
outState.putString(NEW_ACCOUNT_QUALIFIED_NAME_STATE, mAccountQualifiedName);
outState.putString("qualified_name", qualifiedName);
}
@Override
@@ -1335,10 +1474,7 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
goToUser();
break;
}
case FABMoreOptionsBottomSheetFragment.FAB_RANDOM: {
random();
break;
}
case FABMoreOptionsBottomSheetFragment.FAB_HIDE_READ_POSTS: {
if (sectionsPagerAdapter != null) {
sectionsPagerAdapter.hideReadPosts();
@@ -1378,7 +1514,11 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
if (i == EditorInfo.IME_ACTION_DONE) {
Utils.hideKeyboard(this);
Intent subredditIntent = new Intent(this, ViewSubredditDetailActivity.class);
subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, thingEditText.getText().toString());
String communityName = thingEditText.getText().toString();
if (communityName.startsWith("!")) {
communityName = communityName.substring(1);
}
subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_COMMUNITY_FULL_NAME_KEY, communityName);
startActivity(subredditIntent);
return true;
}
@@ -1436,7 +1576,11 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
-> {
Utils.hideKeyboard(this);
Intent subredditIntent = new Intent(this, ViewSubredditDetailActivity.class);
subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, thingEditText.getText().toString());
String communityName = thingEditText.getText().toString();
if (communityName.startsWith("!")) {
communityName = communityName.substring(1);
}
subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_COMMUNITY_FULL_NAME_KEY, communityName);
startActivity(subredditIntent);
})
.setNegativeButton(R.string.cancel, (dialogInterface, i) -> {
@@ -1457,7 +1601,11 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
if (i == EditorInfo.IME_ACTION_DONE) {
Utils.hideKeyboard(this);
Intent userIntent = new Intent(this, ViewUserDetailActivity.class);
userIntent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, thingEditText.getText().toString());
String userName = thingEditText.getText().toString();
if (userName.startsWith("@")) {
userName = userName.substring(1);
}
userIntent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, userName);
startActivity(userIntent);
return true;
}
@@ -1470,7 +1618,11 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
-> {
Utils.hideKeyboard(this);
Intent userIntent = new Intent(this, ViewUserDetailActivity.class);
userIntent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, thingEditText.getText().toString());
String userName = thingEditText.getText().toString();
if (userName.startsWith("@")) {
userName = userName.substring(1);
}
userIntent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, userName);
startActivity(userIntent);
})
.setNegativeButton(R.string.cancel, (dialogInterface, i) -> {
@@ -1550,7 +1702,17 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
@Override
public void markPostAsRead(Post post) {
InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, mAccountName, post.getId());
markPostAsRead.markPostAsRead(post.getId(), mAccessToken, new MarkPostAsRead.MarkPostAsReadListener() {
@Override
public void onMarkPostAsReadSuccess() {
InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, mAccountQualifiedName, post.getId());
}
@Override
public void onMarkPostAsReadFailed() {
Toast.makeText(ViewUserDetailActivity.this, R.string.mark_post_as_read_failed, Toast.LENGTH_SHORT).show();
}
});
}
@Override

View File

@@ -23,14 +23,11 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.text.Html;
import android.view.Menu;
import android.view.MenuItem;
import android.view.OrientationEventListener;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
@@ -70,6 +67,7 @@ import com.google.android.exoplayer2.upstream.cache.SimpleCache;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.video.VideoSize;
import com.google.android.material.bottomappbar.BottomAppBar;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.common.collect.ImmutableList;
import com.otaliastudios.zoom.ZoomEngine;
@@ -108,6 +106,7 @@ import eu.toldi.infinityforlemmy.font.TitleFontFamily;
import eu.toldi.infinityforlemmy.font.TitleFontStyle;
import eu.toldi.infinityforlemmy.post.FetchPost;
import eu.toldi.infinityforlemmy.post.Post;
import eu.toldi.infinityforlemmy.post.enrich.PostEnricher;
import eu.toldi.infinityforlemmy.services.DownloadMediaService;
import eu.toldi.infinityforlemmy.services.DownloadRedditVideoService;
import eu.toldi.infinityforlemmy.utils.APIUtils;
@@ -131,7 +130,7 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
public static final String EXTRA_VIDEO_DOWNLOAD_URL = "EVDU";
public static final String EXTRA_SUBREDDIT = "ES";
public static final String EXTRA_ID = "EI";
public static final String EXTRA_POST_TITLE = "EPT";
public static final String EXTRA_POST = "EP";
public static final String EXTRA_PROGRESS_SECONDS = "EPS";
public static final String EXTRA_VIDEO_TYPE = "EVT";
public static final String EXTRA_GFYCAT_ID = "EGI";
@@ -162,17 +161,19 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
@BindView(R.id.progress_bar_view_video_activity)
ProgressBar progressBar;
@BindView(R.id.mute_exo_playback_control_view)
ImageButton muteButton;
MaterialButton muteButton;
@BindView(R.id.hd_exo_playback_control_view)
ImageButton hdButton;
MaterialButton hdButton;
@BindView(R.id.bottom_navigation_exo_playback_control_view)
BottomAppBar bottomAppBar;
@BindView(R.id.title_text_view_exo_playback_control_view)
TextView titleTextView;
@BindView(R.id.back_button_exo_playback_control_view)
MaterialButton backButton;
@BindView(R.id.download_image_view_exo_playback_control_view)
ImageView downloadImageView;
MaterialButton downloadButton;
@BindView(R.id.playback_speed_image_view_exo_playback_control_view)
ImageView playbackSpeedImageView;
MaterialButton playbackSpeedButton;
@BindView(R.id.lockable_nested_scroll_view_view_video_activity)
LockableNestedScrollView nestedScrollView;
@@ -222,10 +223,6 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
@Named("default")
SharedPreferences mSharedPreferences;
@Inject
@Named("current_account")
SharedPreferences mCurrentAccountSharedPreferences;
@Inject
CustomThemeWrapper mCustomThemeWrapper;
@@ -235,6 +232,9 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
@Inject
SimpleCache mSimpleCache;
@Inject
PostEnricher postEnricher;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -301,6 +301,12 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
ButterKnife.bind(this);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
setTitle(" ");
if (typeface != null) {
titleTextView.setTypeface(typeface);
}
Resources resources = getResources();
getWindow().getDecorView().setSystemUiVisibility(
@@ -312,7 +318,11 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
if (useBottomAppBar) {
getSupportActionBar().hide();
bottomAppBar.setVisibility(View.VISIBLE);
downloadImageView.setOnClickListener(view -> {
backButton.setOnClickListener(view -> {
finish();
});
downloadButton.setOnClickListener(view -> {
if (isDownloading) {
return;
}
@@ -326,12 +336,8 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
requestPermissionAndDownload();
});
playbackSpeedImageView.setOnClickListener(view -> {
PlaybackSpeedBottomSheetFragment playbackSpeedBottomSheetFragment = new PlaybackSpeedBottomSheetFragment();
Bundle bundle = new Bundle();
bundle.putInt(PlaybackSpeedBottomSheetFragment.EXTRA_PLAYBACK_SPEED, playbackSpeed);
playbackSpeedBottomSheetFragment.setArguments(bundle);
playbackSpeedBottomSheetFragment.show(getSupportFragmentManager(), playbackSpeedBottomSheetFragment.getTag());
playbackSpeedButton.setOnClickListener(view -> {
changePlaybackSpeed();
});
} else {
ActionBar actionBar = getSupportActionBar();
@@ -402,12 +408,15 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
};
orientationEventListener.enable();
}
} catch (Exception ignore) {}
} catch (Exception ignore) {
}
}
}
String postTitle = intent.getStringExtra(EXTRA_POST_TITLE);
setSmallTitle(postTitle);
Post post = intent.getParcelableExtra(EXTRA_POST);
if (post != null) {
titleTextView.setText(post.getTitle());
}
trackSelector = new DefaultTrackSelector(this);
if (videoType == VIDEO_TYPE_NORMAL && isDataSavingMode && dataSavingModeDefaultResolution > 0) {
@@ -598,20 +607,6 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
}
}
private void setSmallTitle(String title) {
if (title != null) {
if (useBottomAppBar) {
titleTextView.setText(Html.fromHtml(String.format("<font color=\"#FFFFFF\"><small>%s</small></font>", title)));
} else {
setTitle(Utils.getTabTextWithCustomFont(typeface, Html.fromHtml(String.format("<font color=\"#FFFFFF\"><small>%s</small></font>", title))));
}
} else {
if (!useBottomAppBar) {
setTitle("");
}
}
}
private void preparePlayer(Bundle savedInstanceState) {
if (mSharedPreferences.getBoolean(SharedPreferencesUtils.LOOP_VIDEO, true)) {
player.setRepeatMode(Player.REPEAT_MODE_ALL);
@@ -631,17 +626,17 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
isMute = savedInstanceState.getBoolean(IS_MUTE_STATE);
if (isMute) {
player.setVolume(0f);
muteButton.setImageResource(R.drawable.ic_mute_24dp);
muteButton.setIconResource(R.drawable.ic_mute_24dp);
} else {
player.setVolume(1f);
muteButton.setImageResource(R.drawable.ic_unmute_24dp);
muteButton.setIconResource(R.drawable.ic_unmute_24dp);
}
} else if (muteVideo) {
isMute = true;
player.setVolume(0f);
muteButton.setImageResource(R.drawable.ic_mute_24dp);
muteButton.setIconResource(R.drawable.ic_mute_24dp);
} else {
muteButton.setImageResource(R.drawable.ic_unmute_24dp);
muteButton.setIconResource(R.drawable.ic_unmute_24dp);
}
player.addListener(new Player.Listener() {
@@ -685,11 +680,11 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
if (isMute) {
isMute = false;
player.setVolume(1f);
muteButton.setImageResource(R.drawable.ic_unmute_24dp);
muteButton.setIconResource(R.drawable.ic_unmute_24dp);
} else {
isMute = true;
player.setVolume(0f);
muteButton.setImageResource(R.drawable.ic_mute_24dp);
muteButton.setIconResource(R.drawable.ic_mute_24dp);
}
});
}
@@ -702,6 +697,14 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
});
}
private void changePlaybackSpeed() {
PlaybackSpeedBottomSheetFragment playbackSpeedBottomSheetFragment = new PlaybackSpeedBottomSheetFragment();
Bundle bundle = new Bundle();
bundle.putInt(PlaybackSpeedBottomSheetFragment.EXTRA_PLAYBACK_SPEED, playbackSpeed);
playbackSpeedBottomSheetFragment.setArguments(bundle);
playbackSpeedBottomSheetFragment.show(getSupportFragmentManager(), playbackSpeedBottomSheetFragment.getTag());
}
private int inferPrimaryTrackType(Format format) {
int trackType = MimeTypes.getTrackType(format.sampleMimeType);
if (trackType != C.TRACK_TYPE_UNKNOWN) {
@@ -756,8 +759,8 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
}
});
} else {
FetchGfycatOrRedgifsVideoLinks.fetchRedgifsVideoLinks(this, mExecutor, new Handler(), redgifsRetrofit,
mCurrentAccountSharedPreferences, gfycatId, new FetchGfycatOrRedgifsVideoLinks.FetchGfycatOrRedgifsVideoLinksListener() {
FetchGfycatOrRedgifsVideoLinks.fetchRedgifsVideoLinks(mExecutor, new Handler(), redgifsRetrofit,
gfycatId, new FetchGfycatOrRedgifsVideoLinks.FetchGfycatOrRedgifsVideoLinksListener() {
@Override
public void success(String webm, String mp4) {
progressBar.setVisibility(View.GONE);
@@ -791,7 +794,7 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
int commentsIndex = segments.lastIndexOf("comments");
String postId = segments.get(commentsIndex + 1);
FetchPost.fetchPost(mExecutor, new Handler(), retrofit.getRetrofit(), postId, null,
new FetchPost.FetchPostListener() {
postEnricher, new FetchPost.FetchPostListener() {
@Override
public void fetchPostSuccess(Post post) {
if (post.isGfycat()) {
@@ -884,7 +887,7 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
Toast.makeText(ViewVideoActivity.this, R.string.fetch_streamable_video_failed, Toast.LENGTH_SHORT).show();
return;
}
setSmallTitle(streamableVideo.title);
titleTextView.setText(streamableVideo.title);
progressBar.setVisibility(View.GONE);
videoDownloadUrl = streamableVideo.mp4 == null ? streamableVideo.mp4Mobile.url : streamableVideo.mp4.url;
mVideoUri = Uri.parse(videoDownloadUrl);
@@ -939,11 +942,7 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
requestPermissionAndDownload();
return true;
} else if (itemId == R.id.action_playback_speed_view_video_activity) {
PlaybackSpeedBottomSheetFragment playbackSpeedBottomSheetFragment = new PlaybackSpeedBottomSheetFragment();
Bundle bundle = new Bundle();
bundle.putInt(PlaybackSpeedBottomSheetFragment.EXTRA_PLAYBACK_SPEED, playbackSpeed);
playbackSpeedBottomSheetFragment.setArguments(bundle);
playbackSpeedBottomSheetFragment.show(getSupportFragmentManager(), playbackSpeedBottomSheetFragment.getTag());
changePlaybackSpeed();
return true;
}

View File

@@ -35,16 +35,9 @@ import javax.inject.Named;
import butterknife.BindView;
import butterknife.ButterKnife;
import eu.toldi.infinityforlemmy.RetrofitHolder;
import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon;
import io.noties.markwon.MarkwonConfiguration;
import io.noties.markwon.MarkwonPlugin;
import io.noties.markwon.core.MarkwonTheme;
import io.noties.markwon.recycler.MarkwonAdapter;
import me.saket.bettermovementmethod.BetterLinkMovementMethod;
import eu.toldi.infinityforlemmy.Infinity;
import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.RetrofitHolder;
import eu.toldi.infinityforlemmy.apis.RedditAPI;
import eu.toldi.infinityforlemmy.bottomsheetfragments.UrlMenuBottomSheetFragment;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
@@ -57,10 +50,16 @@ import eu.toldi.infinityforlemmy.markdown.MarkdownUtils;
import eu.toldi.infinityforlemmy.utils.JSONUtils;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import eu.toldi.infinityforlemmy.utils.Utils;
import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon;
import io.noties.markwon.MarkwonConfiguration;
import io.noties.markwon.MarkwonPlugin;
import io.noties.markwon.core.MarkwonTheme;
import io.noties.markwon.recycler.MarkwonAdapter;
import me.saket.bettermovementmethod.BetterLinkMovementMethod;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
public class WikiActivity extends BaseActivity {
@@ -139,7 +138,7 @@ public class WikiActivity extends BaseActivity {
}
}
mGlide = Glide.with(this);
mGlide = Glide.with(getApplication());
swipeRefreshLayout.setEnabled(mSharedPreferences.getBoolean(SharedPreferencesUtils.PULL_TO_REFRESH, true));
swipeRefreshLayout.setOnRefreshListener(this::loadWiki);
@@ -177,7 +176,7 @@ public class WikiActivity extends BaseActivity {
return true;
};
markwon = MarkdownUtils.createFullRedditMarkwon(this,
miscPlugin, markdownColor, spoilerBackgroundColor, onLinkLongClickListener);
miscPlugin, markdownColor, spoilerBackgroundColor, onLinkLongClickListener, mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_IMAGE_PREVIEW, false));
markwonAdapter = MarkdownUtils.createTablesAdapter();
LinearLayoutManagerBugFixed linearLayoutManager = new SwipeLockLinearLayoutManager(this, new SwipeLockInterface() {
@@ -219,7 +218,7 @@ public class WikiActivity extends BaseActivity {
swipeRefreshLayout.setRefreshing(true);
Glide.with(this).clear(mFetchWikiInfoImageView);
Glide.with(getApplication()).clear(mFetchWikiInfoImageView);
mFetchWikiInfoLinearLayout.setVisibility(View.GONE);
retrofit.getRetrofit().create(RedditAPI.class).getWikiPage(getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME), getIntent().getStringExtra(EXTRA_WIKI_PATH)).enqueue(new Callback<String>() {

View File

@@ -0,0 +1,22 @@
package eu.toldi.infinityforlemmy.adapters;
import eu.toldi.infinityforlemmy.activities.BaseActivity;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.user.BasicUserRecyclerViewAdapter;
public class AdminRecyclerViewAdapter extends BasicUserRecyclerViewAdapter {
CustomThemeWrapper mCustomThemeWrapper;
public AdminRecyclerViewAdapter(BaseActivity activity, CustomThemeWrapper customThemeWrapper) {
super(activity, customThemeWrapper);
mCustomThemeWrapper = customThemeWrapper;
}
@Override
protected int getUserNameTextColor() {
return mCustomThemeWrapper.getAdmin();
}
}

View File

@@ -0,0 +1,385 @@
package eu.toldi.infinityforlemmy.adapters;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.request.RequestOptions;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.regex.Pattern;
import butterknife.BindView;
import butterknife.ButterKnife;
import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.RedditDataRoomDatabase;
import eu.toldi.infinityforlemmy.activities.BaseActivity;
import eu.toldi.infinityforlemmy.activities.ViewSubredditDetailActivity;
import eu.toldi.infinityforlemmy.blockedcommunity.BlockedCommunityData;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
import me.zhanghai.android.fastscroll.PopupTextProvider;
import pl.droidsonroids.gif.GifImageView;
import retrofit2.Retrofit;
public class BlockedCommunitiesRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements PopupTextProvider {
private static final int VIEW_TYPE_FAVORITE_SUBREDDIT_DIVIDER = 0;
private static final int VIEW_TYPE_FAVORITE_SUBREDDIT = 1;
private static final int VIEW_TYPE_SUBREDDIT_DIVIDER = 2;
private static final int VIEW_TYPE_SUBREDDIT = 3;
private BaseActivity mActivity;
private Executor mExecutor;
private Retrofit mOauthRetrofit;
private RedditDataRoomDatabase mRedditDataRoomDatabase;
private List<BlockedCommunityData> mBlockedCommunityData;
private List<BlockedCommunityData> mFavoriteBlockedCommunityData;
private RequestManager glide;
private ItemClickListener itemClickListener;
private String accessToken;
private String username;
private String userIconUrl;
private boolean hasClearSelectionRow;
private int primaryTextColor;
private int secondaryTextColor;
public BlockedCommunitiesRecyclerViewAdapter(BaseActivity activity, Executor executor, Retrofit oauthRetrofit,
RedditDataRoomDatabase redditDataRoomDatabase,
CustomThemeWrapper customThemeWrapper,
String accessToken) {
mActivity = activity;
mExecutor = executor;
glide = Glide.with(activity);
mOauthRetrofit = oauthRetrofit;
mRedditDataRoomDatabase = redditDataRoomDatabase;
this.accessToken = accessToken;
primaryTextColor = customThemeWrapper.getPrimaryTextColor();
secondaryTextColor = customThemeWrapper.getSecondaryTextColor();
}
public BlockedCommunitiesRecyclerViewAdapter(BaseActivity activity, Executor executor, Retrofit oauthRetrofit,
RedditDataRoomDatabase redditDataRoomDatabase,
CustomThemeWrapper customThemeWrapper,
String accessToken, boolean hasClearSelectionRow,
ItemClickListener itemClickListener) {
this(activity, executor, oauthRetrofit, redditDataRoomDatabase, customThemeWrapper, accessToken);
this.hasClearSelectionRow = hasClearSelectionRow;
this.itemClickListener = itemClickListener;
}
@Override
public int getItemViewType(int position) {
if (mFavoriteBlockedCommunityData != null && mFavoriteBlockedCommunityData.size() > 0) {
if (itemClickListener != null && !hasClearSelectionRow) {
if (position == 0) {
return VIEW_TYPE_SUBREDDIT;
} else if (position == 1) {
return VIEW_TYPE_FAVORITE_SUBREDDIT_DIVIDER;
} else if (position == mFavoriteBlockedCommunityData.size() + 2) {
return VIEW_TYPE_SUBREDDIT_DIVIDER;
} else if (position <= mFavoriteBlockedCommunityData.size() + 1) {
return VIEW_TYPE_FAVORITE_SUBREDDIT;
} else {
return VIEW_TYPE_SUBREDDIT;
}
} else if (hasClearSelectionRow) {
if (position == 0) {
return VIEW_TYPE_SUBREDDIT;
} else if (position == 1) {
return VIEW_TYPE_SUBREDDIT;
} else if (position == 2) {
return VIEW_TYPE_FAVORITE_SUBREDDIT_DIVIDER;
} else if (position == mFavoriteBlockedCommunityData.size() + 3) {
return VIEW_TYPE_SUBREDDIT_DIVIDER;
} else if (position <= mFavoriteBlockedCommunityData.size() + 2) {
return VIEW_TYPE_FAVORITE_SUBREDDIT;
} else {
return VIEW_TYPE_SUBREDDIT;
}
} else {
if (position == 0) {
return VIEW_TYPE_FAVORITE_SUBREDDIT_DIVIDER;
} else if (position == mFavoriteBlockedCommunityData.size() + 1) {
return VIEW_TYPE_SUBREDDIT_DIVIDER;
} else if (position <= mFavoriteBlockedCommunityData.size()) {
return VIEW_TYPE_FAVORITE_SUBREDDIT;
} else {
return VIEW_TYPE_SUBREDDIT;
}
}
} else {
return VIEW_TYPE_SUBREDDIT;
}
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
switch (i) {
case VIEW_TYPE_FAVORITE_SUBREDDIT_DIVIDER:
return new FavoriteSubredditsDividerViewHolder(LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.item_favorite_thing_divider, viewGroup, false));
case VIEW_TYPE_FAVORITE_SUBREDDIT:
return new FavoriteSubredditViewHolder(LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.item_subscribed_thing, viewGroup, false));
case VIEW_TYPE_SUBREDDIT_DIVIDER:
return new AllSubredditsDividerViewHolder(LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.item_favorite_thing_divider, viewGroup, false));
default:
return new SubredditViewHolder(LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.item_subscribed_thing, viewGroup, false));
}
}
@Override
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder viewHolder, int i) {
if (viewHolder instanceof SubredditViewHolder) {
String name;
String fullname = "";
String iconUrl;
if (hasClearSelectionRow && viewHolder.getBindingAdapterPosition() == 0) {
((SubredditViewHolder) viewHolder).subredditNameTextView.setText(R.string.all_communities);
viewHolder.itemView.setOnClickListener(view -> itemClickListener.onClick(null));
return;
} else {
int offset = hasClearSelectionRow ? 1 : 0;
BlockedCommunityData communityData = mBlockedCommunityData.get(viewHolder.getBindingAdapterPosition() - offset);
name = mBlockedCommunityData.get(viewHolder.getBindingAdapterPosition() - offset).getName();
fullname = mBlockedCommunityData.get(viewHolder.getBindingAdapterPosition() - offset).getQualified_name();
iconUrl = mBlockedCommunityData.get(viewHolder.getBindingAdapterPosition() - offset).getIconUrl();
if (itemClickListener != null) {
viewHolder.itemView.setOnClickListener(view -> itemClickListener.onClick(communityData));
}
}
if (itemClickListener == null) {
String finalFullname = fullname;
viewHolder.itemView.setOnClickListener(view -> {
Intent intent = new Intent(mActivity, ViewSubredditDetailActivity.class);
intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, name);
intent.putExtra(ViewSubredditDetailActivity.EXTRA_COMMUNITY_FULL_NAME_KEY,
finalFullname);
mActivity.startActivity(intent);
});
}
if (iconUrl != null && !iconUrl.equals("")) {
glide.load(iconUrl)
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
.error(glide.load(R.drawable.subreddit_default_icon)
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))))
.into(((SubredditViewHolder) viewHolder).iconGifImageView);
} else {
glide.load(R.drawable.subreddit_default_icon)
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
.into(((SubredditViewHolder) viewHolder).iconGifImageView);
}
((SubredditViewHolder) viewHolder).subredditNameTextView.setText(name);
if (fullname.contains("@")) {
((SubredditViewHolder) viewHolder).communityInstanceTextView.setText("@" + fullname.split(Pattern.quote("@"), 2)[1]);
((SubredditViewHolder) viewHolder).communityInstanceTextView.setTextColor(CustomThemeWrapper.darkenColor(primaryTextColor, 0.7f));
}
} else if (viewHolder instanceof FavoriteSubredditViewHolder) {
int offset;
if (itemClickListener != null) {
if (hasClearSelectionRow) {
offset = 3;
} else {
offset = 2;
}
} else {
offset = 1;
}
BlockedCommunityData communityData = mFavoriteBlockedCommunityData.get(viewHolder.getBindingAdapterPosition() - offset);
String name = mFavoriteBlockedCommunityData.get(viewHolder.getBindingAdapterPosition() - offset).getName();
String iconUrl = mFavoriteBlockedCommunityData.get(viewHolder.getBindingAdapterPosition() - offset).getIconUrl();
if (itemClickListener != null) {
viewHolder.itemView.setOnClickListener(view -> itemClickListener.onClick(communityData));
} else {
viewHolder.itemView.setOnClickListener(view -> {
Intent intent = new Intent(mActivity, ViewSubredditDetailActivity.class);
intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, name);
mActivity.startActivity(intent);
});
}
if (iconUrl != null && !iconUrl.equals("")) {
glide.load(iconUrl)
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
.error(glide.load(R.drawable.subreddit_default_icon)
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))))
.into(((FavoriteSubredditViewHolder) viewHolder).iconGifImageView);
} else {
glide.load(R.drawable.subreddit_default_icon)
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
.into(((FavoriteSubredditViewHolder) viewHolder).iconGifImageView);
}
((FavoriteSubredditViewHolder) viewHolder).subredditNameTextView.setText(name);
}
}
@Override
public int getItemCount() {
if (mBlockedCommunityData != null) {
if (itemClickListener != null) {
return mBlockedCommunityData.size() > 0 ? mBlockedCommunityData.size() + ((hasClearSelectionRow) ? 1 : 0) : 0;
}
return mBlockedCommunityData.size();
}
return 0;
}
@Override
public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
if (holder instanceof SubredditViewHolder) {
glide.clear(((SubredditViewHolder) holder).iconGifImageView);
} else if (holder instanceof FavoriteSubredditViewHolder) {
glide.clear(((FavoriteSubredditViewHolder) holder).iconGifImageView);
}
}
public void setSubscribedSubreddits(List<BlockedCommunityData> subscribedSubreddits) {
mBlockedCommunityData = subscribedSubreddits;
notifyDataSetChanged();
}
public void setFavoriteSubscribedSubreddits(List<BlockedCommunityData> favoriteBlockedCommunityData) {
mFavoriteBlockedCommunityData = favoriteBlockedCommunityData;
notifyDataSetChanged();
}
public void addUser(String username, String userIconUrl) {
this.username = username;
this.userIconUrl = userIconUrl;
}
@NonNull
@Override
public String getPopupText(int position) {
switch (getItemViewType(position)) {
case VIEW_TYPE_SUBREDDIT:
if (hasClearSelectionRow && position == 0) {
return "";
} else if (itemClickListener != null && !hasClearSelectionRow && position == 0) {
return "";
} else if (hasClearSelectionRow && position == 1) {
return "";
} else {
int offset;
if (itemClickListener != null) {
if (hasClearSelectionRow) {
offset = (mFavoriteBlockedCommunityData != null && mFavoriteBlockedCommunityData.size() > 0) ?
mFavoriteBlockedCommunityData.size() + 4 : 0;
} else {
offset = (mFavoriteBlockedCommunityData != null && mFavoriteBlockedCommunityData.size() > 0) ?
mFavoriteBlockedCommunityData.size() + 3 : 0;
}
} else {
offset = (mFavoriteBlockedCommunityData != null && mFavoriteBlockedCommunityData.size() > 0) ?
mFavoriteBlockedCommunityData.size() + 2 : 0;
}
return mBlockedCommunityData.get(position - offset).getName().substring(0, 1).toUpperCase();
}
case VIEW_TYPE_FAVORITE_SUBREDDIT:
int offset;
if (itemClickListener != null) {
if (hasClearSelectionRow) {
offset = 3;
} else {
offset = 2;
}
} else {
offset = 1;
}
return mFavoriteBlockedCommunityData.get(position - offset).getName().substring(0, 1).toUpperCase();
default:
return "";
}
}
public interface ItemClickListener {
void onClick(BlockedCommunityData subredditData);
}
class SubredditViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.thing_icon_gif_image_view_item_subscribed_thing)
GifImageView iconGifImageView;
@BindView(R.id.thing_name_text_view_item_subscribed_thing)
TextView subredditNameTextView;
@BindView(R.id.thing_instance_text_view_item_subscribed_thing)
TextView communityInstanceTextView;
SubredditViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
if (mActivity.typeface != null) {
subredditNameTextView.setTypeface(mActivity.typeface);
}
subredditNameTextView.setTextColor(primaryTextColor);
}
}
class FavoriteSubredditViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.thing_icon_gif_image_view_item_subscribed_thing)
GifImageView iconGifImageView;
@BindView(R.id.thing_name_text_view_item_subscribed_thing)
TextView subredditNameTextView;
FavoriteSubredditViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
if (mActivity.typeface != null) {
subredditNameTextView.setTypeface(mActivity.typeface);
}
subredditNameTextView.setTextColor(primaryTextColor);
}
}
class FavoriteSubredditsDividerViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.divider_text_view_item_favorite_thing_divider)
TextView dividerTextView;
FavoriteSubredditsDividerViewHolder(@NonNull View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
if (mActivity.typeface != null) {
dividerTextView.setTypeface(mActivity.typeface);
}
dividerTextView.setText(R.string.favorites);
dividerTextView.setTextColor(secondaryTextColor);
}
}
class AllSubredditsDividerViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.divider_text_view_item_favorite_thing_divider)
TextView dividerTextView;
AllSubredditsDividerViewHolder(@NonNull View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
if (mActivity.typeface != null) {
dividerTextView.setTypeface(mActivity.typeface);
}
dividerTextView.setText(R.string.all);
dividerTextView.setTextColor(secondaryTextColor);
}
}
}

View File

@@ -0,0 +1,216 @@
package eu.toldi.infinityforlemmy.adapters;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.request.RequestOptions;
import java.util.List;
import java.util.concurrent.Executor;
import butterknife.BindView;
import butterknife.ButterKnife;
import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.RedditDataRoomDatabase;
import eu.toldi.infinityforlemmy.activities.BaseActivity;
import eu.toldi.infinityforlemmy.activities.ViewUserDetailActivity;
import eu.toldi.infinityforlemmy.blockeduser.BlockedUserData;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
import me.zhanghai.android.fastscroll.PopupTextProvider;
import pl.droidsonroids.gif.GifImageView;
import retrofit2.Retrofit;
public class BlockedUsersRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements PopupTextProvider {
private static final int VIEW_TYPE_FAVORITE_USER_DIVIDER = 0;
private static final int VIEW_TYPE_FAVORITE_USER = 1;
private static final int VIEW_TYPE_USER_DIVIDER = 2;
private static final int VIEW_TYPE_USER = 3;
private List<BlockedUserData> mBlockedUserData;
private List<BlockedUserData> mFavoriteBlockedUserData;
private BaseActivity mActivity;
private Executor mExecutor;
private Retrofit mOauthRetrofit;
private RedditDataRoomDatabase mRedditDataRoomDatabase;
private String mAccessToken;
private RequestManager glide;
private int mPrimaryTextColor;
private int mSecondaryTextColor;
public BlockedUsersRecyclerViewAdapter(BaseActivity activity, Executor executor, Retrofit oauthRetrofit,
RedditDataRoomDatabase redditDataRoomDatabase,
CustomThemeWrapper customThemeWrapper,
String accessToken) {
mActivity = activity;
mExecutor = executor;
mOauthRetrofit = oauthRetrofit;
mRedditDataRoomDatabase = redditDataRoomDatabase;
mAccessToken = accessToken;
glide = Glide.with(activity);
mPrimaryTextColor = customThemeWrapper.getPrimaryTextColor();
mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor();
}
@Override
public int getItemViewType(int position) {
if (mFavoriteBlockedUserData != null && mFavoriteBlockedUserData.size() > 0) {
if (position == 0) {
return VIEW_TYPE_FAVORITE_USER_DIVIDER;
} else if (position == mFavoriteBlockedUserData.size() + 1) {
return VIEW_TYPE_USER_DIVIDER;
} else if (position <= mFavoriteBlockedUserData.size()) {
return VIEW_TYPE_FAVORITE_USER;
} else {
return VIEW_TYPE_USER;
}
} else {
return VIEW_TYPE_USER;
}
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
switch (i) {
case VIEW_TYPE_FAVORITE_USER_DIVIDER:
return new FavoriteUsersDividerViewHolder(LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.item_favorite_thing_divider, viewGroup, false));
case VIEW_TYPE_USER_DIVIDER:
return new AllUsersDividerViewHolder(LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.item_favorite_thing_divider, viewGroup, false));
default:
return new UserViewHolder(LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.item_subscribed_thing, viewGroup, false));
}
}
@Override
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder viewHolder, int i) {
if (viewHolder instanceof UserViewHolder) {
int offset = 0;
if (!mBlockedUserData.get(viewHolder.getBindingAdapterPosition() - offset).getAvatar().equals("")) {
glide.load(mBlockedUserData.get(viewHolder.getBindingAdapterPosition() - offset).getAvatar())
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
.error(glide.load(R.drawable.subreddit_default_icon)
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))))
.into(((UserViewHolder) viewHolder).iconGifImageView);
} else {
glide.load(R.drawable.subreddit_default_icon)
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
.into(((UserViewHolder) viewHolder).iconGifImageView);
}
((UserViewHolder) viewHolder).userNameTextView.setText(mBlockedUserData.get(viewHolder.getBindingAdapterPosition() - offset).getName());
}
}
@Override
public int getItemCount() {
if (mBlockedUserData != null && mBlockedUserData.size() > 0) {
return mBlockedUserData.size();
}
return 0;
}
@Override
public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
if (holder instanceof UserViewHolder) {
glide.clear(((UserViewHolder) holder).iconGifImageView);
}
}
public void setSubscribedUsers(List<BlockedUserData> subscribedUsers) {
mBlockedUserData = subscribedUsers;
notifyDataSetChanged();
}
public void setFavoriteSubscribedUsers(List<BlockedUserData> favoriteSubscribedUsers) {
mFavoriteBlockedUserData = favoriteSubscribedUsers;
notifyDataSetChanged();
}
@NonNull
@Override
public String getPopupText(int position) {
switch (getItemViewType(position)) {
case VIEW_TYPE_USER:
int offset = (mFavoriteBlockedUserData != null && mFavoriteBlockedUserData.size() > 0) ?
mFavoriteBlockedUserData.size() + 2 : 0;
return mBlockedUserData.get(position - offset).getName().substring(0, 1).toUpperCase();
case VIEW_TYPE_FAVORITE_USER:
return mFavoriteBlockedUserData.get(position - 1).getName().substring(0, 1).toUpperCase();
default:
return "";
}
}
class UserViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.thing_icon_gif_image_view_item_subscribed_thing)
GifImageView iconGifImageView;
@BindView(R.id.thing_name_text_view_item_subscribed_thing)
TextView userNameTextView;
UserViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
if (mActivity.typeface != null) {
userNameTextView.setTypeface(mActivity.typeface);
}
userNameTextView.setTextColor(mPrimaryTextColor);
itemView.setOnClickListener(view -> {
int offset = (mFavoriteBlockedUserData != null && mFavoriteBlockedUserData.size() > 0) ?
mFavoriteBlockedUserData.size() + 2 : 0;
int position = getBindingAdapterPosition() - offset;
if (position >= 0 && mBlockedUserData.size() > position) {
Intent intent = new Intent(mActivity, ViewUserDetailActivity.class);
intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mBlockedUserData.get(position).getName());
intent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, mBlockedUserData.get(position).getQualifiedName());
mActivity.startActivity(intent);
}
});
}
}
class FavoriteUsersDividerViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.divider_text_view_item_favorite_thing_divider)
TextView dividerTextView;
FavoriteUsersDividerViewHolder(@NonNull View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
if (mActivity.typeface != null) {
dividerTextView.setTypeface(mActivity.typeface);
}
dividerTextView.setText(R.string.favorites);
dividerTextView.setTextColor(mSecondaryTextColor);
}
}
class AllUsersDividerViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.divider_text_view_item_favorite_thing_divider)
TextView dividerTextView;
AllUsersDividerViewHolder(@NonNull View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
if (mActivity.typeface != null) {
dividerTextView.setTypeface(mActivity.typeface);
}
dividerTextView.setText(R.string.all);
dividerTextView.setTextColor(mSecondaryTextColor);
}
}
}

View File

@@ -0,0 +1,76 @@
package eu.toldi.infinityforlemmy.adapters;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.activities.BaseActivity;
import eu.toldi.infinityforlemmy.commentfilter.CommentFilterUsage;
import eu.toldi.infinityforlemmy.databinding.ItemCommentFilterUsageEmbeddedBinding;
public class CommentFilterUsageEmbeddedRecyclerViewAdapter extends RecyclerView.Adapter<CommentFilterUsageEmbeddedRecyclerViewAdapter.EntryViewHolder> {
private BaseActivity baseActivity;
private List<CommentFilterUsage> commentFilterUsageList;
public CommentFilterUsageEmbeddedRecyclerViewAdapter(BaseActivity baseActivity) {
this.baseActivity = baseActivity;
}
@NonNull
@Override
public EntryViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new EntryViewHolder(ItemCommentFilterUsageEmbeddedBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
}
@Override
public void onBindViewHolder(@NonNull EntryViewHolder holder, int position) {
if (commentFilterUsageList == null || commentFilterUsageList.isEmpty()) {
holder.textView.setText(R.string.comment_filter_applied_to_all_subreddits);
} else if (holder.getBindingAdapterPosition() > 4) {
holder.textView.setText(baseActivity.getString(R.string.comment_filter_usage_embedded_more_count, commentFilterUsageList.size() - 5));
} else {
CommentFilterUsage commentFilterUsage = commentFilterUsageList.get(holder.getBindingAdapterPosition());
switch (commentFilterUsage.usage) {
case CommentFilterUsage.SUBREDDIT_TYPE:
holder.textView.setText("r/" + commentFilterUsage.nameOfUsage);
break;
}
}
}
@Override
public int getItemCount() {
return commentFilterUsageList == null || commentFilterUsageList.isEmpty() ? 1 : (commentFilterUsageList.size() > 5 ? 6 : commentFilterUsageList.size());
}
public void setCommentFilterUsageList(List<CommentFilterUsage> commentFilterUsageList) {
this.commentFilterUsageList = commentFilterUsageList;
notifyDataSetChanged();
}
class EntryViewHolder extends RecyclerView.ViewHolder {
TextView textView;
public EntryViewHolder(@NonNull ItemCommentFilterUsageEmbeddedBinding binding) {
super(binding.getRoot());
textView = binding.getRoot();
textView.setTextColor(baseActivity.customThemeWrapper.getSecondaryTextColor());
if (baseActivity.typeface != null) {
textView.setTypeface(baseActivity.typeface);
}
textView.setOnClickListener(view -> {
Toast.makeText(baseActivity, textView.getText(), Toast.LENGTH_SHORT).show();
});
}
}
}

View File

@@ -0,0 +1,80 @@
package eu.toldi.infinityforlemmy.adapters;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.activities.BaseActivity;
import eu.toldi.infinityforlemmy.commentfilter.CommentFilterUsage;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
public class CommentFilterUsageRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<CommentFilterUsage> commentFilterUsages;
private BaseActivity activity;
private CustomThemeWrapper customThemeWrapper;
private CommentFilterUsageRecyclerViewAdapter.OnItemClickListener onItemClickListener;
public interface OnItemClickListener {
void onClick(CommentFilterUsage commentFilterUsage);
}
public CommentFilterUsageRecyclerViewAdapter(BaseActivity activity, CustomThemeWrapper customThemeWrapper,
CommentFilterUsageRecyclerViewAdapter.OnItemClickListener onItemClickListener) {
this.activity = activity;
this.customThemeWrapper = customThemeWrapper;
this.onItemClickListener = onItemClickListener;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new CommentFilterUsageRecyclerViewAdapter.CommentFilterUsageViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_filter_usage, parent, false));
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
CommentFilterUsage commentFilterUsage = commentFilterUsages.get(position);
switch (commentFilterUsage.usage) {
case CommentFilterUsage.SUBREDDIT_TYPE:
((CommentFilterUsageRecyclerViewAdapter.CommentFilterUsageViewHolder) holder).usageTextView.setText(activity.getString(R.string.post_filter_usage_community, commentFilterUsage.nameOfUsage));
break;
}
}
@Override
public int getItemCount() {
return commentFilterUsages == null ? 0 : commentFilterUsages.size();
}
public void setCommentFilterUsages(List<CommentFilterUsage> commentFilterUsages) {
this.commentFilterUsages = commentFilterUsages;
notifyDataSetChanged();
}
private class CommentFilterUsageViewHolder extends RecyclerView.ViewHolder {
TextView usageTextView;
public CommentFilterUsageViewHolder(@NonNull View itemView) {
super(itemView);
usageTextView = (TextView) itemView;
usageTextView.setTextColor(customThemeWrapper.getPrimaryTextColor());
if (activity.typeface != null) {
usageTextView.setTypeface(activity.typeface);
}
usageTextView.setOnClickListener(view -> {
onItemClickListener.onClick(commentFilterUsages.get(getBindingAdapterPosition()));
});
}
}
}

View File

@@ -0,0 +1,81 @@
package eu.toldi.infinityforlemmy.adapters;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import eu.toldi.infinityforlemmy.activities.BaseActivity;
import eu.toldi.infinityforlemmy.commentfilter.CommentFilter;
import eu.toldi.infinityforlemmy.commentfilter.CommentFilterWithUsage;
import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed;
import eu.toldi.infinityforlemmy.databinding.ItemCommentFilterWithUsageBinding;
public class CommentFilterWithUsageRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private BaseActivity activity;
private final OnItemClickListener onItemClickListener;
private List<CommentFilterWithUsage> commentFilterWithUsageList;
private RecyclerView.RecycledViewPool recycledViewPool;
public interface OnItemClickListener {
void onItemClick(CommentFilter commentFilter);
}
public CommentFilterWithUsageRecyclerViewAdapter(BaseActivity activity, OnItemClickListener onItemClickListener) {
this.activity = activity;
this.recycledViewPool = new RecyclerView.RecycledViewPool();
this.onItemClickListener = onItemClickListener;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new CommentFilterViewHolder(ItemCommentFilterWithUsageBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (holder instanceof CommentFilterViewHolder) {
((CommentFilterViewHolder) holder).binding.commentFilterNameTextViewItemCommentFilter.setText(commentFilterWithUsageList.get(position).commentFilter.name);
((CommentFilterViewHolder) holder).adapter.setCommentFilterUsageList(commentFilterWithUsageList.get(position).commentFilterUsageList);
}
}
@Override
public int getItemCount() {
return commentFilterWithUsageList == null ? 0 : commentFilterWithUsageList.size();
}
public void setCommentFilterWithUsageList(List<CommentFilterWithUsage> commentFilterWithUsageList) {
this.commentFilterWithUsageList = commentFilterWithUsageList;
notifyDataSetChanged();
}
private class CommentFilterViewHolder extends RecyclerView.ViewHolder {
ItemCommentFilterWithUsageBinding binding;
CommentFilterUsageEmbeddedRecyclerViewAdapter adapter;
public CommentFilterViewHolder(@NonNull ItemCommentFilterWithUsageBinding binding) {
super(binding.getRoot());
this.binding = binding;
binding.commentFilterNameTextViewItemCommentFilter.setTextColor(activity.customThemeWrapper.getPrimaryTextColor());
if (activity.typeface != null) {
binding.commentFilterNameTextViewItemCommentFilter.setTypeface(activity.typeface);
}
binding.getRoot().setOnClickListener(view -> {
onItemClickListener.onItemClick(commentFilterWithUsageList.get(getBindingAdapterPosition()).commentFilter);
});
binding.commentFilterUsageRecyclerViewItemCommentFilter.setRecycledViewPool(recycledViewPool);
binding.commentFilterUsageRecyclerViewItemCommentFilter.setLayoutManager(new LinearLayoutManagerBugFixed(activity));
adapter = new CommentFilterUsageEmbeddedRecyclerViewAdapter(activity);
binding.commentFilterUsageRecyclerViewItemCommentFilter.setAdapter(adapter);
}
}
}

View File

@@ -4,7 +4,6 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.net.Uri;
import android.os.Bundle;
import android.text.Spanned;
@@ -12,7 +11,6 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
@@ -26,6 +24,8 @@ import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.button.MaterialButton;
import java.util.Locale;
import butterknife.BindView;
@@ -49,6 +49,7 @@ import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed;
import eu.toldi.infinityforlemmy.customviews.SpoilerOnClickTextView;
import eu.toldi.infinityforlemmy.customviews.SwipeLockInterface;
import eu.toldi.infinityforlemmy.customviews.SwipeLockLinearLayoutManager;
import eu.toldi.infinityforlemmy.databinding.ItemCommentBinding;
import eu.toldi.infinityforlemmy.markdown.MarkdownUtils;
import eu.toldi.infinityforlemmy.utils.APIUtils;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
@@ -169,7 +170,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
return true;
};
mMarkwon = MarkdownUtils.createFullRedditMarkwon(mActivity,
miscPlugin, mCommentColor, commentSpoilerBackgroundColor, onLinkLongClickListener);
miscPlugin, mCommentColor, commentSpoilerBackgroundColor, onLinkLongClickListener, sharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_IMAGE_PREVIEW, false));
recycledViewPool = new RecyclerView.RecycledViewPool();
}
@@ -177,7 +178,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_DATA) {
return new CommentViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment, parent, false));
return new CommentViewHolder(ItemCommentBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
} else if (viewType == VIEW_TYPE_ERROR) {
return new ErrorViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_error, parent, false));
} else {
@@ -187,24 +188,24 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (holder instanceof CommentViewHolder) {
if (holder instanceof CommentBaseViewHolder) {
Comment comment = getItem(holder.getBindingAdapterPosition());
if (comment != null) {
String name = comment.getCommunityQualifiedName();
((CommentViewHolder) holder).authorTextView.setText(name);
((CommentViewHolder) holder).authorTextView.setTextColor(mSubredditColor);
((CommentBaseViewHolder) holder).authorTextView.setText(name);
((CommentBaseViewHolder) holder).authorTextView.setTextColor(mSubredditColor);
if (mShowElapsedTime) {
((CommentViewHolder) holder).commentTimeTextView.setText(
((CommentBaseViewHolder) holder).commentTimeTextView.setText(
Utils.getElapsedTime(mActivity, comment.getCommentTimeMillis()));
} else {
((CommentViewHolder) holder).commentTimeTextView.setText(Utils.getFormattedTime(mLocale, comment.getCommentTimeMillis(), mTimeFormatPattern));
((CommentBaseViewHolder) holder).commentTimeTextView.setText(Utils.getFormattedTime(mLocale, comment.getCommentTimeMillis(), mTimeFormatPattern));
}
((CommentViewHolder) holder).markwonAdapter.setMarkdown(mMarkwon, comment.getCommentMarkdown());
// noinspection NotifyDataSetChanged
((CommentViewHolder) holder).markwonAdapter.notifyDataSetChanged();
((CommentBaseViewHolder) holder).markwonAdapter.notifyDataSetChanged();
String commentText = Utils.getNVotes(mShowAbsoluteNumberOfVotes,
comment.getScore() + comment.getVoteType());
@@ -213,21 +214,21 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
switch (comment.getVoteType()) {
case Comment.VOTE_TYPE_UPVOTE:
((CommentViewHolder) holder).upvoteButton
.setColorFilter(mUpvotedColor, PorterDuff.Mode.SRC_IN);
((CommentViewHolder) holder).scoreTextView.setTextColor(mUpvotedColor);
((CommentBaseViewHolder) holder).upvoteButton.setIconResource(R.drawable.ic_upvote_filled_24dp);
((CommentBaseViewHolder) holder).upvoteButton.setIconTint(ColorStateList.valueOf(mUpvotedColor));
((CommentBaseViewHolder) holder).scoreTextView.setTextColor(mUpvotedColor);
break;
case Comment.VOTE_TYPE_DOWNVOTE:
((CommentViewHolder) holder).downvoteButton
.setColorFilter(mDownvotedColor, PorterDuff.Mode.SRC_IN);
((CommentViewHolder) holder).scoreTextView.setTextColor(mDownvotedColor);
((CommentBaseViewHolder) holder).downvoteButton.setIconResource(R.drawable.ic_downvote_filled_24dp);
((CommentBaseViewHolder) holder).downvoteButton.setIconTint(ColorStateList.valueOf(mDownvotedColor));
((CommentBaseViewHolder) holder).scoreTextView.setTextColor(mDownvotedColor);
break;
}
if (comment.isSaved()) {
((CommentViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp);
((CommentBaseViewHolder) holder).saveButton.setIconResource(R.drawable.ic_bookmark_grey_24dp);
} else {
((CommentViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp);
((CommentBaseViewHolder) holder).saveButton.setIconResource(R.drawable.ic_bookmark_border_grey_24dp);
}
}
}
@@ -249,14 +250,16 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
@Override
public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
if (holder instanceof CommentViewHolder) {
((CommentViewHolder) holder).authorFlairTextView.setText("");
((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.GONE);
((CommentViewHolder) holder).awardsTextView.setText("");
((CommentViewHolder) holder).awardsTextView.setVisibility(View.GONE);
((CommentViewHolder) holder).upvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN);
((CommentViewHolder) holder).downvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN);
((CommentViewHolder) holder).scoreTextView.setTextColor(mCommentIconAndInfoColor);
if (holder instanceof CommentBaseViewHolder) {
((CommentBaseViewHolder) holder).authorFlairTextView.setText("");
((CommentBaseViewHolder) holder).authorFlairTextView.setVisibility(View.GONE);
((CommentBaseViewHolder) holder).awardsTextView.setText("");
((CommentBaseViewHolder) holder).awardsTextView.setVisibility(View.GONE);
((CommentBaseViewHolder) holder).upvoteButton.setIconResource(R.drawable.ic_upvote_24dp);
((CommentBaseViewHolder) holder).upvoteButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor));
((CommentBaseViewHolder) holder).scoreTextView.setTextColor(mCommentIconAndInfoColor);
((CommentBaseViewHolder) holder).downvoteButton.setIconResource(R.drawable.ic_downvote_24dp);
((CommentBaseViewHolder) holder).downvoteButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor));
}
}
@@ -289,18 +292,18 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
}
public void onItemSwipe(RecyclerView.ViewHolder viewHolder, int direction, int swipeLeftAction, int swipeRightAction) {
if (viewHolder instanceof CommentViewHolder) {
if (viewHolder instanceof CommentBaseViewHolder) {
if (direction == ItemTouchHelper.LEFT || direction == ItemTouchHelper.START) {
if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) {
((CommentViewHolder) viewHolder).upvoteButton.performClick();
((CommentBaseViewHolder) viewHolder).upvoteButton.performClick();
} else if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) {
((CommentViewHolder) viewHolder).downvoteButton.performClick();
((CommentBaseViewHolder) viewHolder).downvoteButton.performClick();
}
} else {
if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) {
((CommentViewHolder) viewHolder).upvoteButton.performClick();
((CommentBaseViewHolder) viewHolder).upvoteButton.performClick();
} else if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) {
((CommentViewHolder) viewHolder).downvoteButton.performClick();
((CommentBaseViewHolder) viewHolder).downvoteButton.performClick();
}
}
}
@@ -318,46 +321,60 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
void retryLoadingMore();
}
public class CommentViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.vertical_block_indentation_item_comment)
CommentIndentationView commentIndentationView;
@BindView(R.id.linear_layout_item_comment)
public class CommentBaseViewHolder extends RecyclerView.ViewHolder {
LinearLayout linearLayout;
@BindView(R.id.author_text_view_item_post_comment)
TextView authorTextView;
@BindView(R.id.author_flair_text_view_item_post_comment)
TextView authorFlairTextView;
@BindView(R.id.comment_time_text_view_item_post_comment)
TextView commentTimeTextView;
@BindView(R.id.awards_text_view_item_comment)
TextView awardsTextView;
@BindView(R.id.comment_markdown_view_item_post_comment)
RecyclerView commentMarkdownView;
@BindView(R.id.bottom_constraint_layout_item_post_comment)
ConstraintLayout bottomConstraintLayout;
@BindView(R.id.up_vote_button_item_post_comment)
ImageView upvoteButton;
@BindView(R.id.score_text_view_item_post_comment)
MaterialButton upvoteButton;
TextView scoreTextView;
@BindView(R.id.down_vote_button_item_post_comment)
ImageView downvoteButton;
@BindView(R.id.placeholder_item_post_comment)
MaterialButton downvoteButton;
View placeholder;
@BindView(R.id.more_button_item_post_comment)
ImageView moreButton;
@BindView(R.id.save_button_item_post_comment)
ImageView saveButton;
@BindView(R.id.expand_button_item_post_comment)
TextView expandButton;
@BindView(R.id.reply_button_item_post_comment)
ImageView replyButton;
@BindView(R.id.divider_item_comment)
MaterialButton moreButton;
MaterialButton saveButton;
MaterialButton replyButton;
View commentDivider;
CustomMarkwonAdapter markwonAdapter;
CommentViewHolder(View itemView) {
CommentBaseViewHolder(@NonNull View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
void setBaseView(LinearLayout linearLayout,
TextView authorTextView,
TextView authorFlairTextView,
TextView commentTimeTextView,
TextView awardsTextView,
RecyclerView commentMarkdownView,
ConstraintLayout bottomConstraintLayout,
MaterialButton upvoteButton,
TextView scoreTextView,
MaterialButton downvoteButton,
View placeholder,
MaterialButton moreButton,
MaterialButton saveButton,
TextView expandButton,
MaterialButton replyButton,
CommentIndentationView commentIndentationView,
View commentDivider) {
this.linearLayout = linearLayout;
this.authorTextView = authorTextView;
this.authorFlairTextView = authorFlairTextView;
this.commentTimeTextView = commentTimeTextView;
this.awardsTextView = awardsTextView;
this.commentMarkdownView = commentMarkdownView;
this.bottomConstraintLayout = bottomConstraintLayout;
this.upvoteButton = upvoteButton;
this.scoreTextView = scoreTextView;
this.downvoteButton = downvoteButton;
this.placeholder = placeholder;
this.moreButton = moreButton;
this.saveButton = saveButton;
this.replyButton = replyButton;
this.commentDivider = commentDivider;
replyButton.setVisibility(View.GONE);
@@ -413,19 +430,19 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
authorFlairTextView.setTypeface(mActivity.typeface);
commentTimeTextView.setTypeface(mActivity.typeface);
awardsTextView.setTypeface(mActivity.typeface);
scoreTextView.setTypeface(mActivity.typeface);
upvoteButton.setTypeface(mActivity.typeface);
}
itemView.setBackgroundColor(mCommentBackgroundColor);
authorTextView.setTextColor(mUsernameColor);
authorFlairTextView.setTextColor(mAuthorFlairColor);
commentTimeTextView.setTextColor(mSecondaryTextColor);
awardsTextView.setTextColor(mSecondaryTextColor);
upvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN);
upvoteButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor));
scoreTextView.setTextColor(mCommentIconAndInfoColor);
downvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN);
moreButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN);
saveButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN);
replyButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN);
downvoteButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor));
moreButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor));
saveButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor));
replyButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor));
commentDivider.setBackgroundColor(mDividerColor);
authorTextView.setOnClickListener(view -> {
@@ -450,7 +467,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
Comment comment = getItem(getBindingAdapterPosition());
if (comment != null) {
Bundle bundle = new Bundle();
if (comment.getAuthor().equals(mAccountName)) {
if (comment.getAuthorName().equals(mAccountName)) {
bundle.putBoolean(CommentMoreBottomSheetFragment.EXTRA_EDIT_AND_DELETE_AVAILABLE, true);
}
bundle.putString(CommentMoreBottomSheetFragment.EXTRA_ACCESS_TOKEN, mAccessToken);
@@ -472,6 +489,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
Intent intent = new Intent(mActivity, ViewPostDetailActivity.class);
intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, comment.getPostId());
intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_ID, comment.getId());
intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_PARENT_ID, comment.getParentId());
mActivity.startActivity(intent);
}
});
@@ -516,20 +534,22 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
int previousVoteType = comment.getVoteType();
int newVoteType;
downvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN);
downvoteButton.setIconResource(R.drawable.ic_downvote_24dp);
downvoteButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor));
if (previousVoteType != Comment.VOTE_TYPE_UPVOTE) {
//Not upvoted before
comment.setVoteType(Comment.VOTE_TYPE_UPVOTE);
newVoteType = Integer.parseInt(APIUtils.DIR_UPVOTE);
upvoteButton
.setColorFilter(mUpvotedColor, PorterDuff.Mode.SRC_IN);
upvoteButton.setIconResource(R.drawable.ic_upvote_filled_24dp);
upvoteButton.setIconTint(ColorStateList.valueOf(mUpvotedColor));
scoreTextView.setTextColor(mUpvotedColor);
} else {
//Upvoted before
comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE);
newVoteType = Integer.parseInt(APIUtils.DIR_UNVOTE);
upvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN);
upvoteButton.setIconResource(R.drawable.ic_upvote_24dp);
upvoteButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor));
scoreTextView.setTextColor(mCommentIconAndInfoColor);
}
@@ -545,23 +565,25 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
if (newVoteType == Integer.parseInt(APIUtils.DIR_UPVOTE)) {
comment.setVoteType(Comment.VOTE_TYPE_UPVOTE);
if (currentPosition == position) {
upvoteButton.setColorFilter(mUpvotedColor, PorterDuff.Mode.SRC_IN);
upvoteButton.setIconResource(R.drawable.ic_upvote_filled_24dp);
upvoteButton.setIconTint(ColorStateList.valueOf(mUpvotedColor));
scoreTextView.setTextColor(mUpvotedColor);
}
} else {
comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE);
if (currentPosition == position) {
upvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN);
upvoteButton.setIconResource(R.drawable.ic_upvote_24dp);
upvoteButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor));
scoreTextView.setTextColor(mCommentIconAndInfoColor);
}
}
if (currentPosition == position) {
downvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN);
downvoteButton.setIconResource(R.drawable.ic_downvote_24dp);
downvoteButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor));
scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes,
comment.getScore() + comment.getVoteType()));
}
}
@@ -572,6 +594,10 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
}
});
scoreTextView.setOnClickListener(view -> {
upvoteButton.performClick();
});
downvoteButton.setOnClickListener(view -> {
if (mAccessToken == null) {
Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show();
@@ -587,19 +613,22 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
int previousVoteType = comment.getVoteType();
int newVoteType;
upvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN);
upvoteButton.setIconResource(R.drawable.ic_upvote_24dp);
upvoteButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor));
if (previousVoteType != Comment.VOTE_TYPE_DOWNVOTE) {
//Not downvoted before
comment.setVoteType(Comment.VOTE_TYPE_DOWNVOTE);
newVoteType = Integer.parseInt(APIUtils.DIR_DOWNVOTE);
downvoteButton.setColorFilter(mDownvotedColor, PorterDuff.Mode.SRC_IN);
downvoteButton.setIconResource(R.drawable.ic_downvote_filled_24dp);
downvoteButton.setIconTint(ColorStateList.valueOf(mDownvotedColor));
scoreTextView.setTextColor(mDownvotedColor);
} else {
//Downvoted before
comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE);
newVoteType = Integer.parseInt(APIUtils.DIR_UNVOTE);
downvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN);
downvoteButton.setIconResource(R.drawable.ic_downvote_24dp);
downvoteButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor));
scoreTextView.setTextColor(mCommentIconAndInfoColor);
}
@@ -615,22 +644,24 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
if (newVoteType == Integer.parseInt(APIUtils.DIR_DOWNVOTE)) {
comment.setVoteType(Comment.VOTE_TYPE_DOWNVOTE);
if (currentPosition == position) {
downvoteButton.setColorFilter(mDownvotedColor, PorterDuff.Mode.SRC_IN);
downvoteButton.setIconResource(R.drawable.ic_downvote_filled_24dp);
downvoteButton.setIconTint(ColorStateList.valueOf(mDownvotedColor));
scoreTextView.setTextColor(mDownvotedColor);
}
} else {
comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE);
if (currentPosition == position) {
downvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN);
downvoteButton.setIconResource(R.drawable.ic_downvote_24dp);
downvoteButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor));
scoreTextView.setTextColor(mCommentIconAndInfoColor);
}
}
if (currentPosition == position) {
upvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN);
upvoteButton.setIconResource(R.drawable.ic_upvote_24dp);
upvoteButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor));
scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes,
comment.getScore() + comment.getVoteType()));
}
}
@@ -656,7 +687,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
public void success() {
comment.setSaved(false);
if (getBindingAdapterPosition() == position) {
saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp);
saveButton.setIconResource(R.drawable.ic_bookmark_border_grey_24dp);
}
Toast.makeText(mActivity, R.string.comment_unsaved_success, Toast.LENGTH_SHORT).show();
}
@@ -665,7 +696,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
public void failed() {
comment.setSaved(true);
if (getBindingAdapterPosition() == position) {
saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp);
saveButton.setIconResource(R.drawable.ic_bookmark_grey_24dp);
}
Toast.makeText(mActivity, R.string.comment_unsaved_failed, Toast.LENGTH_SHORT).show();
}
@@ -677,7 +708,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
public void success() {
comment.setSaved(true);
if (getBindingAdapterPosition() == position) {
saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp);
saveButton.setIconResource(R.drawable.ic_bookmark_grey_24dp);
}
Toast.makeText(mActivity, R.string.comment_saved_success, Toast.LENGTH_SHORT).show();
}
@@ -686,7 +717,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
public void failed() {
comment.setSaved(false);
if (getBindingAdapterPosition() == position) {
saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp);
saveButton.setIconResource(R.drawable.ic_bookmark_border_grey_24dp);
}
Toast.makeText(mActivity, R.string.comment_saved_failed, Toast.LENGTH_SHORT).show();
}
@@ -697,6 +728,32 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
}
}
class CommentViewHolder extends CommentBaseViewHolder {
ItemCommentBinding binding;
CommentViewHolder(ItemCommentBinding binding) {
super(binding.getRoot());
this.binding = binding;
setBaseView(binding.linearLayoutItemComment,
binding.authorTextViewItemPostComment,
binding.authorFlairTextViewItemPostComment,
binding.commentTimeTextViewItemPostComment,
binding.awardsTextViewItemComment,
binding.commentMarkdownViewItemPostComment,
binding.bottomConstraintLayoutItemPostComment,
binding.upvoteButtonItemPostComment,
binding.scoreTextViewItemPostComment,
binding.downvoteButtonItemPostComment,
binding.placeholderItemPostComment,
binding.moreButtonItemPostComment,
binding.saveButtonItemPostComment,
binding.expandButtonItemPostComment,
binding.replyButtonItemPostComment,
binding.verticalBlockIndentationItemComment,
binding.dividerItemComment);
}
}
class ErrorViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.error_text_view_item_footer_error)
TextView errorTextView;

View File

@@ -0,0 +1,41 @@
package eu.toldi.infinityforlemmy.adapters;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import androidx.annotation.NonNull;
import java.util.List;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
public class CustomArrayAdapter extends ArrayAdapter<String> {
CustomThemeWrapper customThemeWrapper;
public CustomArrayAdapter(@NonNull Context context, int textViewResourceId, @NonNull List<String> objects, CustomThemeWrapper customThemeWrapper) {
super(context, textViewResourceId, objects);
this.customThemeWrapper = customThemeWrapper;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView itemView = (TextView) super.getView(position, convertView, parent);
itemView.setTextColor(customThemeWrapper.getPrimaryTextColor()); // Set the text color
itemView.setBackgroundColor(customThemeWrapper.getBackgroundColor()); // Set the background color
// Apply any other styling as needed
return itemView;
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
TextView itemView = (TextView) super.getDropDownView(position, convertView, parent);
itemView.setTextColor(customThemeWrapper.getPrimaryTextColor()); // Set the text color
itemView.setBackgroundColor(customThemeWrapper.getBackgroundColor()); // Set the background color
// Apply any other styling as needed
return itemView;
}
}

View File

@@ -19,24 +19,13 @@ import androidx.recyclerview.widget.RecyclerView;
import org.greenrobot.eventbus.EventBus;
import java.util.ArrayList;
import butterknife.BindView;
import butterknife.ButterKnife;
import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon;
import io.noties.markwon.MarkwonConfiguration;
import io.noties.markwon.core.MarkwonTheme;
import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import io.noties.markwon.inlineparser.BangInlineProcessor;
import io.noties.markwon.inlineparser.HtmlInlineProcessor;
import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin;
import io.noties.markwon.linkify.LinkifyPlugin;
import io.noties.markwon.movement.MovementMethodPlugin;
import eu.toldi.infinityforlemmy.NetworkState;
import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.activities.BaseActivity;
import eu.toldi.infinityforlemmy.activities.LinkResolverActivity;
import eu.toldi.infinityforlemmy.activities.ViewPostDetailActivity;
import eu.toldi.infinityforlemmy.activities.ViewPrivateMessagesActivity;
import eu.toldi.infinityforlemmy.activities.ViewUserDetailActivity;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
@@ -45,28 +34,38 @@ import eu.toldi.infinityforlemmy.markdown.RedditHeadingPlugin;
import eu.toldi.infinityforlemmy.markdown.SpoilerAwareMovementMethod;
import eu.toldi.infinityforlemmy.markdown.SpoilerParserPlugin;
import eu.toldi.infinityforlemmy.markdown.SuperscriptPlugin;
import eu.toldi.infinityforlemmy.message.CommentInteraction;
import eu.toldi.infinityforlemmy.message.FetchMessage;
import eu.toldi.infinityforlemmy.message.Message;
import eu.toldi.infinityforlemmy.message.ReadMessage;
import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon;
import io.noties.markwon.MarkwonConfiguration;
import io.noties.markwon.core.MarkwonTheme;
import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import io.noties.markwon.image.glide.GlideImagesPlugin;
import io.noties.markwon.inlineparser.HtmlInlineProcessor;
import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin;
import io.noties.markwon.linkify.LinkifyPlugin;
import io.noties.markwon.movement.MovementMethodPlugin;
import retrofit2.Retrofit;
public class MessageRecyclerViewAdapter extends PagedListAdapter<Message, RecyclerView.ViewHolder> {
public class MessageRecyclerViewAdapter extends PagedListAdapter<CommentInteraction, RecyclerView.ViewHolder> {
private static final int VIEW_TYPE_DATA = 0;
private static final int VIEW_TYPE_ERROR = 1;
private static final int VIEW_TYPE_LOADING = 2;
private static final DiffUtil.ItemCallback<Message> DIFF_CALLBACK = new DiffUtil.ItemCallback<>() {
private static final DiffUtil.ItemCallback<CommentInteraction> DIFF_CALLBACK = new DiffUtil.ItemCallback<>() {
@Override
public boolean areItemsTheSame(@NonNull Message message, @NonNull Message t1) {
return message.getId().equals(t1.getId());
public boolean areItemsTheSame(@NonNull CommentInteraction message, @NonNull CommentInteraction t1) {
return message.getComment().getId() == t1.getComment().getId();
}
@Override
public boolean areContentsTheSame(@NonNull Message message, @NonNull Message t1) {
return message.getBody().equals(t1.getBody());
public boolean areContentsTheSame(@NonNull CommentInteraction message, @NonNull CommentInteraction t1) {
return message.getComment().getCommentMarkdown().equals(t1.getComment().getCommentMarkdown());
}
};
private BaseActivity mActivity;
private Retrofit mOauthRetrofit;
private Retrofit retrofit;
private Markwon mMarkwon;
private String mAccessToken;
private int mMessageType;
@@ -88,7 +87,7 @@ public class MessageRecyclerViewAdapter extends PagedListAdapter<Message, Recycl
RetryLoadingMoreCallback retryLoadingMoreCallback) {
super(DIFF_CALLBACK);
mActivity = activity;
mOauthRetrofit = oauthRetrofit;
retrofit = oauthRetrofit;
mRetryLoadingMoreCallback = retryLoadingMoreCallback;
mColorAccent = customThemeWrapper.getColorAccent();
@@ -106,7 +105,6 @@ public class MessageRecyclerViewAdapter extends PagedListAdapter<Message, Recycl
mMarkwon = Markwon.builder(mActivity)
.usePlugin(MarkwonInlineParserPlugin.create(plugin -> {
plugin.excludeInlineProcessor(HtmlInlineProcessor.class);
plugin.excludeInlineProcessor(BangInlineProcessor.class);
}))
.usePlugin(new AbstractMarkwonPlugin() {
@Override
@@ -130,6 +128,7 @@ public class MessageRecyclerViewAdapter extends PagedListAdapter<Message, Recycl
.usePlugin(StrikethroughPlugin.create())
.usePlugin(MovementMethodPlugin.create(new SpoilerAwareMovementMethod()))
.usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS))
.usePlugin(GlideImagesPlugin.create(mActivity))
.build();
mAccessToken = accessToken;
if (where.equals(FetchMessage.WHERE_MESSAGES)) {
@@ -154,41 +153,38 @@ public class MessageRecyclerViewAdapter extends PagedListAdapter<Message, Recycl
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (holder instanceof DataViewHolder) {
Message message = getItem(holder.getBindingAdapterPosition());
CommentInteraction message = getItem(holder.getBindingAdapterPosition());
if (message != null) {
ArrayList<Message> replies = message.getReplies();
Message displayedMessage;
if (replies != null && !replies.isEmpty() && replies.get(replies.size() - 1) != null) {
displayedMessage = replies.get(replies.size() - 1);
} else {
displayedMessage = message;
}
if (message.isNew()) {
if (message.isRead()) {
if (markAllMessagesAsRead) {
message.setNew(false);
message.markAsRead();
} else {
holder.itemView.setBackgroundColor(
mUnreadMessageBackgroundColor);
}
}
if (message.wasComment()) {
((DataViewHolder) holder).titleTextView.setText(message.getTitle());
} else {
((DataViewHolder) holder).titleTextView.setVisibility(View.GONE);
}
((DataViewHolder) holder).authorTextView.setText(displayedMessage.getAuthor());
String subject = displayedMessage.getSubject().substring(0, 1).toUpperCase() + displayedMessage.getSubject().substring(1);
((DataViewHolder) holder).titleTextView.setVisibility(View.GONE);
((DataViewHolder) holder).authorTextView.setText(message.getComment().getAuthorQualifiedName());
String subject = message.getComment().getCommunityQualifiedName();
((DataViewHolder) holder).subjectTextView.setText(subject);
mMarkwon.setMarkdown(((DataViewHolder) holder).contentCustomMarkwonView, displayedMessage.getBody());
mMarkwon.setMarkdown(((DataViewHolder) holder).contentCustomMarkwonView, message.getComment().getCommentMarkdown());
holder.itemView.setOnClickListener(view -> {
if (mMessageType == FetchMessage.MESSAGE_TYPE_INBOX
&& message.getContext() != null && !message.getContext().equals("")) {
Uri uri = Uri.parse(message.getContext());
Intent intent = new Intent(mActivity, LinkResolverActivity.class);
intent.setData(uri);
&& message.getComment() != null) {
Intent intent = new Intent(mActivity, ViewPostDetailActivity.class);
intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, message.getComment().getPostId());
intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_ID, message.getComment().getId());
if(message.getComment().getDepth() > 0) {
intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_PARENT_ID, message.getComment().getParentId());
}
mActivity.startActivity(intent);
} else if (mMessageType == FetchMessage.MESSAGE_TYPE_PRIVATE_MESSAGE) {
Intent intent = new Intent(mActivity, ViewPrivateMessagesActivity.class);
@@ -197,20 +193,21 @@ public class MessageRecyclerViewAdapter extends PagedListAdapter<Message, Recycl
mActivity.startActivity(intent);
}
if (displayedMessage.isNew()) {
if (message.isRead()) {
holder.itemView.setBackgroundColor(mMessageBackgroundColor);
message.setNew(false);
ReadMessage.readMessage(mOauthRetrofit, mAccessToken, message.getFullname(),
ReadMessage.readMessage(retrofit, mAccessToken, message.getId(),
new ReadMessage.ReadMessageListener() {
@Override
public void readSuccess() {
message.markAsRead();
EventBus.getDefault().post(new ChangeInboxCountEvent(-1));
}
@Override
public void readFailed() {
message.setNew(true);
message.markAsUnRead();
holder.itemView.setBackgroundColor(mUnreadMessageBackgroundColor);
}
});
@@ -218,11 +215,10 @@ public class MessageRecyclerViewAdapter extends PagedListAdapter<Message, Recycl
});
((DataViewHolder) holder).authorTextView.setOnClickListener(view -> {
if (message.isAuthorDeleted()) {
return;
}
Intent intent = new Intent(mActivity, ViewUserDetailActivity.class);
intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, message.getAuthor());
intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, message.getComment().getAuthorName());
intent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, message.getComment().getAuthorQualifiedName());
mActivity.startActivity(intent);
});
}
@@ -280,9 +276,9 @@ public class MessageRecyclerViewAdapter extends PagedListAdapter<Message, Recycl
}
}
public void updateMessageReply(Message newReply, int position) {
public void updateMessageReply(CommentInteraction newReply, int position) {
if (position >= 0 && position < super.getItemCount()) {
Message message = getItem(position);
CommentInteraction message = getItem(position);
if (message != null) {
notifyItemChanged(position);
}

View File

@@ -0,0 +1,20 @@
package eu.toldi.infinityforlemmy.adapters;
import eu.toldi.infinityforlemmy.activities.BaseActivity;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.user.BasicUserRecyclerViewAdapter;
public class ModeratorRecyclerViewAdapter extends BasicUserRecyclerViewAdapter {
private final int mModeratorColor;
public ModeratorRecyclerViewAdapter(BaseActivity activity, CustomThemeWrapper customThemeWrapper) {
super(activity, customThemeWrapper);
mModeratorColor = customThemeWrapper.getModerator();
}
@Override
protected int getUserNameTextColor() {
return mModeratorColor;
}
}

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