Compare commits

..

186 commits

Author SHA1 Message Date
7269444a31
misc improvements
Some checks failed
Mirror to Codeberg / sync-git (push) Has been cancelled
Validate Gradle Wrapper / Validation (push) Has been cancelled
Nightly builds / build (push) Has been cancelled
2025-03-20 09:28:22 -04:00
ab3d3ff068
add support for sending bites
Some checks failed
Nightly builds / build (push) Waiting to run
Mirror to Codeberg / sync-git (push) Has been cancelled
Validate Gradle Wrapper / Validation (push) Has been cancelled
2025-03-19 20:57:31 -04:00
LucasGGamerM
ab72435347
Merge pull request #516
Iceshrimp improvements
2025-03-19 10:58:36 -03:00
LucasGGamerM
d5f6852bdc Merge: feat(Timeline/Hashtag): show confirmation sheet when muting 2025-03-17 22:27:07 -03:00
LucasGGamerM
36f96c1ed6
misc(github-actions): create mirror-to-codeberg.yml 2025-03-15 09:05:34 -03:00
LucasGGamerM
058fb62253 fix(unified-push-connector): remove try catches that are no longer needed 2025-03-13 08:26:31 -03:00
LucasGGamerM
bc43e2180f build(unified-push-connector): update the dependency 2025-03-13 08:25:56 -03:00
LucasGGamerM
c1e96d4ff0 fix(enhance-text-size): just enhance the font size, not the whole app's density 2025-03-12 10:40:50 -03:00
LucasGGamerM
42a060e8a6 build(unified-push): update unifiedPush connector dependency 2025-03-11 19:22:08 -03:00
LucasGGamerM
065db923cc fix(unifiedPushHelper): surround by try and catch due to a javax.crypto.AEADBadTagException
cc: @p1gp1g
2025-03-11 14:52:07 -03:00
openhuman
0089a10a81 Translated using Weblate (German)
Currently translated at 100.0% (40 of 40 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/de/
2025-03-11 10:21:45 -03:00
notAvi10
c6d4436467 Translated using Weblate (Esperanto)
Currently translated at 100.0% (122 of 122 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/eo/
2025-03-11 10:21:45 -03:00
notAvi10
98d58c35dc Translated using Weblate (Esperanto)
Currently translated at 50.0% (20 of 40 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/eo/
2025-03-11 10:21:45 -03:00
guille11
3f7c0417c2 Translated using Weblate (Asturian)
Currently translated at 74.5% (313 of 420 strings)

Translation: Moshidon/megalodon_values
Translate-URL: https://translate.codeberg.org/projects/moshidon/megalodon_values/ast/
2025-03-11 10:21:45 -03:00
Ricky-Tigg
64dcb8b387 Translated using Weblate (Finnish)
Currently translated at 5.0% (2 of 40 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/fi/
2025-03-11 10:21:45 -03:00
Ricky-Tigg
4145b6451b Translated using Weblate (Finnish)
Currently translated at 9.8% (12 of 122 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/fi/
2025-03-11 10:21:45 -03:00
Linerly
188b3fade7 Translated using Weblate (Indonesian)
Currently translated at 100.0% (40 of 40 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/id/
2025-03-11 10:21:45 -03:00
dieguitux8623
87800a696a Translated using Weblate (Italian)
Currently translated at 100.0% (40 of 40 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/it/
2025-03-11 10:21:45 -03:00
dieguitux8623
f51891f64c Translated using Weblate (Italian)
Currently translated at 100.0% (122 of 122 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/it/
2025-03-11 10:21:45 -03:00
guille11
45c822c48d Translated using Weblate (Asturian)
Currently translated at 68.8% (84 of 122 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/ast/
2025-03-11 10:21:45 -03:00
Eryk Michalak
a1eae5a1a1 Translated using Weblate (Polish)
Currently translated at 100.0% (420 of 420 strings)

Translation: Moshidon/megalodon_values
Translate-URL: https://translate.codeberg.org/projects/moshidon/megalodon_values/pl/
2025-03-11 10:21:45 -03:00
Eryk Michalak
73926e0ac1 Translated using Weblate (Polish)
Currently translated at 99.1% (121 of 122 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/pl/
2025-03-11 10:21:45 -03:00
brli
00333604c9 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 15.0% (6 of 40 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/zh_Hant/
2025-03-11 10:21:45 -03:00
brli
8aa9e99e91 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 12.5% (5 of 40 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/zh_Hant/
2025-03-11 10:21:45 -03:00
Vaclovas Intas
5159e8fbda Translated using Weblate (Lithuanian)
Currently translated at 100.0% (420 of 420 strings)

Translation: Moshidon/megalodon_values
Translate-URL: https://translate.codeberg.org/projects/moshidon/megalodon_values/lt/
2025-03-11 10:21:45 -03:00
GunChleoc
6cf3253d40 Translated using Weblate (Gaelic)
Currently translated at 100.0% (420 of 420 strings)

Translation: Moshidon/megalodon_values
Translate-URL: https://translate.codeberg.org/projects/moshidon/megalodon_values/gd/
2025-03-11 10:21:45 -03:00
GunChleoc
b769bf5ee4 Translated using Weblate (Gaelic)
Currently translated at 99.1% (121 of 122 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/gd/
2025-03-11 10:21:45 -03:00
Vaclovas Intas
7adb3c7b39 Translated using Weblate (Lithuanian)
Currently translated at 100.0% (420 of 420 strings)

Translation: Moshidon/megalodon_values
Translate-URL: https://translate.codeberg.org/projects/moshidon/megalodon_values/lt/
2025-03-11 10:21:45 -03:00
Metanoir
4f33194884 Translated using Weblate (Turkish)
Currently translated at 0.7% (3 of 420 strings)

Translation: Moshidon/megalodon_values
Translate-URL: https://translate.codeberg.org/projects/moshidon/megalodon_values/tr/
2025-03-11 10:21:45 -03:00
Metanoir
bfaa6e12a7 Translated using Weblate (Turkish)
Currently translated at 2.5% (1 of 40 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/tr/
2025-03-11 10:21:45 -03:00
guille11
e48143585e Translated using Weblate (Asturian)
Currently translated at 57.3% (70 of 122 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/ast/
2025-03-11 10:21:45 -03:00
guille11
3f60beb999 Translated using Weblate (Asturian)
Currently translated at 0.0% (0 of 40 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/ast/
2025-03-11 10:21:45 -03:00
guille11
a952a17a18 Translated using Weblate (Asturian)
Currently translated at 74.5% (313 of 420 strings)

Translation: Moshidon/megalodon_values
Translate-URL: https://translate.codeberg.org/projects/moshidon/megalodon_values/ast/
2025-03-11 10:21:45 -03:00
Languages add-on
ae966cc784 Added translation using Weblate (Asturian) 2025-03-11 10:21:45 -03:00
guille11
5b684bd9b3 Added translation using Weblate (Asturian) 2025-03-11 10:21:45 -03:00
aindriu80
251a518e56 Translated using Weblate (Irish)
Currently translated at 100.0% (420 of 420 strings)

Translation: Moshidon/megalodon_values
Translate-URL: https://translate.codeberg.org/projects/moshidon/megalodon_values/ga/
2025-03-11 10:21:45 -03:00
aindriu80
0156f8a732 Translated using Weblate (Irish)
Currently translated at 100.0% (122 of 122 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/ga/
2025-03-11 10:21:45 -03:00
aindriu80
20464001b8 Translated using Weblate (Irish)
Currently translated at 100.0% (40 of 40 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/ga/
2025-03-11 10:21:45 -03:00
irure
2d4f3b9a88 Translated using Weblate (Basque)
Currently translated at 76.4% (321 of 420 strings)

Translation: Moshidon/megalodon_values
Translate-URL: https://translate.codeberg.org/projects/moshidon/megalodon_values/eu/
2025-03-11 10:21:45 -03:00
SomeTr
66afd9d091 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (122 of 122 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/uk/
2025-03-11 10:21:45 -03:00
dampuzakura
69562fa3e4 Translated using Weblate (Japanese)
Currently translated at 99.2% (417 of 420 strings)

Translation: Moshidon/megalodon_values
Translate-URL: https://translate.codeberg.org/projects/moshidon/megalodon_values/ja/
2025-03-11 10:21:45 -03:00
dampuzakura
9e2839c0ae Translated using Weblate (Japanese)
Currently translated at 20.0% (8 of 40 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/ja/
2025-03-11 10:21:45 -03:00
dampuzakura
f1b9f110d2 Translated using Weblate (Japanese)
Currently translated at 100.0% (122 of 122 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/ja/
2025-03-11 10:21:45 -03:00
Linerly
94cb110f99 Translated using Weblate (Indonesian)
Currently translated at 100.0% (122 of 122 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/id/
2025-03-11 10:21:45 -03:00
Vaclovas Intas
07a29564d5 Translated using Weblate (Lithuanian)
Currently translated at 47.5% (19 of 40 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/lt/
2025-03-11 10:21:45 -03:00
yeyueww
015d416773 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 91.9% (386 of 420 strings)

Translation: Moshidon/megalodon_values
Translate-URL: https://translate.codeberg.org/projects/moshidon/megalodon_values/zh_Hant/
2025-03-11 10:21:45 -03:00
kdh8219
2fea6a2934 Translated using Weblate (Korean)
Currently translated at 95.7% (402 of 420 strings)

Translation: Moshidon/megalodon_values
Translate-URL: https://translate.codeberg.org/projects/moshidon/megalodon_values/ko/
2025-03-11 10:21:45 -03:00
yeyueww
3af59de797 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 7.5% (3 of 40 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/zh_Hant/
2025-03-11 10:21:45 -03:00
yeyueww
543f7ab30a Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 7.3% (9 of 122 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/zh_Hant/
2025-03-11 10:21:45 -03:00
Vaclovas Intas
dacc32dcaa Translated using Weblate (Lithuanian)
Currently translated at 47.5% (19 of 40 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/lt/
2025-03-11 10:21:45 -03:00
Vaclovas Intas
45568f600a Translated using Weblate (Lithuanian)
Currently translated at 100.0% (420 of 420 strings)

Translation: Moshidon/megalodon_values
Translate-URL: https://translate.codeberg.org/projects/moshidon/megalodon_values/lt/
2025-03-11 10:21:45 -03:00
butterflyoffire
df96e6af31 Translated using Weblate (French)
Currently translated at 99.0% (416 of 420 strings)

Translation: Moshidon/megalodon_values
Translate-URL: https://translate.codeberg.org/projects/moshidon/megalodon_values/fr/
2025-03-11 10:21:45 -03:00
butterflyoffire
c7b58a0982 Translated using Weblate (Arabic (Algeria))
Currently translated at 43.5% (183 of 420 strings)

Translation: Moshidon/megalodon_values
Translate-URL: https://translate.codeberg.org/projects/moshidon/megalodon_values/ar_DZ/
2025-03-11 10:21:45 -03:00
butterflyoffire
463933b19a Translated using Weblate (Arabic (Algeria))
Currently translated at 90.9% (111 of 122 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/ar_DZ/
2025-03-11 10:21:45 -03:00
butterflyoffire
53f3a42588 Translated using Weblate (French)
Currently translated at 100.0% (122 of 122 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/fr/
2025-03-11 10:21:45 -03:00
Vaclovas Intas
9338fbc246 Translated using Weblate (Lithuanian)
Currently translated at 47.5% (19 of 40 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/lt/
2025-03-11 10:21:45 -03:00
lizarion
54d074839c Translated using Weblate (Basque)
Currently translated at 74.5% (313 of 420 strings)

Translation: Moshidon/megalodon_values
Translate-URL: https://translate.codeberg.org/projects/moshidon/megalodon_values/eu/
2025-03-11 10:21:45 -03:00
butterflyoffire
0424dcd6ca Translated using Weblate (French)
Currently translated at 97.1% (408 of 420 strings)

Translation: Moshidon/megalodon_values
Translate-URL: https://translate.codeberg.org/projects/moshidon/megalodon_values/fr/
2025-03-11 10:21:45 -03:00
Vaclovas Intas
dedd1a7b70 Translated using Weblate (Lithuanian)
Currently translated at 100.0% (122 of 122 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/lt/
2025-03-11 10:21:45 -03:00
Vaclovas Intas
7684b6705c Translated using Weblate (Lithuanian)
Currently translated at 45.0% (18 of 40 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/lt/
2025-03-11 10:21:45 -03:00
gallegonovato
86d01cbb97 Translated using Weblate (Spanish)
Currently translated at 100.0% (40 of 40 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/es/
2025-03-11 10:21:45 -03:00
gallegonovato
3ca18ed38b Translated using Weblate (Spanish)
Currently translated at 100.0% (122 of 122 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/es/
2025-03-11 10:21:45 -03:00
Lefteris T
5a5c2fbc69 Translated using Weblate (Greek)
Currently translated at 100.0% (122 of 122 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/el/
2025-03-11 10:21:45 -03:00
SomeTr
4bbeb4f198 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (420 of 420 strings)

Translation: Moshidon/megalodon_values
Translate-URL: https://translate.codeberg.org/projects/moshidon/megalodon_values/uk/
2025-03-11 10:21:45 -03:00
SomeTr
2133ca7188 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (420 of 420 strings)

Translation: Moshidon/megalodon_values
Translate-URL: https://translate.codeberg.org/projects/moshidon/megalodon_values/uk/
2025-03-11 10:21:45 -03:00
SomeTr
33a71e1c46 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (40 of 40 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/uk/
2025-03-11 10:21:45 -03:00
ghose
0cba8f30a6 Translated using Weblate (Galician)
Currently translated at 55.0% (22 of 40 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/gl/
2025-03-11 10:21:45 -03:00
SomeTr
0241628cf5 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (122 of 122 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/uk/
2025-03-11 10:21:45 -03:00
alextecplayz
a4bac9c100 Translated using Weblate (Romanian)
Currently translated at 100.0% (122 of 122 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/ro/
2025-03-11 10:21:45 -03:00
ghose
915bd41b71 Translated using Weblate (Galician)
Currently translated at 100.0% (122 of 122 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/gl/
2025-03-11 10:21:45 -03:00
nethad
32c3b81ec3 Translated using Weblate (German)
Currently translated at 100.0% (122 of 122 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/de/
2025-03-11 10:21:44 -03:00
nethad
fad20394ff Translated using Weblate (German)
Currently translated at 95.0% (38 of 40 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/de/
2025-03-11 10:21:44 -03:00
Outbreak2096
fba279f43e Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (40 of 40 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/zh_Hans/
2025-03-11 10:21:44 -03:00
Outbreak2096
a8fd78b1a8 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (122 of 122 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/zh_Hans/
2025-03-11 10:21:44 -03:00
SomeTr
19390221ec Translated using Weblate (Ukrainian)
Currently translated at 100.0% (122 of 122 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/uk/
2025-03-11 10:21:44 -03:00
Vaclovas Intas
ab47192b2c Translated using Weblate (Lithuanian)
Currently translated at 38.4% (15 of 39 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/lt/
2025-03-11 10:21:44 -03:00
Outbreak2096
e9c01a5452 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (420 of 420 strings)

Translation: Moshidon/megalodon_values
Translate-URL: https://translate.codeberg.org/projects/moshidon/megalodon_values/zh_Hans/
2025-03-11 10:21:44 -03:00
Vaclovas Intas
bc45072542 Translated using Weblate (Lithuanian)
Currently translated at 33.3% (13 of 39 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/lt/
2025-03-11 10:21:44 -03:00
Andrewblasco
e24bfb0448 Translated using Weblate (Spanish)
Currently translated at 100.0% (420 of 420 strings)

Translation: Moshidon/megalodon_values
Translate-URL: https://translate.codeberg.org/projects/moshidon/megalodon_values/es/
2025-03-11 10:21:44 -03:00
nethad
673ada4782 Translated using Weblate (German)
Currently translated at 100.0% (420 of 420 strings)

Translation: Moshidon/megalodon_values
Translate-URL: https://translate.codeberg.org/projects/moshidon/megalodon_values/de/
2025-03-11 10:21:44 -03:00
Andrewblasco
ee02634036 Translated using Weblate (Spanish)
Currently translated at 100.0% (39 of 39 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/es/
2025-03-11 10:21:44 -03:00
Andrewblasco
1c42b9a4e7 Translated using Weblate (Spanish)
Currently translated at 100.0% (121 of 121 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/es/
2025-03-11 10:21:44 -03:00
eana
3bd855ed1e Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (420 of 420 strings)

Translation: Moshidon/megalodon_values
Translate-URL: https://translate.codeberg.org/projects/moshidon/megalodon_values/zh_Hans/
2025-03-11 10:21:44 -03:00
eana
fba7650918 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (39 of 39 strings)

Translation: Moshidon/metadata
Translate-URL: https://translate.codeberg.org/projects/moshidon/metadata/zh_Hans/
2025-03-11 10:21:44 -03:00
poesty
c3b2e9fdc2 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (121 of 121 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/zh_Hans/
2025-03-11 10:21:44 -03:00
eana
b957f3500b Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (121 of 121 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/zh_Hans/
2025-03-11 10:21:44 -03:00
eana
51bf3416bf Translated using Weblate (Chinese (Simplified))
Currently translated at 97.5% (118 of 121 strings)

Translation: Moshidon/values
Translate-URL: https://translate.codeberg.org/projects/moshidon/values/zh_Hans/
2025-03-11 10:21:44 -03:00
LucasGGamerM
8bdbde0ea6
Merge pull request #521 from FineFindus/feat/block-domain
Feat/block domain
2025-03-11 10:17:51 -03:00
LucasGGamerM
c50aecdd05
Merge pull request #549 from FineFindus/feat/reblog-mention
feat(Compose): exclude own account from reblog mentions
2025-03-11 10:17:10 -03:00
LucasGGamerM
f4ffd4718e
Merge pull request #589 from p1gp1g/unifiedpush/push_settings
Unifiedpush/push settings
2025-03-11 08:54:31 -03:00
LucasGGamerM
6d83453f96 fix(display-settings): move enhanced text size option to correct place 2025-03-10 13:15:31 -03:00
LucasGGamerM
69dbf38e1e fix(compose): hide bottom char counter when not in use 2025-03-10 12:38:57 -03:00
LucasGGamerM
a03297313a feat(accessibility): add display setting to make app's text size bigger 2025-03-10 12:10:33 -03:00
LucasGGamerM
b52f1c156d fix(unofficial-quote-toots): ignore youtube links
Youtube links look a lot like fediverse links, so we added a special rule for it, just in case. This may mitigate the too many requests problems we are facing.
2025-03-09 19:38:18 -03:00
LucasGGamerM
28097554a7 fix(animated-avatars): restart app when this setting is changed
This setting needs the app to be reset for it to apply. This commits does that.
2025-03-07 16:45:49 -03:00
LucasGGamerM
5984783831
Merge pull request #608 from TRMSC/patch-1
Add reply_to_user string
2025-03-05 16:56:30 -03:00
TRMSC
5299cda1ad
Add reply_to_user string 2025-03-04 20:10:48 +01:00
LucasGGamerM
65c8906b2a
build(github-actions): update upload-artifact dependency on nightly-builds.yml 2025-03-01 18:47:09 -03:00
LucasGGamerM
86e7e7cdc6
Merge pull request #606 from blacklight/346-fix-akkoma-translations
[#346] Fix Akkoma translations.
2025-03-01 18:45:03 -03:00
Fabio Manganiello
fe7f9f14c3 [#346] Fix Akkoma translations.
Not sure if something has changed in the Akkoma API since the latest
version of `AkkomaTranslateStatus`, but it seems that the API expects
the target language to be _lowercase_ (not _uppercase_).

Libretranslate nginx traces from my instance with the current
implementation show a 400 with the current implementation:

```
1.2.3.4 - - [11/Feb/2025:11:40:34 +0100] "POST /translate HTTP/1.1" 400 32 "-" "Akkoma 3.13.2-0-g050bc74; https://myinstance.social <fabio@myinstance.social>"
```

And that's also mirrored on my Akkoma logs:

```
1.2.3.4 - - [11/Feb/2025:11:40:35 +0100] "GET /api/v1/statuses/Ar0PZaoyJwN2GD3UJs/translations/EN HTTP/2.0" 400 54 "-" "MoshidonAndroid/2.3.0+fork.108.moshinda"
```

A direct API call to the endpoint above indeed returns a 400:

```
{"error":"libre_translate: request failed (code 400)"}
```

But everything works when `en` is used instead of `EN`:

```
{"text":"<p>Help me! </p><p>**As a large organization you go to Mastodon because: **<br/>- You want to set a standard<br/>- Guarantee your free access to your posts<br/>- as an anti-reaction against big tech and its associated:<br/> - data collections<br/> - earning models<br/> - algorithms that spread her<br/>- ... </p><p>**You run your own server because: **<br/>- your owner wants to remain over your dates<br/>- you can arrange your own accounts for your employees<br/>- ...</p><p>What arguments would you have for switching to Mastodon and own server?</p>","detected_language":"nl"}
```
2025-02-11 11:43:37 +01:00
LucasGGamerM
1bbfc45bd0 fix(publish-button): update both button states
This is bullshit, I will fix this tomfoolery with the 2 buttons in the rewrite
2025-01-29 13:14:41 -03:00
LucasGGamerM
0b5588515e fix(pixelfed): allow publishing comments without images on pixelfed 2025-01-29 13:10:52 -03:00
LucasGGamerM
2cdc649b7d fix(pleroma-login): use longs for min and max poll expiration values 2025-01-26 15:22:23 -03:00
sim
4e1f7839b3 Allow configuring push notifications with UnifiedPush 2025-01-21 18:00:14 +01:00
sim
281e989749 Use server VAPID keys 2025-01-21 17:59:52 +01:00
sim
7cd756f6b0 Re-register UnifiedPush when application starts 2025-01-14 17:06:19 +01:00
sim
cc4558458c Add Helper for some UnifiedPush functions 2025-01-14 17:06:19 +01:00
sim
66824aadb9 Use standard webpush for UnifiedPush only 2025-01-14 16:13:31 +01:00
sim
00e90e5f21 Use standard webpush when available 2025-01-14 16:04:27 +01:00
sim
376653cb3f Update UnifiedPush lib 2025-01-14 16:00:54 +01:00
LucasGGamerM
082de410e0 build: disable vcsInfo for fdroid builds 2025-01-07 12:12:16 -03:00
LucasGGamerM
899f48b40c build: disable DependencyInfoBlock 2025-01-07 11:55:05 -03:00
LucasGGamerM
dae5989d64 docs: add changelog 2025-01-05 19:34:29 -03:00
LucasGGamerM
1d1c4f2666 build: bump version number 2025-01-05 19:33:11 -03:00
LucasGGamerM
0fecdf345a
Merge pull request #570
Upgrade build dependencies for the project
2025-01-04 15:15:24 -03:00
Jacoco
ed5c58b4ea
Fix wrong padding under reactions 2024-12-22 12:08:32 +01:00
Jacoco
cbab92ed87
Prevent double long press for reaction buttons 2024-12-21 17:34:28 +01:00
Aurimas
82bcfe3fa8
Update gradle.properties
Co-authored-by: Zongle Wang <wangzongler@gmail.com>
2024-11-17 18:46:51 -08:00
Aurimas
203c43343a
Update build.gradle
Co-authored-by: Zongle Wang <wangzongler@gmail.com>
2024-11-17 18:46:43 -08:00
Aurimas Liutikas
4c105acc30 Upgrade build dependencies for the project
- Upgrade to Gradle 8.11
- Upgrade to Android Gradle Plugin 8.7.2
- Remove deprecated android.defaults.buildfeatures.buildconfig=true
  gradle property, it is not needed as mastodon/build.gradle already
  sets android { buildFeatures { buildConfig true } }
- Move plugin repository definition to settings.gradle to match latest
  Gradle practices
- Move to using plugin {} mechanism to add Android Gradle Plugin to
  match the latest Gradle practices
- Remove root project clean task as this project does not produce any
  real artifacts, it seems to be leftover from original Android new
  project template
2024-11-15 17:21:37 -08:00
FineFindus
bd6f739842
feat(Compose): exclude own account from reblog mentions
Excludes the users account from being automatically included when
repplying to a status that has been bosted by the user.

Fixes https://github.com/LucasGGamerM/moshidon/issues/548
2024-09-23 18:44:40 +02:00
Jacocococo
e336f15cb0 Don't hide filter settings on Iceshrimp.NET 2024-09-14 21:28:42 +02:00
Jacocococo
a554059cce Change isAkkoma to be based on version code
Iceshrimp.NET now also implements some APIs using the pleroma field, so
only checking for that would create false positives for Iceshrimp.NET
2024-09-14 21:21:41 +02:00
LucasGGamerM
d81eb6ad0a
Merge pull request #538 from FineFindus/fix/hashtag-timeline-open-crash
fix(Timeline/Hashtag): check if hashtag is null
2024-09-09 09:03:54 -03:00
FineFindus
08542cd16f
fix(Timeline/Hashtag): check if hashtag is null
Fixes a crash when clicking on hashtags in profiles, since the hashtag
is for some reason null.
2024-09-09 12:03:10 +02:00
LucasGGamerM
f30e12f5c6
Merge pull request #526 from FineFindus/fix/empty-hashtag
feat(Error): disable clicking + crash fix
2024-09-02 09:39:41 -03:00
LucasGGamerM
3a14fb5912
Merge pull request #529 from FineFindus/fix/hashtag-timeline-follow-icon
fix(HashtagTimeline): update follow menu icon
2024-09-02 08:55:15 -03:00
FineFindus
cc64a1b6a2
fix(HashtagTimeline): update follow menu icon
Fixes an issue, where the menu follow icon was not correctly updated,
and would always show the follow state.
2024-08-31 17:49:04 +02:00
FineFindus
7fa079e362
fix(HtmlParser): check if hashtag has text
Fixes a crash, where the text of an hashtag was empty, leading to an oob
string access.
2024-08-31 10:44:53 +02:00
FineFindus
c2e6280a18
feat(ErrorStatusDisplayItem): disable clicking on error item
Disable clicking on the ErrorStatusDisplayItem, since there is no valid
content that can be displayed.
2024-08-31 10:42:09 +02:00
LucasGGamerM
01225b05f2
Merge pull request #515 from collingsr/master
Updated README formatting & content
2024-08-29 20:25:16 -03:00
Jacocococo
f016b87ea0 Fix indent 2024-08-28 16:32:30 +02:00
Jacocococo
9426a9bc59 Code comments clarifying features being hidden on some servers 2024-08-27 22:21:47 +02:00
Jacocococo
f146067cda Code comments to clear up isIceshrimp and isIceshrimpJs 2024-08-27 22:16:59 +02:00
Jacocococo
f28e06d2f5 Code comments about hiding news discovery on Iceshrimp 2024-08-27 22:16:00 +02:00
Jacocococo
87cbffcb06 Better code style for hiding language button 2024-08-27 22:04:14 +02:00
FineFindus
7a103046b4
feat(sheets): add domain block sheet 2024-08-26 13:12:56 +02:00
FineFindus
64c53be990
fix(MuteAccountSheet): set selected mute time 2024-08-26 13:10:30 +02:00
FineFindus
e419c504e4
feat: use mute row
Partially 6c519b3cb9 to use the full row
again, but keep the selection in a dialog. This improves the UI, as the
secondary button is confusing, and feels out-of-place.
2024-08-26 13:10:30 +02:00
FineFindus
1f06e4e8f3
feat(Timeline/Hashtag): show snackbar when unmuting
Gives the user feedback in the form of a snackbar that the unmuting was
sucessful. This is already done for unmuting accounts.
2024-08-25 13:43:26 +02:00
FineFindus
b0f8cbb2e3
feat(Timeline/Hashtag): show confirmation sheet when muting
Shows a MuteHashtagConfirmationSheet when muting a hashtag, similar to
the MuteAccountConfirmationSheet. This also adds the option for the mute
to expire.
2024-08-25 13:35:32 +02:00
Ruth Collings
89f27984b7
Update FAQ.md
Co-authored-by: FineFindus <63370021+FineFindus@users.noreply.github.com>
2024-08-22 14:22:30 -04:00
Jacocococo
e3df5ce0a8 Properly set emoji reactions padding 2024-08-22 14:01:35 +02:00
Jacocococo
fcf7665ab5 Merge branch 'master' of https://github.com/LucasGGamerM/moshidon into moshidon-iceshrimp-improvements 2024-08-22 13:32:48 +02:00
Jacocococo
407844378f Revert some changes specifically for Iceshrimp.NET 2024-08-21 22:56:33 +02:00
Ruth Collings
61b933655c clean up
removing stuff I dropped in there earlier
2024-08-21 14:22:13 -04:00
Ruth Collings
d47e1939d0 formatting 2024-08-21 14:18:42 -04:00
Jacocococo
c834199ee4 Hide filter settings on Iceshrimp 2024-08-19 22:42:13 +02:00
Ruth Collings
00b934dc69 spacing and lines
it was bothering me
2024-08-19 16:34:22 -04:00
Ruth Collings
c86ff1cce4 update
Reformatted header buttons and donate section, rewrote blurb, shortened up features descriptions and moved some to FAQ which I will tidy up later
2024-08-19 16:30:50 -04:00
Jacocococo
893b88350a Allow all content types on Iceshrimp
It's disabled anyways for new users, and allowing all lowers the chance
of crashes from a previously selected option being missing
2024-08-19 22:26:11 +02:00
Jacocococo
96b992025b Disable content type setting on Iceshrimp
We can be sure it doesn't support anything other than MFM
2024-08-19 22:24:06 +02:00
Jacocococo
cd7c546bed Only allow MFM content type on Iceshrimp 2024-08-19 21:59:42 +02:00
Jacocococo
6a46815809 Prevent more reactions if max has been reached
This is specifically for tapping existing reactions on a post if the
user has already reached the instance max
2024-08-19 21:11:57 +02:00
Jacocococo
5d411e842e Place new reaction where server specified it 2024-08-19 17:26:33 +02:00
Jacocococo
309d27242d Fix crash when liking statuses from non-Iceshrimp instances 2024-08-19 17:16:39 +02:00
Jacocococo
5f78cd4a8e Fix unicode reaction not showing up if no reactions were previsouly present 2024-08-19 17:13:16 +02:00
Jacocococo
1ad2257bb1 Add favorite reaction in right place + fix issues 2024-08-19 17:04:47 +02:00
LucasGGamerM
5427b21365
Merge pull request #508 from FineFindus/feat/duration
feat(MuteSheet): revert to row
2024-08-18 17:35:05 -03:00
Ruth Collings
d875edbc23 Update README.md 2024-08-15 14:57:57 -04:00
LucasGGamerM
4aecb17497
Merge pull request #507 from FineFindus/fix/note-save-crash
fix(Profile) note save crash
2024-08-14 15:56:20 -03:00
LucasGGamerM
806db1d09f
Merge pull request #496 from FineFindus/fix/share-theme
fix(ExternalShareActivity): set theme before opening compose
2024-08-14 15:55:16 -03:00
FineFindus
49cf100d37
fix(MuteAccountSheet): set selected mute time 2024-08-14 19:12:35 +02:00
FineFindus
259a0ae140
feat: use mute row
Partially 6c519b3cb9 to use the full row
again, but keep the selection in a dialog. This improves the UI, as the
secondary button is confusing, and feels out-of-place.
2024-08-14 18:50:58 +02:00
FineFindus
420233da14
fix(Profile): remove note text before hiding NoteTextField
Fixes an issue, where if the NoteTextField was focussed and the note was
hidden, the note would saved and reshown once the NoteTextField was
hidden.
2024-08-12 07:16:15 +02:00
FineFindus
78ec24ff0c
feat(Profile): only show note saved if note has not been hidden
The note text field being hidden is already enough comfirmation that the
note has been hidden.
2024-08-12 07:15:22 +02:00
FineFindus
a6f1d981db
fix(Profile): use global context for note toast
Uses the global context for displaying the note saved toast. When using
the local context, it was somehow, sometimes null, leading to crashes.
2024-08-12 07:09:17 +02:00
LucasGGamerM
b07789b346
Merge pull request #505 from FineFindus/fix/scheduled-status-quote-crash
fix(StatusDisplayItem): check if account is null before adding quote
2024-08-11 19:32:08 -03:00
FineFindus
42c55d5eee
fix(StatusDisplayItem): check if account is null before adding quote
This should fix crashes in the ScheduledStatusListFragment,
as ScheduledStatus do not contain an account.
2024-08-11 23:48:31 +02:00
LucasGGamerM
13545fd5ef
Merge pull request #503 from FineFindus/feat/profile-note-save-feedback
feat(Profile): display Toast when saving note
2024-08-11 09:38:45 -03:00
FineFindus
134513babd
feat(ProfileFragment): display toast when saving note
It can be quite unclear if the note has been saved. This adds a toast,
to indicate that the profile note has been saved.
2024-08-11 11:48:51 +02:00
FineFindus
91cb616164
refactor(ProfileFragment): remove duplicated InputType setting
The NoteEdit InputType is already set in the UI file.
2024-08-11 11:47:34 +02:00
Jacocococo
3266a490be Add reaction when favoriting post on Iceshrimp 2024-08-05 18:02:27 +02:00
FineFindus
f3d600282e
fix(ExternalShareActivity): set theme before opening compose
Fixes https://github.com/sk22/megalodon/issues/926.
2024-08-05 14:28:20 +02:00
Jacocococo
86b6adf228 Move unauthenticatedApiController
The constructor of AccountSessionManager may need this object which
could lead to a situation where it was being used before it had been
created.
Making it static and moving it to MastodonAPIRequest, the only place it
was being used anyways, seems to fix the issue.
2024-03-29 14:38:06 +01:00
Jacocococo
2856e99569 Update favorite when reacting on Iceshrimp 2024-03-17 00:05:47 +01:00
Jacocococo
684164903a Disable add reaction button upon reaching limit when using that button 2024-03-16 23:08:55 +01:00
Jacocococo
2dfb79c828 Disable remote emoji reaction buttons on Iceshrimp 2024-03-16 14:25:30 +01:00
Jacocococo
86f54f5a02 Respect instance max reaction count 2024-03-15 23:00:25 +01:00
Jacocococo
3593d8d80f Announcements fixes on Iceshrimp
- Hide emoji reactions
- Correctly set editedAt
2024-02-16 00:10:20 +01:00
Jacocococo
454660fe89 Hide profile notify button on Iceshrimp 2024-02-15 23:25:09 +01:00
Jacocococo
325eda58cb Fix Iceshrimp quote notification 2024-02-15 22:58:40 +01:00
Jacocococo
0e96e23cfa Hide language selector on Iceshrimp 2024-02-15 00:06:08 +01:00
Jacocococo
2892a31c72 Hide news discovery on Iceshrimp 2024-02-14 23:35:13 +01:00
Jacocococo
c8bb0de7d4 Don't load instance info in background
This information is very useful and it's loaded very quickly anyways
2024-02-14 22:35:32 +01:00
Jacocococo
53e8c0d2f4 Quoting 2024-02-14 19:22:50 +01:00
210 changed files with 3185 additions and 543 deletions

View file

@ -0,0 +1,16 @@
name: Mirror to Codeberg
on: [push]
jobs:
sync-git:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: yesolutions/mirror-action@master
with:
REMOTE: 'https://codeberg.org/LucasGGamerM/moshidon.git'
GIT_USERNAME: LucasGGamerM
GIT_PASSWORD: ${{ secrets.CODEBERG_GIT_PASSWORD }}

View file

@ -65,7 +65,7 @@ jobs:
CURRENT_DATE: ${{ steps.date.outputs.date }}
- name: Upload a Build Artifact
uses: actions/upload-artifact@v3.1.2
uses: actions/upload-artifact@v4
with:
name: moshidon-nightly.apk
path: ./mastodon/build/outputs/apk/nightly/moshidon-nightly.apk

54
FAQ.md
View file

@ -7,3 +7,57 @@ A: There are many, but the most outstanding differences are: the ability to have
Q: Will there ever be a version of Moshidon for iOS?
A: No. As android and iOS apps do not share code, it is incredibly hard to port.
## Detailed changes
### Features
* [Adding the ability to view other server's local timelines](https://github.com/LucasGGamerM/moshidon/tree/feature/local-timelines)
* [Adding the ability to load followers and following from remote instance](https://github.com/LucasGGamerM/moshidon/tree/feature/remote-followers)
* [Adding the ability to have filtered posts show with a warning](https://github.com/LucasGGamerM/moshidon/tree/feature/filters_again)
* [Add “Unlisted” as a post visibility option](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/enable-unlisted)
([Pull request](https://github.com/mastodon/mastodon-android/pull/103))
* Adding a useful private profile note box
* Auto hiding the compose button on scroll
* Adding the ability to remind yourself to add alt text to images
* An indicator for if an image has alt text or not
* Adding the ability to have drafts
* Also adding the ability to view announcements from your instance
* Adding the ability to post for local timeline only (Only on instances that support it!)
* [Add image description button and viewer](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/display-alt-text) ([Pull request](https://github.com/mastodon/mastodon-android/pull/129))
* [Implement pinning posts and displaying pinned posts](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/pin-posts) ([Pull request](https://github.com/mastodon/mastodon-android/pull/140))
* [Implement deleting and re-drafting](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/delete-redraft) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/21))
* [Implement a bookmark button and list](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/bookmarks) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/22))
* [Add “Check for update” button in addition to integrated update checker](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/check-for-update-button)
* [Add “Mark media as sensitive” option](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/mark-media-as-sensitive)
* [Add settings to hide replies and reposts from the timeline](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/filter-home-timeline) ([Pull request](https://github.com/mastodon/mastodon-android/pull/317))
* [Follow and unfollow hashtags](https://github.com/sk22/megalodon/commit/7d38f031f197aa6cefaf53e39d929538689c1e4e) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/233))
* [Notification bell for posts](https://github.com/sk22/megalodon/commit/b166ca705eb9169025ef32bbe6315b42491b57ea) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/81))
* [Viewing lists and adding/removing users from lists](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:list-timeline-views) based on [@obstsalatschuessel](https://github.com/obstsalatschuessel)'s [Pull request](https://github.com/mastodon/mastodon-android/pull/286)
* [List favorited posts](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/favs-list)
* [Accept/reject follow requests](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/follow-requests)
* [Display content warning title above text](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/cw-above-text)
* [Add notifications tab for posts](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/posts-notifications-tab)
* [Show visibility of original post when replying](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/display-reply-visibility)
* [Clickable reply/boost line above posts](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:clickable-boost-reply-line)
* [Clickable reply line while replying to open original post](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/clickable-reply-line-compose)
### Behavior
* Ask for confirmation before reblogging
* Adding a bottom option for the publish button, allowing for easier use on larger screens!
* [Make back button return to the home tab before exiting the app](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/back-returns-home) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/118))
* [Always preserve content warnings when replying](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/always-preserve-cw) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/113))
* [Display full image when adding image description](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/compose-image-description-full-image) ([Pull request](https://github.com/mastodon/mastodon-android/pull/182))
* [Set spoiler height independently to content height](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:spoiler-height-independent) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/166))
* [Option to hide interaction numbers](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:settings/hide-interaction-numbers)
* [Option to always reveal content warnings](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/cw-above-text)
* [Option to disable scrolling title bars](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:settings/disable-marquee)
### Visual
* [Custom extended footer redesign](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:compact-extended-footer)
* [Improvements to the true black mode](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:true-black-improvements)
* [Profile header tweaks](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:ui/profile-header-tweaks)

215
README.md
View file

@ -1,185 +1,91 @@
![MoshidonLogo](mastodon/src/main/res/mipmap-xhdpi/ic_launcher_round.png)
# ![MoshidonLogo](mastodon/src/main/res/mipmap-xhdpi/ic_launcher_round.png) Moshidon, the material you mastodon client!
# Moshidon, the material you mastodon client!
> A fork of [megalodon](https://github.com/sk22/megalodon) which is a fork of [official Mastodon Android app](https://github.com/mastodon/mastodon-android) adding important features that are missing in the official app and possibly wont ever be implemented, such as the federated timeline, unlisted posting, bookmarks and an image description viewer.
> A fast, highly customizable, up-to-date fork of [megalodon](https://github.com/sk22/megalodon) adding important features such as a fully federated timeline, unlisted posting, drafts, scheduled posts, bookmarks, and alt text warnings.
[![Download latest release](https://img.shields.io/badge/dynamic/json?color=282C37&label=Download%20APK&query=%24.tag_name&url=https%3A%2F%2Fapi.github.com%2Frepos%2FLucasGGamerM%2Fmoshidon%2Freleases%2Flatest&style=for-the-badge)](https://github.com/LucasGGamerM/moshidon/releases/latest/download/moshidon.apk)
## Download Now
[![Download nightly release](https://img.shields.io/badge/dynamic/json?color=282C37&label=Download%20Nightly%20APK&query=%24.tag_name&url=https%3A%2F%2Fapi.github.com%2Frepos%2FLucasGGamerM%2Fmoshidon%2Freleases%2Flatest&style=for-the-badge)](https://github.com/LucasGGamerM/moshidon-nightly/releases/latest/download/moshidon-nightly.apk)
<a href="https://play.google.com/store/apps/details?id=org.joinmastodon.android.moshinda"><img height="35" alt="Get it on Google Play" src="img/google-play-badge.png"></a> <a href="https://f-droid.org/pt_BR/packages/org.joinmastodon.android.moshinda"><img height="35" alt="Get it on F-Droid" src="img/f-droid-badge.png"></a> <a href="https://apt.izzysoft.de/fdroid/index/apk/org.joinmastodon.android.moshinda"><img height="35" alt="Get it on IzzyOnDroid" src="img/izzy-badge.png"></a>
[![GitHub Release Download](https://img.shields.io/badge/dynamic/json?color=282C37&label=Download%20APK&query=%24.tag_name&url=https%3A%2F%2Fapi.github.com%2Frepos%2FLucasGGamerM%2Fmoshidon%2Freleases%2Flatest&style=for-the-badge)](https://github.com/LucasGGamerM/moshidon/releases/latest/download/moshidon.apk) [![Translation status](https://translate.codeberg.org/widgets/moshidon/-/svg-badge.svg)](https://translate.codeberg.org/engage/moshidon/) [![GitHub Nightly Download](https://img.shields.io/badge/dynamic/json?color=282C37&label=Download%20Nightly%20APK&query=%24.tag_name&url=https%3A%2F%2Fapi.github.com%2Frepos%2FLucasGGamerM%2Fmoshidon%2Freleases%2Flatest&style=for-the-badge)](https://github.com/LucasGGamerM/moshidon-nightly/releases/latest/download/moshidon-nightly.apk) [![GitHub Nightly Build Download](https://github.com/LucasGGamerM/moshidon/actions/workflows/nightly-builds.yml/badge.svg)](https://github.com/LucasGGamerM/moshidon/actions/workflows/nightly-builds.yml)
[![Translation status](https://translate.codeberg.org/widgets/moshidon/-/svg-badge.svg)](https://translate.codeberg.org/engage/moshidon/)
&nbsp;
[![Nightly build](https://github.com/LucasGGamerM/moshidon/actions/workflows/nightly-builds.yml/badge.svg)](https://github.com/LucasGGamerM/moshidon/actions/workflows/nightly-builds.yml)
## Donate
<a href="https://play.google.com/store/apps/details?id=org.joinmastodon.android.moshinda"><img height="50" alt="Get it on Google Play" src="img/google-play-badge.png"></a>
&nbsp;
<a href="https://f-droid.org/pt_BR/packages/org.joinmastodon.android.moshinda"><img height="50" alt="Get it on F-Droid" src="img/f-droid-badge.png"></a>
&nbsp;
<a href="https://apt.izzysoft.de/fdroid/index/apk/org.joinmastodon.android.moshinda"><img height="50" alt="Get it on IzzyOnDroid" src="img/izzy-badge.png"></a>
<a href="https://github.com/sponsors/LucasGGamerM">Github Sponsors</a> | <a href="https://liberapay.com/LucasGGamerM/donate">Liberapay</a> | Monero Wallet Key: `4886mdarcyB6Yf8Qc6vDJBK1fz6ibHFLZUmHb4GZZz9yLGNhcG3XC64e5UZ8dVQYTLZb82W6P9WhteowW4STJEec97Gf22j`
## Help out the project by donating at: https://github.com/sponsors/LucasGGamerM!
### We also support LiberaPay at: https://liberapay.com/LucasGGamerM/donate
## Key Features
### You can also donate some Monero through this wallet address as well:
4886mdarcyB6Yf8Qc6vDJBK1fz6ibHFLZUmHb4GZZz9yLGNhcG3XC64e5UZ8dVQYTLZb82W6P9WhteowW4STJEec97Gf22j
[ screenshot of full timeline in default colour scheme ]
[ screenshot of full timeline in an alt colour scheme ]
[ screenshot of profile page ]
[ screenshot of compose post window ]
---
### Flexible Timelines
## Key features
[ Home dropdown menu ]
### **The ability to add other server's local timeline to your timelines**
Under the Home menu by default you can see your active account's timeline, your server's local timeline, and your server's federated timeline. You can also pin hashtags, lists, other servers, or make a custom view of just your posts, your bookmarks, or your favourites for quick access. Then sort these timelines to prioritize the ones you visit most often.
It can be accessed in the "Edit timelines" menu, where you can add a new "Community" to see other server's local posts!
### Multiple Accounts & Crossposting
### **View remote profiles**
Sign in to multiple accounts in the same app and easily switch between them. Press and hold on the boost or fave button to boost or fave a post to a different account than the one you are currently browsing with.
You can now see all of a profile follows and followers, by directly loading them from the profile's home instance. In case of a failed lookup, the app will automatically fall back to the older method.
[ boost icon pop up select profile ]
### **Translate posts easily**
### Drafts & Scheduled Posts
Allows you to easily translate posts in another language with a translate button! Your instance must support translation, otherwise it will not work.
Write posts and save them, or schedule them to post later. Edit and delete your drafts.
### **Show posts filtered with a warning**
### Alt Text Tag & Reminder
Allows you to have filtered posts collapsed with a warning! As shown in the screenshots:
An unobtrusive ALT tag appears on images with alt text. Clicking on the icon makes the alt text appear. By default, Moshidon will show a warning to add alt text if your post has any attachments lacking alt text. This is for better accessibility, and it can be disabled in settings. You can also hide from your feed all posts that are lacking in alt text.
Before | After
:-------------------------:|:-------------------------:
![Screenshot_20230205-100200edited](https://user-images.githubusercontent.com/71328265/216820539-20802dc5-e433-4511-b2d9-291d810e4ef2.png) | ![Screenshot_20230205-100203edited](https://user-images.githubusercontent.com/71328265/216820544-231b2966-f38f-4ec6-b555-d39c62433839.png)
[ image with alt text icon higlighted ]
[ alt text expanded ]
### Themes & Customization
### **Color themes**
Moshidon is designed according to Material Design principles. Follow your device's light or dark mode settings or change colour palette - your system's default, purple, black & white, "pitch black" (battery saving) and more. Customize your experience by moving or renaming the publish button, show or hide sensitive media by default, reduce motion, collapse long posts, add haptic feedback, or making the fave button a heart &hearts; or a star &starf;.
Allows you to change theme within the app. Supports Material You, purple, pink, green, blue, red, orange, yellow and Nord!
### Not Just For Mastodon
### **Unlisted posting**
Supports features available on other types of fediverse servers such as admin announcements, showing pronouns in user names, post translation, emoji reactions, local-only posting, and markdown or html in posts.
**Allows you to post publicly without having your post show up in trends, hashtags or public timelines (i.e., in the tabs “Local”, “Community” and “Posts”).**
### Fully Federated Feed & Profiles
When posting with Unlisted visibility, your posts will still be publicly accessible in your profile. They will also be shown in peoples Home timelines, but only if they follow you or someone they follow reposted/replied to your post.
See all public posts from servers your server federates with and fetch profiles from a user's local server for accurate up to date information.
The Mastodon documentation has some more information about [Unlisted posting](https://docs.joinmastodon.org/user/posting/#unlisted) and [Public timelines](https://docs.joinmastodon.org/user/network/#timelines).
## And more...
- quote-posts - links to fediverse posts in other posts will be loaded inline like quote-tweets
- manage pinned posts and bookmarks
- manage lists, filters, and most privacy settings
- display pronouns in timelines, threads, and user listings
- get only specific types of notifications (no more finished polls!), limit who you get notifications from, or group all notifications into one.
- automatically add "re:" to beginning of replies with content warnings
- ask before boosting or deleting posts
- when replying to a boosted post automatically mention the person who boosted it
- overlay audio from posts, allowing your existing media to keep playing
- auto-reveal CWs that are the same as ones you've already opened, or always reveal content warnings and sensitive media
- hide media previews in timelines (save data)
- show post interaction counts in timeline
- allow custom emoji in display names
- enable scrolling text for long display names
- hide interaction buttons
- show post dividers
### **Federated timeline**
**This allows you to chronologically see all Public posts from people on all other Fediverse neighborhoods your home instance is connected to.**
## Installation & Releases
Despite being one of the main features of federated social media, the Federated timeline wasnt included in the official Mastodon app supposedly, because this conflicts with Googles safety requirements for apps on the Play Store.
Moshidon is available on GitHub, Google Play, F-Droid, and the IzzyOnDroid repo. All sources provide the same ` moshidon.apk ` stable release. Older releases are available on the [Releases](https://github.com/LucasGGamerM/moshidon/releases) page.
Thats one of the reasons why choosing a small, **well-moderated instance is important**. Instance admins and moderators should always make sure to ban abusive users and stop federating with instances who platform them. On well-moderated instances, the Federated timeline can be a welcoming place to meet new people!
### How to Install from GitHub
[Download the latest stable release from Github](https://github.com/LucasGGamerM/moshidon/releases/latest/download/moshidon.apk) and open it. You might have to accept installing APK files from your browser. Moshidon will automatically check for new updates available on GitHub and offer to download and install them within the app. You can also manually press “Check for updates” at the bottom of the settings page.
### **Image description viewer**
### Nightly Version
All ` moshidon-night.apk ` nightly builds can be downloaded on the [Nightly Releases](https://github.com/LucasGGamerM/moshidon-nightly/releases) page. This is an unstable version with an integrated updater for development and testing purposes. If you find any bugs with it, please file a bug report on our [Issues](https://github.com/LucasGGamerM/moshidon/issues) page.
**Allows you to quickly check whether an image or video has an alternative text attached to it.**
This is important to **ensure the content youre sharing is as accessible as possible** to people who cant see the images and rely on software to read back the provided content descriptions. Thankfully, its quite common for people on the Fediverse to provide such alt texts, and hopefully things stay this way!
### **Reminder to add alt text to attached media**
By default, Moshidon will show a warning to add alt text if your post has any attachments without any alt text. This is for better accessibility, and it can easily be bypassed and disabled in settings.
### **Pinning posts**
**This lets you can highlight important posts on your profile. A dedicated “Pinned” tab in peoples profiles shows all the posts they pinned.**
On the Fediverse, its quite common for people to pin posts they want others to read before following them. You can pin/unpin posts yourself by clicking the `⋯` button in the top right corner of your posts.
### **Bookmarks**
**They allow for quickly saving posts and viewing them through the Bookmarks button on the top right of your profile.**
To bookmark a post, press the button between the Favorite and Share buttons on the bottom of the post. Bookmarks are saved privately, so the post authors wont know you saved their post the list of bookmarked posts is only visible to you.
## Installation
**Press the download button above to download the APK. Open the downloaded file on your Android device to install it. Moshidon will automatically notify you about new updates inside the app.**
To install this app on your Android device, download the [latest release from GitHub](https://github.com/LucasGGamerM/moshidon/releases/latest/download/moshidon.apk) and open it. You might have to accept installing APK files from your browser when trying to install it. You can also take a look at all releases on the [Releases](https://github.com/LucasGGamerM/moshidon/releases) page.
Moshidon makes use of [Mastodon for Android](https://github.com/mastodon/mastodon-android)s automatic update checker. Moshidon will check for new updates available on GitHub and offer to download and install them. You can also manually press “Check for updates” at the bottom of the settings page!
Moshidon is also available in [IzzyOnDroid repo](https://apt.izzysoft.de/fdroid/index/apk/org.joinmastodon.android.moshinda), compatible with all F-Droid clients. The APK provided here is the same as the one included in the Releases.
## Release variants
### Stable variant
All stable version downloads can be found on the [Releases](https://github.com/LucasGGamerM/moshidon/releases) page.
**`moshidon.apk`**
Variant with an integrated updater. If you download Moshidon from here (and not from an app store), just download the regular `moshidon.apk`.
### Nightly variant
All nightly builds can be downloaded at [Nightly Releases](https://github.com/LucasGGamerM/moshidon-nightly/releases) page.
**`moshidon-nightly.apk`**
Unstable variant with an integrated updater. It's for development and testing purposes. If you find any bugs with it, please file a bug report at our [issues](https://github.com/LucasGGamerM/moshidon/issues) page.
---
## Detailed changes
### Features
* [Adding the ability to view other server's local timelines](https://github.com/LucasGGamerM/moshidon/tree/feature/local-timelines)
* [Adding the ability to load followers and following from remote instance](https://github.com/LucasGGamerM/moshidon/tree/feature/remote-followers)
* [Adding the ability to have filtered posts show with a warning](https://github.com/LucasGGamerM/moshidon/tree/feature/filters_again)
* [Add “Unlisted” as a post visibility option](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/enable-unlisted)
([Pull request](https://github.com/mastodon/mastodon-android/pull/103))
* Adding a useful private profile note box
* Auto hiding the compose button on scroll
* Adding the ability to remind yourself to add alt text to images
* An indicator for if an image has alt text or not
* Adding the ability to have drafts
* Also adding the ability to view announcements from your instance
* Adding the ability to post for local timeline only (Only on instances that support it!)
* [Add image description button and viewer](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/display-alt-text) ([Pull request](https://github.com/mastodon/mastodon-android/pull/129))
* [Implement pinning posts and displaying pinned posts](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/pin-posts) ([Pull request](https://github.com/mastodon/mastodon-android/pull/140))
* [Implement deleting and re-drafting](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/delete-redraft) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/21))
* [Implement a bookmark button and list](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/bookmarks) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/22))
* [Add “Check for update” button in addition to integrated update checker](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/check-for-update-button)
* [Add “Mark media as sensitive” option](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/mark-media-as-sensitive)
* [Add settings to hide replies and reposts from the timeline](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/filter-home-timeline) ([Pull request](https://github.com/mastodon/mastodon-android/pull/317))
* [Follow and unfollow hashtags](https://github.com/sk22/megalodon/commit/7d38f031f197aa6cefaf53e39d929538689c1e4e) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/233))
* [Notification bell for posts](https://github.com/sk22/megalodon/commit/b166ca705eb9169025ef32bbe6315b42491b57ea) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/81))
* [Viewing lists and adding/removing users from lists](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:list-timeline-views) based on [@obstsalatschuessel](https://github.com/obstsalatschuessel)'s [Pull request](https://github.com/mastodon/mastodon-android/pull/286)
* [List favorited posts](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/favs-list)
* [Accept/reject follow requests](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/follow-requests)
* [Display content warning title above text](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/cw-above-text)
* [Add notifications tab for posts](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/posts-notifications-tab)
* [Show visibility of original post when replying](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/display-reply-visibility)
* [Clickable reply/boost line above posts](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:clickable-boost-reply-line)
* [Clickable reply line while replying to open original post](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/clickable-reply-line-compose)
### Behavior
* Allow for confirmation before reblogging
* Adding a bottom option for the publish button, allowing for easier use on larger screens!
* [Make back button return to the home tab before exiting the app](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/back-returns-home) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/118))
* [Always preserve content warnings when replying](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/always-preserve-cw) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/113))
* [Display full image when adding image description](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/compose-image-description-full-image) ([Pull request](https://github.com/mastodon/mastodon-android/pull/182))
* [Set spoiler height independently to content height](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:spoiler-height-independent) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/166))
* [Option to hide interaction numbers](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:settings/hide-interaction-numbers)
* [Option to always reveal content warnings](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:feature/cw-above-text)
* [Option to disable scrolling title bars](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:settings/disable-marquee)
### Visual
* [Custom extended footer redesign](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:compact-extended-footer)
* [Improvements to the true black mode](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:true-black-improvements)
* [Profile header tweaks](https://github.com/mastodon/mastodon-android/compare/master...sk22:megalodon:ui/profile-header-tweaks)
## Building
## Building & Contributing
As this app is using Java 17 features, you need JDK 17 or newer to build it. Other than that, everything is pretty standard. You can either import the project into Android Studio and build it from there, or run the following command in the project directory:
@ -191,14 +97,13 @@ As this app is using Java 17 features, you need JDK 17 or newer to build it. Oth
This project is released under the [GPL-3 License](./LICENSE).
## Links
## Contact & Support
**<a rel="me" href="https://floss.social/@moshidon">@moshidon@floss.social</a>**
[Official Matrix Chatroom](https://matrix.to/#/#moshidon:floss.social)
[F.A.Q](FAQ.md)
[Official matrix chatroom:](https://matrix.to/#/#moshidon:floss.social) https://matrix.to/#/#moshidon:floss.social
[Moshidon Roadmap](https://github.com/users/LucasGGamerM/projects/1)
[Moshidon roadmap](https://github.com/users/LucasGGamerM/projects/1)
<a rel="me" href="https://floss.social/@moshidon">@moshidon<wbr>@floss.social</a>
---

View file

@ -1,23 +1,3 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
mavenCentral()
maven {
url "https://www.jitpack.io"
content {
includeModule 'com.github.UnifiedPush', 'android-connector'
}
}
mavenLocal()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
task clean(type: Delete) {
delete rootProject.buildDir
plugins {
id("com.android.application") version "8.7.2" apply false
}

View file

@ -17,7 +17,5 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=false
android.defaults.buildfeatures.buildconfig=true
android.nonTransitiveRClass=true
android.nonFinalResIds=false
org.gradle.configuration-cache=true

View file

@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=e111cb9948407e26351227dabce49822fb88c37ee72f1d1582a69c68af2e702f
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
distributionSha256Sum=57dafb5c2622c6cc08b993c85b7c06956a2f53536432a30ead46166dbca0f1e9
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View file

@ -16,12 +16,19 @@ android {
applicationId "org.joinmastodon.android.moshinda"
minSdk 23
targetSdk 34
versionCode 107
versionName "2.3.0+fork.107.moshinda"
versionCode 108
versionName "2.3.0+fork.108.moshinda.luke"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
resourceConfigurations += ['ar-rSA', 'ar-rDZ', 'be-rBY', 'bn-rBD', 'bs-rBA', 'ca-rES', 'cs-rCZ', 'da-rDK', 'de-rDE', 'el-rGR', 'es-rES', 'eu-rES', 'fa-rIR', 'fi-rFI', 'fil-rPH', 'fr-rFR', 'ga-rIE', 'gd-rGB', 'gl-rES', 'hi-rIN', 'hr-rHR', 'hu-rHU', 'hy-rAM', 'ig-rNG', 'in-rID', 'is-rIS', 'it-rIT', 'iw-rIL', 'ja-rJP', 'kab', 'ko-rKR', 'my-rMM', 'nl-rNL', 'no-rNO', 'oc-rFR', 'pl-rPL', 'pt-rBR', 'pt-rPT', 'ro-rRO', 'ru-rRU', 'si-rLK', 'sl-rSI', 'sv-rSE', 'th-rTH', 'tr-rTR', 'uk-rUA', 'ur-rIN', 'vi-rVN', 'zh-rCN', 'zh-rTW']
}
dependenciesInfo {
// Disables dependency metadata when building APKs.
includeInApk = false
// Disables dependency metadata when building Android App Bundles.
includeInBundle = false
}
signingConfigs {
nightly{
storeFile = file("keystore/nightly_keystore.jks")
@ -108,6 +115,7 @@ android {
}
fdroidRelease {
initWith release
vcsInfo.include false
// The F-droid build system doesn't like this at all for some reason.
// versionNameSuffix '-fdroid'
// signingConfig signingConfigs.release
@ -156,7 +164,7 @@ dependencies {
implementation 'com.github.bottom-software-foundation:bottom-java:2.1.0'
annotationProcessor 'org.parceler:parceler:1.1.12'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'
implementation 'com.github.UnifiedPush:android-connector:2.1.1'
implementation 'org.unifiedpush.android:connector:3.0.7'
androidTestImplementation 'androidx.test:core:1.5.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'

View file

@ -20,6 +20,8 @@
# hide the original source file name.
#-renamesourcefileattribute SourceFile
-dontwarn android.app.BroadcastOptions
# Keep all model classes as they're used with gson and their names are shown in errors
-keep public class org.joinmastodon.android.model.**{
<fields>;

View file

@ -86,6 +86,8 @@ public class ExternalShareActivity extends FragmentStackActivity{
}
private void openComposeFragment(String accountID){
AccountSession session=AccountSessionManager.get(accountID);
UiUtils.setUserPreferredTheme(this, session);
getWindow().setBackgroundDrawable(null);
Intent intent=getIntent();

View file

@ -81,6 +81,7 @@ public class GlobalUserPreferences{
public static boolean showPostsWithoutAlt;
public static boolean showMediaPreview;
public static boolean removeTrackingParams;
public static boolean enhanceTextSize;
public static SharedPreferences getPrefs(){
return MastodonApp.context.getSharedPreferences("global", Context.MODE_PRIVATE);
@ -162,10 +163,10 @@ public class GlobalUserPreferences{
showPostsWithoutAlt=prefs.getBoolean("showPostsWithoutAlt", true);
showMediaPreview=prefs.getBoolean("showMediaPreview", true);
removeTrackingParams=prefs.getBoolean("removeTrackingParams", true);
enhanceTextSize=prefs.getBoolean("enhanceTextSize", false);
theme=ThemePreference.values()[prefs.getInt("theme", 0)];
if (prefs.contains("prefixRepliesWithRe")) {
prefixReplies = prefs.getBoolean("prefixRepliesWithRe", false)
? PrefixRepliesMode.TO_OTHERS : PrefixRepliesMode.NEVER;
@ -237,6 +238,7 @@ public class GlobalUserPreferences{
.putBoolean("showPostsWithoutAlt", showPostsWithoutAlt)
.putBoolean("showMediaPreview", showMediaPreview)
.putBoolean("removeTrackingParams", removeTrackingParams)
.putBoolean("enhanceTextSize", enhanceTextSize)
.apply();
}

View file

@ -7,8 +7,10 @@ import android.Manifest;
import android.app.Activity;
import android.app.Fragment;
import android.app.assist.AssistContent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.Uri;
@ -16,7 +18,9 @@ import android.os.BadParcelableException;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.Toast;
@ -338,4 +342,20 @@ public class MainActivity extends FragmentStackActivity implements ProvidesAssis
}
}
}
@Override
protected void attachBaseContext(Context base) {
if (!GlobalUserPreferences.enhanceTextSize) {
super.attachBaseContext(base);
return;
}
final Configuration override = new Configuration(base.getResources().getConfiguration());
// This is the font multiplier, which should be multiplied by, because the system settings also play a role here
override.fontScale *= 1.15f;
final Context newBase = base.createConfigurationContext(override);
super.attachBaseContext(newBase);
}
}

View file

@ -6,6 +6,7 @@ import android.content.Context;
import android.webkit.WebView;
import org.joinmastodon.android.api.PushSubscriptionManager;
import org.joinmastodon.android.utils.UnifiedPushHelper;
import me.grishka.appkit.imageloader.ImageCache;
import me.grishka.appkit.utils.NetworkUtils;
@ -27,7 +28,11 @@ public class MastodonApp extends Application{
ImageCache.setParams(params);
NetworkUtils.setUserAgent("MoshidonAndroid/"+BuildConfig.VERSION_NAME);
PushSubscriptionManager.tryRegisterFCM();
if (UnifiedPushHelper.isUnifiedPushEnabled(this)){
UnifiedPushHelper.registerAllAccounts(this);
} else {
PushSubscriptionManager.tryRegisterFCM();
}
GlobalUserPreferences.load();
if(BuildConfig.DEBUG){
WebView.setWebContentsDebuggingEnabled(true);

View file

@ -163,7 +163,7 @@ public class PushNotificationReceiver extends BroadcastReceiver{
PushNotificationReceiver.this.notify(context, PushNotification.fromNotification(context, account, notification), account.getID(), notification);
}
private void notify(Context context, PushNotification pn, String accountID, org.joinmastodon.android.model.Notification notification){
void notify(Context context, PushNotification pn, String accountID, org.joinmastodon.android.model.Notification notification){
NotificationManager nm=context.getSystemService(NotificationManager.class);
AccountSession session=AccountSessionManager.get(accountID);
Account self=session.self;

View file

@ -5,14 +5,22 @@ import android.util.Log;
import org.jetbrains.annotations.NotNull;
import org.joinmastodon.android.api.MastodonAPIController;
import org.joinmastodon.android.api.requests.notifications.GetNotificationByID;
import org.joinmastodon.android.api.session.AccountSession;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.model.Notification;
import org.joinmastodon.android.model.PaginatedResponse;
import org.joinmastodon.android.model.PushNotification;
import org.unifiedpush.android.connector.FailedReason;
import org.unifiedpush.android.connector.MessagingReceiver;
import org.unifiedpush.android.connector.data.PublicKeySet;
import org.unifiedpush.android.connector.data.PushEndpoint;
import org.unifiedpush.android.connector.data.PushMessage;
import java.util.List;
import java.util.function.Function;
import kotlin.text.Charsets;
import me.grishka.appkit.api.Callback;
import me.grishka.appkit.api.ErrorResponse;
@ -24,16 +32,23 @@ public class UnifiedPushNotificationReceiver extends MessagingReceiver{
}
@Override
public void onNewEndpoint(@NotNull Context context, @NotNull String endpoint, @NotNull String instance) {
public void onNewEndpoint(@NotNull Context context, @NotNull PushEndpoint endpoint, @NotNull String instance) {
// Called when a new endpoint be used for sending push messages
Log.d(TAG, "onNewEndpoint: New Endpoint " + endpoint + " for "+ instance);
Log.d(TAG, "onNewEndpoint: New Endpoint " + endpoint.getUrl() + " for "+ instance);
AccountSession account = AccountSessionManager.getInstance().tryGetAccount(instance);
if (account != null)
account.getPushSubscriptionManager().registerAccountForPush(null, endpoint);
if (account != null) {
PublicKeySet ks = endpoint.getPubKeySet();
if (ks != null){
account.getPushSubscriptionManager().registerAccountForPush(account.pushSubscription, true, endpoint.getUrl(), ks.getPubKey(), ks.getAuth());
} else {
// ks should never be null on new endpoint
account.getPushSubscriptionManager().registerAccountForPush(account.pushSubscription, endpoint.getUrl());
}
}
}
@Override
public void onRegistrationFailed(@NotNull Context context, @NotNull String instance) {
public void onRegistrationFailed(@NotNull Context context, @NotNull FailedReason reason, @NotNull String instance) {
// called when the registration is not possible, eg. no network
Log.d(TAG, "onRegistrationFailed: " + instance);
//re-register for gcm
@ -53,26 +68,46 @@ public class UnifiedPushNotificationReceiver extends MessagingReceiver{
}
@Override
public void onMessage(@NotNull Context context, @NotNull byte[] message, @NotNull String instance) {
public void onMessage(@NotNull Context context, @NotNull PushMessage message, @NotNull String instance) {
Log.d(TAG, "New message for " + instance);
// Called when a new message is received. The message contains the full POST body of the push message
AccountSession account = AccountSessionManager.getInstance().tryGetAccount(instance);
if (account == null)
return;
//this is stupid
// Mastodon stores the info to decrypt the message in the HTTP headers, which are not accessible in UnifiedPush,
// thus it is not possible to decrypt them. SO we need to re-request them from the server and transform them later on
// The official uses fcm and moves the headers to extra data, see
// https://github.com/mastodon/webpush-fcm-relay/blob/cac95b28d5364b0204f629283141ac3fb749e0c5/webpush-fcm-relay.go#L116
// https://github.com/tuskyapp/Tusky/pull/2303#issue-1112080540
if (message.getDecrypted()) {
// If the mastodon server supports the standard webpush, we can directly use the content
Log.d(TAG, "Push message correctly decrypted");
PushNotification pn = MastodonAPIController.gson.fromJson(new String(message.getContent(), Charsets.UTF_8), PushNotification.class);
new GetNotificationByID(pn.notificationId)
.setCallback(new Callback<>(){
@Override
public void onSuccess(org.joinmastodon.android.model.Notification result){
MastodonAPIController.runInBackground(()->new PushNotificationReceiver().notify(context, pn, instance, result));
}
@Override
public void onError(ErrorResponse error){
MastodonAPIController.runInBackground(()-> new PushNotificationReceiver().notify(context, pn, instance, null));
}
})
.exec(instance);
} else {
// else, we have to sync with the server
Log.d(TAG, "Server doesn't support standard webpush, fetching one notification");
fetchOneNotification(context, account, (notif) -> () -> new PushNotificationReceiver().notifyUnifiedPush(context, account, notif));
}
}
private void fetchOneNotification(@NotNull Context context, @NotNull AccountSession account, @NotNull Function<Notification, Runnable> callback) {
account.getCacheController().getNotifications(null, 1, false, false, true, new Callback<>(){
@Override
public void onSuccess(PaginatedResponse<List<Notification>> result){
result.items
.stream()
.findFirst()
.ifPresent(value->MastodonAPIController.runInBackground(()->new PushNotificationReceiver().notifyUnifiedPush(context, account, value)));
.ifPresent(value->MastodonAPIController.runInBackground(callback.apply(value)));
}
@Override

View file

@ -226,7 +226,11 @@ public class MastodonAPIController{
}catch(JsonIOException|JsonSyntaxException x){
req.onError(response.code()+" "+response.message(), response.code(), x);
}catch(Exception x){
req.onError("Error parsing an API error", response.code(), x);
if (response.code() == 501){
req.onError("API route not implemented: " + response.request().url(), response.code(), x);
} else {
req.onError("Error parsing an API error", response.code(), x);
}
}
}
}catch(Exception x){

View file

@ -37,6 +37,8 @@ import okhttp3.Response;
public abstract class MastodonAPIRequest<T> extends APIRequest<T>{
private static final String TAG="MastodonAPIRequest";
private static MastodonAPIController unauthenticatedApiController=new MastodonAPIController(null);
private String domain;
private AccountSession account;
private String path;
@ -95,14 +97,14 @@ public abstract class MastodonAPIRequest<T> extends APIRequest<T>{
public MastodonAPIRequest<T> execNoAuth(String domain){
this.domain=domain;
AccountSessionManager.getInstance().getUnauthenticatedApiController().submitRequest(this);
unauthenticatedApiController.submitRequest(this);
return this;
}
public MastodonAPIRequest<T> exec(String domain, Token token){
this.domain=domain;
this.token=token;
AccountSessionManager.getInstance().getUnauthenticatedApiController().submitRequest(this);
unauthenticatedApiController.submitRequest(this);
return this;
}
@ -137,7 +139,7 @@ public abstract class MastodonAPIRequest<T> extends APIRequest<T>{
return this;
}
protected void setRequestBody(Object body){
public void setRequestBody(Object body){
requestBody=body;
}

View file

@ -166,12 +166,23 @@ public class PushSubscriptionManager{
//work-around for adding the randomAccountId
String newEndpoint = endpoint;
if (endpoint.startsWith("https://app.joinmastodon.org/relay-to/fcm/"))
newEndpoint += pushAccountID;
Boolean standard = true;
if (endpoint.startsWith("https://app.joinmastodon.org/relay-to/fcm/")){
newEndpoint+=pushAccountID;
standard = false;
}
new RegisterForPushNotifications(newEndpoint,
encodedPublicKey,
encodedAuthKey,
registerAccountForPush(subscription, standard, newEndpoint, encodedPublicKey, encodedAuthKey);
});
}
public void registerAccountForPush(PushSubscription subscription, Boolean standard, String endpoint, String p256dh, String auth){
MastodonAPIController.runInBackground(()->{
Log.d(TAG, "registerAccountForPush: started for "+accountID);
new RegisterForPushNotifications(endpoint,
standard,
p256dh,
auth,
subscription==null ? PushSubscription.Alerts.ofAll() : subscription.alerts,
subscription==null ? PushSubscription.Policy.ALL : subscription.policy)
.setCallback(new Callback<>(){

View file

@ -8,14 +8,23 @@ import org.joinmastodon.android.api.requests.statuses.SetStatusBookmarked;
import org.joinmastodon.android.api.requests.statuses.SetStatusFavorited;
import org.joinmastodon.android.api.requests.statuses.SetStatusMuted;
import org.joinmastodon.android.api.requests.statuses.SetStatusReblogged;
import org.joinmastodon.android.api.session.AccountSession;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.events.EmojiReactionsUpdatedEvent;
import org.joinmastodon.android.events.ReblogDeletedEvent;
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
import org.joinmastodon.android.events.StatusCreatedEvent;
import org.joinmastodon.android.events.StatusDeletedEvent;
import org.joinmastodon.android.model.Emoji;
import org.joinmastodon.android.model.EmojiCategory;
import org.joinmastodon.android.model.EmojiReaction;
import org.joinmastodon.android.model.Instance;
import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.model.StatusPrivacy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import me.grishka.appkit.api.Callback;
@ -42,6 +51,9 @@ public class StatusInteractionController{
if(!Looper.getMainLooper().isCurrentThread())
throw new IllegalStateException("Can only be called from main thread");
AccountSession session=AccountSessionManager.get(accountID);
Instance instance=session.getInstance().get();
SetStatusFavorited current=runningFavoriteRequests.remove(status.id);
if(current!=null){
current.cancel();
@ -54,6 +66,7 @@ public class StatusInteractionController{
result.favouritesCount = Math.max(0, status.favouritesCount + (favorited ? 1 : -1));
cb.accept(result);
if(updateCounters) E.post(new StatusCountersUpdatedEvent(result));
if(instance.isIceshrimpJs()) E.post(new EmojiReactionsUpdatedEvent(status.id, result.reactions, false, null));
}
@Override
@ -63,12 +76,58 @@ public class StatusInteractionController{
status.favourited=!favorited;
cb.accept(status);
if(updateCounters) E.post(new StatusCountersUpdatedEvent(status));
if(instance.isIceshrimpJs()) E.post(new EmojiReactionsUpdatedEvent(status.id, status.reactions, false, null));
}
})
.exec(accountID);
runningFavoriteRequests.put(status.id, req);
status.favourited=favorited;
if(updateCounters) E.post(new StatusCountersUpdatedEvent(status));
if(instance.configuration==null || instance.configuration.reactions==null)
return;
String defaultReactionEmojiRaw=instance.configuration.reactions.defaultReaction;
if(!instance.isIceshrimpJs() || defaultReactionEmojiRaw==null)
return;
boolean reactionIsCustom=defaultReactionEmojiRaw.startsWith(":");
String defaultReactionEmoji=reactionIsCustom ? defaultReactionEmojiRaw.substring(1, defaultReactionEmojiRaw.length()-1) : defaultReactionEmojiRaw;
ArrayList<EmojiReaction> reactions=new ArrayList<>(status.reactions.size());
for(EmojiReaction reaction:status.reactions){
reactions.add(reaction.copy());
}
Optional<EmojiReaction> existingReaction=reactions.stream().filter(r->r.me).findFirst();
Optional<EmojiReaction> existingDefaultReaction=reactions.stream().filter(r->r.name.equals(defaultReactionEmoji)).findFirst();
if(existingReaction.isPresent() && !favorited){
existingReaction.get().me=false;
existingReaction.get().count--;
existingReaction.get().pendingChange=true;
}else if(existingDefaultReaction.isPresent() && favorited){
existingDefaultReaction.get().count++;
existingDefaultReaction.get().me=true;
existingDefaultReaction.get().pendingChange=true;
}else if(favorited){
EmojiReaction reaction=null;
if(reactionIsCustom){
List<EmojiCategory> customEmojis=AccountSessionManager.getInstance().getCustomEmojis(session.domain);
for(EmojiCategory category:customEmojis){
for(Emoji emoji:category.emojis){
if(emoji.shortcode.equals(defaultReactionEmoji)){
reaction=EmojiReaction.of(emoji, session.self);
break;
}
}
}
if(reaction==null)
reaction=EmojiReaction.of(defaultReactionEmoji, session.self);
}else{
reaction=EmojiReaction.of(defaultReactionEmoji, session.self);
}
reaction.pendingChange=true;
reactions.add(reaction);
}
E.post(new EmojiReactionsUpdatedEvent(status.id, reactions, false, null));
}
public void setReblogged(Status status, boolean reblogged, StatusPrivacy visibility, Consumer<Status> cb){

View file

@ -0,0 +1,14 @@
package org.joinmastodon.android.api.requests.accounts;
import com.google.gson.reflect.TypeToken;
import org.joinmastodon.android.api.MastodonAPIRequest;
import org.joinmastodon.android.model.FollowList;
import java.util.List;
public class BiteAccount extends MastodonAPIRequest{
public BiteAccount(String id){
super(HttpMethod.POST, "/users/"+id+"/bite", BiteAccount.class);
}
}

View file

@ -4,10 +4,11 @@ import org.joinmastodon.android.api.MastodonAPIRequest;
import org.joinmastodon.android.model.PushSubscription;
public class RegisterForPushNotifications extends MastodonAPIRequest<PushSubscription>{
public RegisterForPushNotifications(String endpoint, String encryptionKey, String authKey, PushSubscription.Alerts alerts, PushSubscription.Policy policy){
public RegisterForPushNotifications(String endpoint, Boolean standard, String encryptionKey, String authKey, PushSubscription.Alerts alerts, PushSubscription.Policy policy){
super(HttpMethod.POST, "/push/subscription", PushSubscription.class);
Request r=new Request();
r.subscription.endpoint=endpoint;
r.subscription.standard = standard;
r.data.alerts=alerts;
r.policy=policy;
r.subscription.keys.p256dh=encryptionKey;
@ -27,6 +28,8 @@ public class RegisterForPushNotifications extends MastodonAPIRequest<PushSubscri
private static class Subscription{
public String endpoint;
// Use standard push notifications if available
public Boolean standard;
public Keys keys=new Keys();
}

View file

@ -5,7 +5,6 @@ import org.joinmastodon.android.model.AkkomaTranslation;
public class AkkomaTranslateStatus extends MastodonAPIRequest<AkkomaTranslation>{
public AkkomaTranslateStatus(String id, String lang){
super(HttpMethod.GET, "/statuses/"+id+"/translations/"+lang.toUpperCase(), AkkomaTranslation.class);
super(HttpMethod.GET, "/statuses/"+id+"/translations/"+lang.toLowerCase(), AkkomaTranslation.class);
}
}

View file

@ -0,0 +1,9 @@
package org.joinmastodon.android.api.requests.statuses;
import org.joinmastodon.android.api.MastodonAPIRequest;
public class BitePost extends MastodonAPIRequest{
public BitePost(String id){
super(HttpMethod.POST, "/statuses/"+id+"/bite", BitePost.class);
}
}

View file

@ -16,6 +16,7 @@ import org.joinmastodon.android.model.ContentType;
import org.joinmastodon.android.model.Emoji;
import org.joinmastodon.android.model.Emoji;
import org.joinmastodon.android.model.PushSubscription;
import org.joinmastodon.android.model.Instance;
import org.joinmastodon.android.model.TimelineDefinition;
import java.lang.reflect.Type;
@ -23,6 +24,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
public class AccountLocalPreferences{
private final SharedPreferences prefs;
@ -72,19 +74,20 @@ public class AccountLocalPreferences{
// preReplySheet=prefs.getBoolean("preReplySheet", false);
// MEGALODON
Optional<Instance> instance=session.getInstance();
showReplies=prefs.getBoolean("showReplies", true);
showBoosts=prefs.getBoolean("showBoosts", true);
recentLanguages=fromJson(prefs.getString("recentLanguages", null), recentLanguagesType, new ArrayList<>());
bottomEncoding=prefs.getBoolean("bottomEncoding", false);
defaultContentType=enumValue(ContentType.class, prefs.getString("defaultContentType", ContentType.PLAIN.name()));
contentTypesEnabled=prefs.getBoolean("contentTypesEnabled", true);
defaultContentType=enumValue(ContentType.class, prefs.getString("defaultContentType", instance.map(Instance::isIceshrimp).orElse(false) ? ContentType.MISSKEY_MARKDOWN.name() : ContentType.PLAIN.name()));
contentTypesEnabled=prefs.getBoolean("contentTypesEnabled", instance.map(i->!i.isIceshrimp()).orElse(false));
timelines=fromJson(prefs.getString("timelines", null), timelinesType, TimelineDefinition.getDefaultTimelines(session.getID()));
localOnlySupported=prefs.getBoolean("localOnlySupported", false);
glitchInstance=prefs.getBoolean("glitchInstance", false);
publishButtonText=prefs.getString("publishButtonText", null);
timelineReplyVisibility=prefs.getString("timelineReplyVisibility", null);
keepOnlyLatestNotification=prefs.getBoolean("keepOnlyLatestNotification", false);
emojiReactionsEnabled=prefs.getBoolean("emojiReactionsEnabled", session.getInstance().isPresent() && session.getInstance().get().isAkkoma());
emojiReactionsEnabled=prefs.getBoolean("emojiReactionsEnabled", instance.map(i->i.isAkkoma() || i.isIceshrimp()).orElse(false));
showEmojiReactions=ShowEmojiReactions.valueOf(prefs.getString("showEmojiReactions", ShowEmojiReactions.HIDE_EMPTY.name()));
color=prefs.contains("color") ? ColorPreference.valueOf(prefs.getString("color", null)) : null;
recentCustomEmoji=fromJson(prefs.getString("recentCustomEmoji", null), recentCustomEmojiType, new ArrayList<>());

View file

@ -12,6 +12,7 @@ import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Build;
import android.util.Log;
import android.widget.Toast;
import org.joinmastodon.android.BuildConfig;
import org.joinmastodon.android.E;
@ -34,6 +35,7 @@ import org.joinmastodon.android.model.EmojiCategory;
import org.joinmastodon.android.model.LegacyFilter;
import org.joinmastodon.android.model.Instance;
import org.joinmastodon.android.model.Token;
import org.joinmastodon.android.utils.UnifiedPushHelper;
import org.unifiedpush.android.connector.UnifiedPush;
import java.io.File;
@ -70,7 +72,6 @@ public class AccountSessionManager{
private HashMap<String, List<EmojiCategory>> customEmojis=new HashMap<>();
private HashMap<String, Long> instancesLastUpdated=new HashMap<>();
private HashMap<String, Instance> instances=new HashMap<>();
private MastodonAPIController unauthenticatedApiController=new MastodonAPIController(null);
private Instance authenticatingInstance;
private Application authenticatingApp;
private String lastActiveAccountID;
@ -109,7 +110,7 @@ public class AccountSessionManager{
Log.e(TAG, "Error loading accounts", x);
}
lastActiveAccountID=prefs.getString("lastActiveAccount", null);
MastodonAPIController.runInBackground(()->readInstanceInfo(domains));
readInstanceInfo(domains);
maybeUpdateShortcuts();
}
@ -126,13 +127,13 @@ public class AccountSessionManager{
wrapper.instance = instance;
MastodonAPIController.runInBackground(()->writeInstanceInfoFile(wrapper, instance.uri));
updateMoreInstanceInfo(instance, instance.uri);
if (!UnifiedPush.getDistributor(context).isEmpty()) {
UnifiedPush.registerApp(
updateMoreInstanceInfo(instance, AccountSessionManager.get(session.getID()).domain);
if (UnifiedPushHelper.isUnifiedPushEnabled(context)) {
UnifiedPush.register(
context,
session.getID(),
new ArrayList<>(),
context.getPackageName()
null,
session.app.vapidKey.replaceAll("=","")
);
} else if(PushSubscriptionManager.arePushNotificationsAvailable()){
session.getPushSubscriptionManager().registerAccountForPush(null);
@ -247,11 +248,6 @@ public class AccountSessionManager{
maybeUpdateShortcuts();
}
@NonNull
public MastodonAPIController getUnauthenticatedApiController(){
return unauthenticatedApiController;
}
public void authenticate(Activity activity, Instance instance){
authenticatingInstance=instance;
new CreateOAuthApp()
@ -395,7 +391,7 @@ public class AccountSessionManager{
public void onError(ErrorResponse errorResponse) {
updateInstanceEmojis(instance, domain);
}
}).execNoAuth(instance.uri);
}).execNoAuth(domain);
}
private void updateInstanceEmojis(Instance instance, String domain){

View file

@ -68,14 +68,14 @@ public class AnnouncementsFragment extends BaseStatusListFragment<Announcement>
instanceUser.url = "https://"+session.domain+"/about";
instanceUser.avatar = instanceUser.avatarStatic = instance.thumbnail;
instanceUser.emojis = List.of();
Status fakeStatus = a.toStatus();
Status fakeStatus = a.toStatus(isInstanceIceshrimp());
TextStatusDisplayItem textItem = new TextStatusDisplayItem(a.id, HtmlParser.parse(a.content, a.emojis, a.mentions, a.tags, accountID), this, fakeStatus, true);
textItem.textSelectable = true;
List<StatusDisplayItem> items=new ArrayList<>();
items.add(HeaderStatusDisplayItem.fromAnnouncement(a, fakeStatus, instanceUser, this, accountID, this::onMarkAsRead));
items.add(textItem);
if(!isInstanceAkkoma()) items.add(new EmojiReactionsStatusDisplayItem(a.id, this, fakeStatus, accountID, false, true));
if(!isInstanceAkkoma() && !isInstanceIceshrimp()) items.add(new EmojiReactionsStatusDisplayItem(a.id, this, fakeStatus, accountID, false, true));
return items;
}

View file

@ -838,6 +838,14 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
list.invalidateItemDecorations();
}
public void onFavoriteChanged(Status status, String itemID) {
FooterStatusDisplayItem.Holder footer=findHolderOfType(itemID, FooterStatusDisplayItem.Holder.class);
if(footer!=null){
footer.getItem().status=status;
footer.onFavoriteClick();
}
}
@Override
public String getAccountID(){
return accountID;

View file

@ -787,7 +787,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
String ownID=AccountSessionManager.getInstance().getAccount(accountID).self.id;
if(!status.account.id.equals(ownID))
mentions.add('@'+status.account.acct);
if(status.rebloggedBy != null && GlobalUserPreferences.mentionRebloggerAutomatically)
if(GlobalUserPreferences.mentionRebloggerAutomatically && status.rebloggedBy != null && !status.rebloggedBy.id.equals(ownID))
mentions.add('@'+status.rebloggedBy.acct);
for(Mention mention:status.mentions){
if(mention.id.equals(ownID))
@ -927,6 +927,9 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
}
return false;
});
if(instance.isIceshrimpJs())
languageButton.setVisibility(View.GONE); // hide language selector on Iceshrimp-JS because the feature is not supported
if (!GlobalUserPreferences.relocatePublishButton)
publishButton.post(()->publishButton.setMinimumWidth(publishButton.getWidth()));
@ -1052,12 +1055,12 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
public void updatePublishButtonState(){
uuid=null;
if(GlobalUserPreferences.relocatePublishButton && publishButtonRelocated != null){
publishButtonRelocated.setEnabled((!isInstancePixelfed() || !mediaViewController.isEmpty()) && (trimmedCharCount>0 || !mediaViewController.isEmpty()) && charCount<=charLimit && mediaViewController.getNonDoneAttachmentCount()==0 && (pollViewController.isEmpty() || pollViewController.getNonEmptyOptionsCount()>1));
publishButtonRelocated.setEnabled(((!isInstancePixelfed() || replyTo != null) || !mediaViewController.isEmpty()) && (trimmedCharCount>0 || !mediaViewController.isEmpty()) && charCount<=charLimit && mediaViewController.getNonDoneAttachmentCount()==0 && (pollViewController.isEmpty() || pollViewController.getNonEmptyOptionsCount()>1));
}
if(publishButton==null)
return;
publishButton.setEnabled((!isInstancePixelfed() || !mediaViewController.isEmpty()) && (trimmedCharCount>0 || !mediaViewController.isEmpty()) && charCount<=charLimit && mediaViewController.getNonDoneAttachmentCount()==0 && (pollViewController.isEmpty() || pollViewController.getNonEmptyOptionsCount()>1));
publishButton.setEnabled(((!isInstancePixelfed() || replyTo != null) || !mediaViewController.isEmpty()) && (trimmedCharCount>0 || !mediaViewController.isEmpty()) && charCount<=charLimit && mediaViewController.getNonDoneAttachmentCount()==0 && (pollViewController.isEmpty() || pollViewController.getNonEmptyOptionsCount()>1));
}
private void onCustomEmojiClick(Emoji emoji){

View file

@ -22,6 +22,14 @@ public interface HasAccountID {
return getInstance().map(Instance::isPixelfed).orElse(false);
}
default boolean isInstanceIceshrimp() {
return getInstance().map(Instance::isIceshrimp).orElse(false);
}
default boolean isInstanceIceshrimpJs() {
return getInstance().map(Instance::isIceshrimpJs).orElse(false);
}
default Optional<Instance> getInstance() {
return getSession().getInstance();
}

View file

@ -11,7 +11,6 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
@ -32,21 +31,21 @@ import org.joinmastodon.android.model.FilterAction;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.model.FilterContext;
import org.joinmastodon.android.model.FilterKeyword;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.model.FilterContext;
import org.joinmastodon.android.model.Hashtag;
import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.model.TimelineDefinition;
import org.joinmastodon.android.ui.Snackbar;
import org.joinmastodon.android.ui.sheets.MuteHashtagConfirmationSheet;
import org.joinmastodon.android.ui.text.SpacerSpan;
import org.joinmastodon.android.ui.utils.UiUtils;
import org.joinmastodon.android.ui.views.ProgressBarButton;
import org.parceler.Parcels;
import java.util.ArrayList;
import java.time.Duration;
import java.util.EnumSet;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.concurrent.atomic.AtomicReference;
import me.grishka.appkit.Nav;
import me.grishka.appkit.api.Callback;
@ -105,15 +104,40 @@ public class HashtagTimelineFragment extends PinnableStatusListFragment{
muteMenuItem.setIcon(newMute ? R.drawable.ic_fluent_speaker_2_24_regular : R.drawable.ic_fluent_speaker_off_24_regular);
}
private void showMuteDialog(boolean mute) {
UiUtils.showConfirmationAlert(getContext(),
mute ? R.string.mo_unmute_hashtag : R.string.mo_mute_hashtag,
mute ? R.string.mo_confirm_to_unmute_hashtag : R.string.mo_confirm_to_mute_hashtag,
mute ? R.string.do_unmute : R.string.do_mute,
mute ? R.drawable.ic_fluent_speaker_2_28_regular : R.drawable.ic_fluent_speaker_off_28_regular,
mute ? this::unmuteHashtag : this::muteHashtag
);
private void updateFollowState(boolean following) {
followMenuItem.setTitle(getString(following ? R.string.unfollow_user : R.string.follow_user, "#"+hashtagName));
followMenuItem.setIcon(following ? R.drawable.ic_fluent_person_delete_24_filled : R.drawable.ic_fluent_person_add_24_regular);
}
private void showMuteDialog(boolean currentlyMuted) {
if (currentlyMuted) {
unmuteHashtag();
return;
}
//pass a references, so they can be changed inside the confirmation sheet
AtomicReference<Duration> muteDuration=new AtomicReference<>(Duration.ZERO);
new MuteHashtagConfirmationSheet(getContext(), null, muteDuration, hashtag, (onSuccess, onError)->{
FilterKeyword hashtagFilter=new FilterKeyword();
hashtagFilter.wholeWord=true;
hashtagFilter.keyword="#"+hashtagName;
new CreateFilter("#"+hashtagName, EnumSet.of(FilterContext.HOME), FilterAction.HIDE, (int) muteDuration.get().getSeconds(), List.of(hashtagFilter)).setCallback(new Callback<>(){
@Override
public void onSuccess(Filter result){
filter=Optional.of(result);
updateMuteState(true);
onSuccess.run();
}
@Override
public void onError(ErrorResponse error){
error.showToast(getContext());
onError.run();
}
}).exec(accountID);
}).show();
}
private void unmuteHashtag() {
//safe to get, this only called if filter is present
new DeleteFilter(filter.get().id).setCallback(new Callback<>(){
@ -121,6 +145,9 @@ public class HashtagTimelineFragment extends PinnableStatusListFragment{
public void onSuccess(Void result){
filter=Optional.empty();
updateMuteState(false);
new Snackbar.Builder(getContext())
.setText(getContext().getString(R.string.unmuted_user_x, '#'+hashtagName))
.show();
}
@Override
@ -130,26 +157,6 @@ public class HashtagTimelineFragment extends PinnableStatusListFragment{
}).exec(accountID);
}
private void muteHashtag() {
FilterKeyword hashtagFilter=new FilterKeyword();
hashtagFilter.wholeWord=true;
hashtagFilter.keyword="#"+hashtagName;
new CreateFilter("#"+hashtagName, EnumSet.of(FilterContext.HOME), FilterAction.HIDE, 0 , List.of(hashtagFilter)).setCallback(new Callback<>(){
@Override
public void onSuccess(Filter result){
filter=Optional.of(result);
updateMuteState(true);
}
@Override
public void onError(ErrorResponse error){
error.showToast(getContext());
}
}).exec(accountID);
}
@Override
protected TimelineDefinition makeTimelineDefinition() {
return TimelineDefinition.ofHashtag(hashtagName);
@ -292,6 +299,7 @@ public class HashtagTimelineFragment extends PinnableStatusListFragment{
followMenuItem=optionsMenu.findItem(R.id.follow_hashtag);
pinMenuItem=optionsMenu.findItem(R.id.pin);
followMenuItem.setVisible(toolbarContentVisible);
updateFollowState(hashtag!=null && hashtag.following);
// pinMenuItem.setShowAsAction(toolbarContentVisible ? MenuItem.SHOW_AS_ACTION_NEVER : MenuItem.SHOW_AS_ACTION_ALWAYS);
super.updatePinButton(pinMenuItem);
@ -388,8 +396,7 @@ public class HashtagTimelineFragment extends PinnableStatusListFragment{
followButton.setTextVisible(true);
followProgress.setVisibility(View.GONE);
if(followMenuItem!=null){
followMenuItem.setTitle(getString(hashtag.following ? R.string.unfollow_user : R.string.follow_user, "#"+hashtagName));
followMenuItem.setIcon(hashtag.following ? R.drawable.ic_fluent_person_delete_24_filled : R.drawable.ic_fluent_person_add_24_regular);
updateFollowState(hashtag.following);
}
if(muteMenuItem!=null){
muteMenuItem.setTitle(getString(filter.isPresent() ? R.string.unmute_user : R.string.mute_user, "#" + hashtag));
@ -429,6 +436,7 @@ public class HashtagTimelineFragment extends PinnableStatusListFragment{
return;
hashtag=result;
updateHeader();
updateFollowState(result.following);
followRequestRunning=false;
}

View file

@ -24,6 +24,7 @@ import org.joinmastodon.android.events.EmojiReactionsUpdatedEvent;
import org.joinmastodon.android.events.PollUpdatedEvent;
import org.joinmastodon.android.events.RemoveAccountPostsEvent;
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.Notification;
import org.joinmastodon.android.model.PaginatedResponse;
import org.joinmastodon.android.model.Status;
@ -122,7 +123,9 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
}
NotificationHeaderStatusDisplayItem titleItem;
if(n.type==Notification.Type.MENTION || n.type==Notification.Type.STATUS){
Account self=AccountSessionManager.get(accountID).self;
if(n.type==Notification.Type.MENTION || n.type==Notification.Type.STATUS
|| (n.type==Notification.Type.REBLOG && !n.status.account.id.equals(self.id))){ // Iceshrimp quote
titleItem=null;
}else{
titleItem=new NotificationHeaderStatusDisplayItem(n.id, this, n, accountID);
@ -316,13 +319,16 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
public void onEmojiReactionsChanged(EmojiReactionsUpdatedEvent ev){
for(Notification n : data){
if(n.status!=null && n.status.getContentStatus().id.equals(ev.id)){
n.status.getContentStatus().update(ev);
AccountSessionManager.get(accountID).getCacheController().updateNotification(n);
for(int i=0; i<list.getChildCount(); i++){
RecyclerView.ViewHolder holder=list.getChildViewHolder(list.getChildAt(i));
if(holder instanceof EmojiReactionsStatusDisplayItem.Holder reactions && reactions.getItem().status==n.status.getContentStatus() && ev.viewHolder!=holder){
reactions.rebind();
}else if(holder instanceof TextStatusDisplayItem.Holder text && text.getItem().parentID.equals(n.getID())){
reactions.updateReactions(ev.reactions);
}
}
AccountSessionManager.get(accountID).getCacheController().updateNotification(n);
for(int i=0;i<list.getChildCount();i++){
RecyclerView.ViewHolder holder=list.getChildViewHolder(list.getChildAt(i));
if(holder instanceof TextStatusDisplayItem.Holder text && text.getItem().parentID.equals(n.getID())){
text.rebind();
}
}

View file

@ -58,7 +58,9 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.viewpager2.widget.ViewPager2;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.MastodonApp;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.accounts.BiteAccount;
import org.joinmastodon.android.api.requests.accounts.GetAccountByID;
import org.joinmastodon.android.api.requests.accounts.GetAccountRelationships;
import org.joinmastodon.android.api.requests.accounts.GetAccountStatuses;
@ -287,11 +289,10 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
noteEdit.setOnFocusChangeListener((v, hasFocus)->{
if(hasFocus){
hideFab();
noteEdit.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
}else{
showFab();
savePrivateNote(noteEdit.getText().toString());
return;
}
showFab();
savePrivateNote(noteEdit.getText().toString());
});
FrameLayout sizeWrapper=new FrameLayout(getActivity()){
@ -454,8 +455,8 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
}
private void hidePrivateNote(){
noteWrap.setVisibility(View.GONE);
noteEdit.setText(null);
noteWrap.setVisibility(View.GONE);
}
private void savePrivateNote(String note){
@ -469,6 +470,8 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
public void onSuccess(Relationship result) {
updateRelationship(result);
invalidateOptionsMenu();
if(!TextUtils.isEmpty(result.note))
Toast.makeText(MastodonApp.context, R.string.mo_personal_note_saved, Toast.LENGTH_SHORT).show();
}
@Override
@ -814,7 +817,10 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
if(isOwnProfile){
UiUtils.enableOptionsMenuIcons(getActivity(), menu, R.id.scheduled, R.id.bookmarks);
}else{
UiUtils.enableOptionsMenuIcons(getActivity(), menu, R.id.edit_note);
UiUtils.enableOptionsMenuIcons(getActivity(), menu, R.id.edit_note, R.id.biteuser_btn);
if (isInstanceIceshrimp()){
UiUtils.enableOptionsMenuIcons(getActivity(), menu, R.id.biteuser_btn);
}
}
boolean hasMultipleAccounts = AccountSessionManager.getInstance().getLoggedInAccounts().size() > 1;
menu.findItem(R.id.open_with_account).setVisible(hasMultipleAccounts);
@ -875,7 +881,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
}else if(id==R.id.open_in_browser){
UiUtils.launchWebBrowser(getActivity(), account.url);
}else if(id==R.id.block_domain){
UiUtils.confirmToggleBlockDomain(getActivity(), accountID, account.getDomain(), relationship.domainBlocking, ()->{
UiUtils.confirmToggleBlockDomain(getActivity(), accountID, account, relationship.domainBlocking, ()->{
relationship.domainBlocking=!relationship.domainBlocking;
updateRelationship();
});
@ -931,6 +937,18 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
}else if(id==R.id.save){
if(isInEditMode)
saveAndExitEditMode();
}else if(id==R.id.biteuser_btn){
new BiteAccount(profileAccountID).setCallback(new Callback<>(){
@Override
public void onSuccess(Object result){
Toast.makeText(getContext(), "User was bitten", Toast.LENGTH_SHORT).show();
}
@Override
public void onError(ErrorResponse error){
error.showToast(getContext());
}
}).exec(accountID).setRequestBody(new Object());
}else if(id==R.id.edit_note){
if(noteWrap.getVisibility()==View.GONE){
showPrivateNote();
@ -989,7 +1007,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
else hidePrivateNote();
invalidateOptionsMenu();
actionButton.setVisibility(View.VISIBLE);
notifyButton.setVisibility(relationship.following ? View.VISIBLE : View.GONE);
notifyButton.setVisibility(relationship.following && !isInstanceIceshrimpJs() ? View.VISIBLE : View.GONE); // always hide notify button on Iceshrimp-JS because it's unsupported on the server
UiUtils.setRelationshipToActionButtonM3(relationship, actionButton);
actionProgress.setIndeterminateTintList(actionButton.getTextColors());
notifyProgress.setIndeterminateTintList(notifyButton.getTextColors());

View file

@ -327,13 +327,16 @@ public abstract class StatusListFragment extends BaseStatusListFragment<Status>
public void onEmojiReactionsChanged(EmojiReactionsUpdatedEvent ev){
for(Status s:data){
if(s.getContentStatus().id.equals(ev.id)){
s.getContentStatus().update(ev);
AccountSessionManager.get(accountID).getCacheController().updateStatus(s);
for(int i=0;i<list.getChildCount();i++){
RecyclerView.ViewHolder holder=list.getChildViewHolder(list.getChildAt(i));
if(holder instanceof EmojiReactionsStatusDisplayItem.Holder reactions && reactions.getItem().status==s.getContentStatus() && ev.viewHolder!=holder){
reactions.rebind();
}else if(holder instanceof TextStatusDisplayItem.Holder text && text.getItem().parentID.equals(s.getID())){
reactions.updateReactions(ev.reactions);
}
}
AccountSessionManager.get(accountID).getCacheController().updateStatus(s);
for(int i=0;i<list.getChildCount();i++){
RecyclerView.ViewHolder holder=list.getChildViewHolder(list.getChildAt(i));
if(holder instanceof TextStatusDisplayItem.Holder text && text.getItem().parentID.equals(s.getID())){
text.rebind();
}
}

View file

@ -1,6 +1,7 @@
package org.joinmastodon.android.fragments.discover;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.app.assist.AssistContent;
import android.os.Build;
import android.os.Bundle;
@ -31,6 +32,9 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager2.widget.ViewPager2;
import java.util.Optional;
import me.grishka.appkit.Nav;
import me.grishka.appkit.fragments.AppKitFragment;
import me.grishka.appkit.fragments.BaseRecyclerFragment;
@ -60,6 +64,7 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
private String currentQuery;
private boolean disableDiscover;
private boolean isIceshrimp;
@Override
public void onCreate(Bundle savedInstanceState){
@ -78,13 +83,17 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
tabLayout=view.findViewById(R.id.tabbar);
pager=view.findViewById(R.id.pager);
tabViews=new FrameLayout[4];
Optional<Instance> instance=AccountSessionManager.get(accountID).getInstance();
disableDiscover=instance.map(Instance::isAkkoma).orElse(false);
isIceshrimp=instance.map(Instance::isIceshrimp).orElse(false);
tabViews=new FrameLayout[isIceshrimp ? 3 : 4]; // reduce array size on Iceshrimp to hide news feed because it's unsupported and always returns an empty list
for(int i=0;i<tabViews.length;i++){
FrameLayout tabView=new FrameLayout(getActivity());
tabView.setId(switch(i){
case 0 -> R.id.discover_posts;
case 1 -> R.id.discover_hashtags;
case 2 -> R.id.discover_news;
case 2 -> isIceshrimp ? R.id.discover_users : R.id.discover_news; // skip unsupported news discovery on Iceshrimp
case 3 -> R.id.discover_users;
default -> throw new IllegalStateException("Unexpected value: "+i);
});
@ -126,12 +135,15 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
accountsFragment=new DiscoverAccountsFragment();
accountsFragment.setArguments(args);
getChildFragmentManager().beginTransaction()
.add(R.id.discover_posts, postsFragment)
.add(R.id.discover_hashtags, hashtagsFragment)
.add(R.id.discover_news, newsFragment)
.add(R.id.discover_users, accountsFragment)
.commit();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction
.add(R.id.discover_posts, postsFragment)
.add(R.id.discover_hashtags, hashtagsFragment);
if(!isIceshrimp) // skip unsupported news discovery on Iceshrimp
transaction.add(R.id.discover_news, newsFragment);
transaction
.add(R.id.discover_users, accountsFragment)
.commit();
}
tabLayoutMediator=new TabLayoutMediator(tabLayout, pager, new TabLayoutMediator.TabConfigurationStrategy(){
@ -140,7 +152,7 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
tab.setText(switch(position){
case 0 -> R.string.posts;
case 1 -> R.string.hashtags;
case 2 -> R.string.news;
case 2 -> isIceshrimp ? R.string.for_you : R.string.news; // skip unsupported news discovery on Iceshrimp
case 3 -> R.string.for_you;
default -> throw new IllegalStateException("Unexpected value: "+position);
});
@ -160,7 +172,6 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
}
});
disableDiscover=AccountSessionManager.get(accountID).getInstance().map(Instance::isAkkoma).orElse(false);
searchView=view.findViewById(R.id.search_fragment);
if(searchFragment==null){
searchFragment=new SearchFragment();
@ -262,7 +273,7 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
return switch(page){
case 0 -> postsFragment;
case 1 -> hashtagsFragment;
case 2 -> newsFragment;
case 2 -> isIceshrimp ? accountsFragment : newsFragment; // skip unsupported news discovery on Iceshrimp
case 3 -> accountsFragment;
default -> throw new IllegalStateException("Unexpected value: "+page);
};

View file

@ -54,7 +54,6 @@ public class SettingsBehaviorFragment extends BaseSettingsFragment<Void> impleme
languageResolver.from(s.preferences.postingDefaultLanguage).orElse(null);
List<ListItem<Void>> items = new ArrayList<>(List.of(
languageItem=new ListItem<>(getString(R.string.default_post_language), postLanguage!=null ? postLanguage.getDisplayName(getContext()) : null, R.drawable.ic_fluent_local_language_24_regular, this::onDefaultLanguageClick),
customTabsItem=new ListItem<>(getString(R.string.settings_custom_tabs), getString(GlobalUserPreferences.useCustomTabs ? R.string.in_app_browser : R.string.system_browser), R.drawable.ic_fluent_open_24_regular, this::onCustomTabsClick),
altTextItem=new CheckableListItem<>(R.string.settings_alt_text_reminders, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.altTextReminders, R.drawable.ic_fluent_image_alt_text_24_regular, i->toggleCheckableItem(altTextItem)),
showPostsWithoutAltItem=new CheckableListItem<>(R.string.mo_settings_show_posts_without_alt, R.string.mo_settings_show_posts_without_alt_summary, CheckableListItem.Style.SWITCH, GlobalUserPreferences.showPostsWithoutAlt, R.drawable.ic_fluent_eye_tracking_on_24_regular, i->toggleCheckableItem(showPostsWithoutAltItem)),
@ -73,6 +72,11 @@ public class SettingsBehaviorFragment extends BaseSettingsFragment<Void> impleme
showRepliesItem=new CheckableListItem<>(R.string.sk_settings_show_replies, 0, CheckableListItem.Style.SWITCH, lp.showReplies, R.drawable.ic_fluent_arrow_reply_24_regular, i->toggleCheckableItem(showRepliesItem))
));
if(!isInstanceIceshrimpJs()) items.add(
0,
languageItem=new ListItem<>(getString(R.string.default_post_language), postLanguage!=null ? postLanguage.getDisplayName(getContext()) : null, R.drawable.ic_fluent_local_language_24_regular, this::onDefaultLanguageClick)
);
if(isInstanceAkkoma()) items.add(
replyVisibilityItem=new ListItem<>(R.string.sk_settings_reply_visibility, getReplyVisibilityString(), R.drawable.ic_fluent_chat_24_regular, this::onReplyVisibilityClick)
);
@ -203,7 +207,6 @@ public class SettingsBehaviorFragment extends BaseSettingsFragment<Void> impleme
@Override
protected void onHidden(){
super.onHidden();
GlobalUserPreferences.playGifs=playGifsItem.checked;
GlobalUserPreferences.overlayMedia=overlayMediaItem.checked;
GlobalUserPreferences.altTextReminders=altTextItem.checked;
GlobalUserPreferences.confirmUnfollow=confirmUnfollowItem.checked;
@ -215,13 +218,14 @@ public class SettingsBehaviorFragment extends BaseSettingsFragment<Void> impleme
GlobalUserPreferences.mentionRebloggerAutomatically=mentionRebloggerAutomaticallyItem.checked;
GlobalUserPreferences.hapticFeedback=hapticFeedbackItem.checked;
GlobalUserPreferences.showPostsWithoutAlt=showPostsWithoutAltItem.checked;
GlobalUserPreferences.save();
AccountLocalPreferences lp=getLocalPrefs();
boolean restartPlease=lp.showBoosts!=showBoostsItem.checked
|| lp.showReplies!=showRepliesItem.checked;
|| lp.showReplies!=showRepliesItem.checked || GlobalUserPreferences.playGifs!=playGifsItem.checked;
lp.showBoosts=showBoostsItem.checked;
lp.showReplies=showRepliesItem.checked;
GlobalUserPreferences.playGifs=playGifsItem.checked;
lp.save();
GlobalUserPreferences.save();
if(newPostLanguage!=null){
AccountSession s=AccountSessionManager.get(accountID);
if(s.preferences==null)

View file

@ -47,7 +47,7 @@ public class SettingsDisplayFragment extends BaseSettingsFragment<Void>{
private CheckableListItem<Void> pronounsInUserListingsItem, pronounsInTimelinesItem, pronounsInThreadsItem;
// MOSHIDON
private CheckableListItem<Void> enableDoubleTapToSwipeItem, relocatePublishButtonItem, showPostDividersItem, enableDoubleTapToSearchItem, showMediaPreviewItem;
private CheckableListItem<Void> enableDoubleTapToSwipeItem, relocatePublishButtonItem, showPostDividersItem, enableDoubleTapToSearchItem, showMediaPreviewItem, enhanceTextSizeItem;
private AccountLocalPreferences lp;
@ -63,6 +63,7 @@ public class SettingsDisplayFragment extends BaseSettingsFragment<Void>{
trueBlackModeItem=new CheckableListItem<>(R.string.sk_settings_true_black, R.string.mo_setting_true_black_summary, CheckableListItem.Style.SWITCH, GlobalUserPreferences.trueBlackTheme, R.drawable.ic_fluent_dark_theme_24_regular, i->onTrueBlackModeClick(), true),
publishTextItem=new ListItem<>(getString(R.string.sk_settings_publish_button_text), getPublishButtonText(), R.drawable.ic_fluent_send_24_regular, this::onPublishTextClick),
autoRevealCWsItem=new ListItem<>(R.string.sk_settings_auto_reveal_equal_spoilers, getAutoRevealSpoilersText(), R.drawable.ic_fluent_eye_24_regular, this::onAutoRevealSpoilersClick),
enhanceTextSizeItem=new CheckableListItem<>(R.string.mo_settings_enhance_text_size, R.string.mo_settings_enhance_text_size_summary, CheckableListItem.Style.SWITCH, GlobalUserPreferences.enhanceTextSize, R.drawable.ic_fluent_text_more_24_regular, i->onEnhanceTextSizeClick()),
relocatePublishButtonItem=new CheckableListItem<>(R.string.mo_relocate_publish_button, R.string.mo_setting_relocate_publish_summary, CheckableListItem.Style.SWITCH, GlobalUserPreferences.relocatePublishButton, R.drawable.ic_fluent_arrow_autofit_down_24_regular, i->toggleCheckableItem(relocatePublishButtonItem)),
revealCWsItem=new CheckableListItem<>(R.string.sk_settings_always_reveal_content_warnings, 0, CheckableListItem.Style.SWITCH, lp.revealCWs, R.drawable.ic_fluent_chat_warning_24_regular, i->toggleCheckableItem(revealCWsItem)),
hideSensitiveMediaItem=new CheckableListItem<>(R.string.settings_hide_sensitive_media, 0, CheckableListItem.Style.SWITCH, lp.hideSensitiveMedia, R.drawable.ic_fluent_flag_24_regular, i->toggleCheckableItem(hideSensitiveMediaItem)),
@ -141,6 +142,7 @@ public class SettingsDisplayFragment extends BaseSettingsFragment<Void>{
GlobalUserPreferences.displayPronounsInThreads=pronounsInThreadsItem.checked;
GlobalUserPreferences.displayPronounsInUserListings=pronounsInUserListingsItem.checked;
GlobalUserPreferences.showMediaPreview=showMediaPreviewItem.checked;
GlobalUserPreferences.enhanceTextSize=enhanceTextSizeItem.checked;
GlobalUserPreferences.save();
if(restartPlease) restartActivityToApplyNewTheme();
else E.post(new StatusDisplaySettingsChangedEvent(accountID));
@ -182,6 +184,11 @@ public class SettingsDisplayFragment extends BaseSettingsFragment<Void>{
maybeApplyNewThemeRightNow(null, null, prev);
}
private void onEnhanceTextSizeClick(){
toggleCheckableItem(enhanceTextSizeItem);
restartActivityToApplyNewTheme();
}
private void onAppearanceClick(ListItem<?> item_){
int selected=switch(GlobalUserPreferences.theme){
case LIGHT -> 0;

View file

@ -17,6 +17,7 @@ import org.joinmastodon.android.model.viewmodel.ListItem;
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
import org.joinmastodon.android.ui.utils.UiUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@ -35,24 +36,27 @@ public class SettingsInstanceFragment extends BaseSettingsFragment<Void> impleme
setTitle(R.string.sk_settings_instance);
AccountSession s=AccountSessionManager.get(accountID);
lp=s.getLocalPreferences();
onDataLoaded(List.of(
ArrayList<ListItem<Void>> items=new ArrayList<>(List.of(
new ListItem<>(AccountSessionManager.get(accountID).domain, getString(R.string.settings_server_explanation), R.drawable.ic_fluent_server_24_regular, this::onServerClick),
new ListItem<>(R.string.sk_settings_profile, 0, R.drawable.ic_fluent_open_24_regular, i->UiUtils.launchWebBrowser(getActivity(), "https://"+s.domain+"/settings/profile")),
new ListItem<>(R.string.sk_settings_posting, 0, R.drawable.ic_fluent_open_24_regular, i->UiUtils.launchWebBrowser(getActivity(), "https://"+s.domain+"/settings/preferences/other")),
new ListItem<>(R.string.sk_settings_auth, 0, R.drawable.ic_fluent_open_24_regular, i->UiUtils.launchWebBrowser(getActivity(), "https://"+s.domain+"/auth/edit"), 0, true),
contentTypesItem=new CheckableListItem<>(R.string.sk_settings_content_types, R.string.sk_settings_content_types_explanation, CheckableListItem.Style.SWITCH, lp.contentTypesEnabled, R.drawable.ic_fluent_text_edit_style_24_regular, i->onContentTypeClick()),
defaultContentTypeItem=new ListItem<>(R.string.sk_settings_default_content_type, lp.defaultContentType.getName(), R.drawable.ic_fluent_text_bold_24_regular, this::onDefaultContentTypeClick, 0, true),
emojiReactionsItem=new CheckableListItem<>(R.string.sk_settings_emoji_reactions, R.string.sk_settings_emoji_reactions_explanation, CheckableListItem.Style.SWITCH, lp.emojiReactionsEnabled, R.drawable.ic_fluent_emoji_laugh_24_regular, i->onEmojiReactionsClick()),
showEmojiReactionsItem=new ListItem<>(R.string.sk_settings_show_emoji_reactions, getShowEmojiReactionsString(), R.drawable.ic_fluent_emoji_24_regular, this::onShowEmojiReactionsClick, 0, true),
localOnlyItem=new CheckableListItem<>(R.string.sk_settings_support_local_only, R.string.sk_settings_local_only_explanation, CheckableListItem.Style.SWITCH, lp.localOnlySupported, R.drawable.ic_fluent_eye_24_regular, i->onLocalOnlyClick()),
glitchModeItem=new CheckableListItem<>(R.string.sk_settings_glitch_instance, R.string.sk_settings_glitch_mode_explanation, CheckableListItem.Style.SWITCH, lp.glitchInstance, R.drawable.ic_fluent_eye_24_filled, i->toggleCheckableItem(glitchModeItem))
));
contentTypesItem.checkedChangeListener=checked->onContentTypeClick();
defaultContentTypeItem.isEnabled=contentTypesItem.checked;
if(!isInstanceIceshrimp()){
items.add(4, contentTypesItem=new CheckableListItem<>(R.string.sk_settings_content_types, R.string.sk_settings_content_types_explanation, CheckableListItem.Style.SWITCH, lp.contentTypesEnabled, R.drawable.ic_fluent_text_edit_style_24_regular, i->onContentTypeClick()));
items.add(5, defaultContentTypeItem=new ListItem<>(R.string.sk_settings_default_content_type, lp.defaultContentType.getName(), R.drawable.ic_fluent_text_bold_24_regular, this::onDefaultContentTypeClick, 0, true));
contentTypesItem.checkedChangeListener=checked->onContentTypeClick();
defaultContentTypeItem.isEnabled=contentTypesItem.checked;
}
emojiReactionsItem.checkedChangeListener=checked->onEmojiReactionsClick();
showEmojiReactionsItem.isEnabled=emojiReactionsItem.checked;
localOnlyItem.checkedChangeListener=checked->onLocalOnlyClick();
glitchModeItem.isEnabled=localOnlyItem.checked;
onDataLoaded(items);
}
@Override
@ -61,7 +65,8 @@ public class SettingsInstanceFragment extends BaseSettingsFragment<Void> impleme
@Override
protected void onHidden(){
super.onHidden();
lp.contentTypesEnabled=contentTypesItem.checked;
if(contentTypesItem!=null)
lp.contentTypesEnabled=contentTypesItem.checked;
lp.emojiReactionsEnabled=emojiReactionsItem.checked;
lp.localOnlySupported=localOnlyItem.checked;
lp.glitchInstance=glitchModeItem.checked;
@ -84,7 +89,8 @@ public class SettingsInstanceFragment extends BaseSettingsFragment<Void> impleme
private void resetDefaultContentType(){
lp.defaultContentType=defaultContentTypeItem.isEnabled
? ContentType.PLAIN : ContentType.UNSPECIFIED;
? isInstanceIceshrimp() ? ContentType.MISSKEY_MARKDOWN
: ContentType.PLAIN : ContentType.UNSPECIFIED;
defaultContentTypeItem.subtitleRes=lp.defaultContentType.getName();
}

View file

@ -64,7 +64,7 @@ public class SettingsMainFragment extends BaseSettingsFragment<Void>{
));
Instance instance=AccountSessionManager.getInstance().getInstanceInfo(account.domain);
if(!instance.isAkkoma()){
if(!instance.isAkkoma() && !instance.isIceshrimpJs()){ // hide filter settings on Akkoma and Iceshrimp-JS because the servers don't support the feature
data.add(3, new ListItem<>(R.string.settings_filters, 0, R.drawable.ic_fluent_filter_24_regular, this::onFiltersClick));
}

View file

@ -26,6 +26,7 @@ import org.joinmastodon.android.model.viewmodel.ListItem;
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
import org.joinmastodon.android.ui.utils.HideableSingleViewRecyclerAdapter;
import org.joinmastodon.android.ui.utils.UiUtils;
import org.joinmastodon.android.utils.UnifiedPushHelper;
import org.unifiedpush.android.connector.UnifiedPush;
import java.time.Instant;
@ -57,6 +58,7 @@ public class SettingsNotificationsFragment extends BaseSettingsFragment<Void>{
// MEGALODON
private boolean useUnifiedPush = false;
private boolean hasAnyUnifiedPushDistrib = false;
private CheckableListItem<Void> uniformIconItem, deleteItem, onlyLatestItem, unifiedPushItem;
private CheckableListItem<Void> postsItem, updateItem;
@ -72,7 +74,8 @@ public class SettingsNotificationsFragment extends BaseSettingsFragment<Void>{
lp=AccountSessionManager.get(accountID).getLocalPreferences();
getPushSubscription();
useUnifiedPush=!UnifiedPush.getDistributor(getContext()).isEmpty();
useUnifiedPush=UnifiedPushHelper.isUnifiedPushEnabled(getContext());
hasAnyUnifiedPushDistrib=UnifiedPushHelper.hasAnyDistributorInstalled(getContext());
onDataLoaded(List.of(
pauseItem=new CheckableListItem<>(getString(R.string.pause_all_notifications), getPauseItemSubtitle(), CheckableListItem.Style.SWITCH, false, R.drawable.ic_fluent_alert_snooze_24_regular, i->onPauseNotificationsClick(false)),
@ -94,7 +97,7 @@ public class SettingsNotificationsFragment extends BaseSettingsFragment<Void>{
));
//only enable when distributors, who can receive notifications, are available
unifiedPushItem.isEnabled=!UnifiedPush.getDistributors(getContext(), new ArrayList<>()).isEmpty();
unifiedPushItem.isEnabled=hasAnyUnifiedPushDistrib;
if (!unifiedPushItem.isEnabled) {
unifiedPushItem.subtitleRes=R.string.sk_settings_unifiedpush_no_distributor_body;
}
@ -124,7 +127,7 @@ public class SettingsNotificationsFragment extends BaseSettingsFragment<Void>{
GlobalUserPreferences.save();
lp.keepOnlyLatestNotification=onlyLatestItem.checked;
lp.save();
if(needUpdateNotificationSettings && PushSubscriptionManager.arePushNotificationsAvailable()){
if(needUpdateNotificationSettings && (PushSubscriptionManager.arePushNotificationsAvailable() || useUnifiedPush)){
ps.alerts.mention=mentionsItem.checked;
ps.alerts.reblog=boostsItem.checked;
ps.alerts.favourite=favoritesItem.checked;
@ -316,12 +319,12 @@ public class SettingsNotificationsFragment extends BaseSettingsFragment<Void>{
bannerText.setText(R.string.notifications_disabled_in_system);
bannerButton.setText(R.string.open_system_notification_settings);
bannerButton.setOnClickListener(v->openSystemNotificationSettings());
}else if(BuildConfig.BUILD_TYPE.equals("fdroidRelease") && UnifiedPush.getDistributor(getContext()).isEmpty()){
}else if(BuildConfig.BUILD_TYPE.equals("fdroidRelease") && useUnifiedPush){
bannerAdapter.setVisible(true);
bannerIcon.setImageResource(R.drawable.ic_fluent_warning_24_filled);
bannerTitle.setVisibility(View.VISIBLE);
bannerTitle.setText(R.string.mo_settings_unifiedpush_warning);
if(UnifiedPush.getDistributors(getContext(), new ArrayList<>()).isEmpty()) {
if(!hasAnyUnifiedPushDistrib) {
bannerText.setText(R.string.mo_settings_unifiedpush_warning_no_distributors);
bannerButton.setText(R.string.info);
bannerButton.setOnClickListener(v->UiUtils.launchWebBrowser(getContext(), "https://unifiedpush.org/"));
@ -342,23 +345,15 @@ public class SettingsNotificationsFragment extends BaseSettingsFragment<Void>{
}
private void onUnifiedPushClick(){
if(UnifiedPush.getDistributor(getContext()).isEmpty()){
List<String> distributors = UnifiedPush.getDistributors(getContext(), new ArrayList<>());
if(!useUnifiedPush){
List<String> distributors = UnifiedPush.getDistributors(getContext());
showUnifiedPushRegisterDialog(distributors);
return;
}
for (AccountSession accountSession : AccountSessionManager.getInstance().getLoggedInAccounts()) {
UnifiedPush.unregisterApp(
getContext(),
accountSession.getID()
);
//re-register to fcm
accountSession.getPushSubscriptionManager().registerAccountForPush(getPushSubscription());
}
UnifiedPushHelper.unregisterAllAccounts(getContext());
unifiedPushItem.toggle();
rebindItem(unifiedPushItem);
useUnifiedPush = false;
}
private void showUnifiedPushRegisterDialog(List<String> distributors){
@ -366,16 +361,10 @@ public class SettingsNotificationsFragment extends BaseSettingsFragment<Void>{
(dialog, which)->{
String userDistrib = distributors.get(which);
UnifiedPush.saveDistributor(getContext(), userDistrib);
for (AccountSession accountSession : AccountSessionManager.getInstance().getLoggedInAccounts()){
UnifiedPush.registerApp(
getContext(),
accountSession.getID(),
new ArrayList<>(),
getContext().getPackageName()
);
}
UnifiedPushHelper.registerAllAccounts(getContext());
unifiedPushItem.toggle();
rebindItem(unifiedPushItem);
useUnifiedPush = true;
}).setOnCancelListener(d->rebindItem(unifiedPushItem)).show();
}

View file

@ -50,11 +50,11 @@ public class Announcement extends BaseModel implements DisplayItemsParent {
if(reactions==null) reactions=new ArrayList<>();
}
public Status toStatus() {
public Status toStatus(boolean isIceshrimp) {
Status s=Status.ofFake(id, content, publishedAt);
s.createdAt=startsAt != null ? startsAt : publishedAt;
s.reactions=reactions;
if(updatedAt != null) s.editedAt=updatedAt;
if(updatedAt != null && (!isIceshrimp || !updatedAt.equals(publishedAt))) s.editedAt=updatedAt;
return s;
}

View file

@ -34,6 +34,6 @@ public enum ContentType {
}
public boolean supportedByInstance(Instance i) {
return i.isAkkoma() || (this!=BBCODE && this!=MISSKEY_MARKDOWN);
return i.isAkkoma() || i.isIceshrimp() || (this!=BBCODE && this!=MISSKEY_MARKDOWN);
}
}

View file

@ -22,6 +22,7 @@ public class EmojiReaction {
public String staticUrl;
public transient ImageLoaderRequest request;
public transient boolean pendingChange=false;
public String getUrl(boolean playGifs){
String idealUrl=playGifs ? url : staticUrl;
@ -60,4 +61,18 @@ public class EmojiReaction {
accounts.add(self);
accountIds.add(self.id);
}
public EmojiReaction copy() {
EmojiReaction r=new EmojiReaction();
r.accounts=accounts;
r.accountIds=accountIds;
r.count=count;
r.me=me;
r.name=name;
r.url=url;
r.staticUrl=staticUrl;
r.request=request;
r.pendingChange=pendingChange;
return r;
}
}

View file

@ -146,14 +146,28 @@ public class Instance extends BaseModel{
return ci;
}
// This method has almost exclusively been used to improve support for
// Akkoma with no regard for Pleroma, hence its name. However, it is
// more likely than not that most uses should also apply to Pleroma,
// so checking for that too probably causes more good than harm.
public boolean isAkkoma() {
return pleroma != null;
return version.contains("compatible; Akkoma") || version.contains("compatible; Pleroma");
}
public boolean isPixelfed() {
return version.contains("compatible; Pixelfed");
}
// For both Iceshrimp-JS and Iceshrimp.NET
public boolean isIceshrimp() {
return version.contains("compatible; Iceshrimp");
}
// Only for Iceshrimp-JS
public boolean isIceshrimpJs() {
return version.contains("compatible; Iceshrimp "); // Iceshrimp.NET will not have a space immediately after
}
public boolean hasFeature(Feature feature) {
Optional<List<String>> pleromaFeatures = Optional.ofNullable(pleroma)
.map(p -> p.metadata)
@ -219,6 +233,7 @@ public class Instance extends BaseModel{
public StatusesConfiguration statuses;
public MediaAttachmentsConfiguration mediaAttachments;
public PollsConfiguration polls;
public ReactionsConfiguration reactions;
}
@Parcel
@ -242,8 +257,14 @@ public class Instance extends BaseModel{
public static class PollsConfiguration{
public int maxOptions;
public int maxCharactersPerOption;
public int minExpiration;
public int maxExpiration;
public long minExpiration;
public long maxExpiration;
}
@Parcel
public static class ReactionsConfiguration {
public int maxReactions;
public String defaultReaction;
}
@Parcel

View file

@ -65,7 +65,9 @@ public class Notification extends BaseModel implements DisplayItemsParent{
@SerializedName("admin.sign_up")
SIGN_UP,
@SerializedName("admin.report")
REPORT
REPORT,
@SerializedName("bite")
BITE
}
@Parcel

View file

@ -111,12 +111,13 @@ public class CustomEmojiPopupKeyboard extends PopupKeyboard{
list.setPadding(V.dp(16), 0, V.dp(16), 0);
imgLoader=new ListImageLoaderWrapper(activity, list, new RecyclerViewDelegate(list), null);
List<Emoji> recentEmoji=new ArrayList<>(lp.recentCustomEmoji);
if(!recentEmoji.isEmpty())
adapter.addAdapter(new SingleCategoryAdapter(recentEmojiCategory=new EmojiCategory(activity.getString(R.string.mo_emoji_recent), recentEmoji)));
for(EmojiCategory category:emojis)
adapter.addAdapter(new SingleCategoryAdapter(category));
if (!forReaction){
List<Emoji> recentEmoji=new ArrayList<>(lp.recentCustomEmoji);
if(!recentEmoji.isEmpty())
adapter.addAdapter(new SingleCategoryAdapter(recentEmojiCategory=new EmojiCategory(activity.getString(R.string.mo_emoji_recent), recentEmoji)));
for(EmojiCategory category : emojis)
adapter.addAdapter(new SingleCategoryAdapter(category));
}
list.setAdapter(adapter);
list.addItemDecoration(new RecyclerView.ItemDecoration(){
@Override
@ -229,6 +230,15 @@ public class CustomEmojiPopupKeyboard extends PopupKeyboard{
}
}
public void customToggleKeyboardPopup(){
List<Emoji> recentEmoji=new ArrayList<>(lp.recentCustomEmoji);
if(!recentEmoji.isEmpty())
adapter.addAdapter(new SingleCategoryAdapter(recentEmojiCategory=new EmojiCategory(activity.getString(R.string.mo_emoji_recent), recentEmoji)));
for(EmojiCategory category : emojis)
adapter.addAdapter(new SingleCategoryAdapter(category));
super.toggleKeyboardPopup(null);
}
private class SingleCategoryAdapter extends UsableRecyclerView.Adapter<RecyclerView.ViewHolder> implements ImageLoaderRecyclerAdapter, Filterable{
private EmojiCategory category;

View file

@ -1,5 +1,6 @@
package org.joinmastodon.android.ui.displayitems;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.Context;
import android.graphics.Paint;
@ -14,6 +15,8 @@ import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.Toast;
import android.widget.Toolbar;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
@ -33,16 +36,24 @@ import org.joinmastodon.android.api.requests.statuses.PleromaDeleteStatusReactio
import org.joinmastodon.android.api.session.AccountSession;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.events.EmojiReactionsUpdatedEvent;
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
import org.joinmastodon.android.fragments.BaseStatusListFragment;
import org.joinmastodon.android.fragments.account_list.StatusEmojiReactionsListFragment;
import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.Emoji;
import org.joinmastodon.android.model.EmojiReaction;
import org.joinmastodon.android.model.Instance;
import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.ui.CustomEmojiPopupKeyboard;
import org.joinmastodon.android.ui.utils.TextDrawable;
import org.joinmastodon.android.ui.utils.UiUtils;
import org.joinmastodon.android.ui.views.ProgressBarButton;
import org.joinmastodon.android.ui.views.EmojiReactionButton;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import me.grishka.appkit.Nav;
import me.grishka.appkit.api.Callback;
@ -62,6 +73,7 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
private final boolean hideEmpty, forAnnouncement, playGifs;
private final String accountID;
private static final float ALPHA_DISABLED=0.55f;
private boolean forceShow=false;
public EmojiReactionsStatusDisplayItem(String parentID, BaseStatusListFragment<?> parentFragment, Status status, String accountID, boolean hideEmpty, boolean forAnnouncement) {
super(parentID, parentFragment);
@ -90,6 +102,10 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
}
public boolean isHidden(){
if(forceShow){
forceShow=false;
return false;
}
return status.reactions.isEmpty() && hideEmpty;
}
@ -101,7 +117,7 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
vh.btn.setAlpha(visible ? ALPHA_DISABLED : 1);
}
private MastodonAPIRequest<?> createRequest(String name, int count, boolean delete, Holder.EmojiReactionViewHolder vh, Runnable cb, Runnable err){
private MastodonAPIRequest<?> createRequest(String name, int count, boolean delete, Holder.EmojiReactionViewHolder vh, Consumer<Status> cb, Runnable err){
setActionProgressVisible(vh, true);
boolean ak=parentFragment.isInstanceAkkoma();
boolean keepSpinning=delete && count == 1;
@ -113,7 +129,7 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
@Override
public void onSuccess(Object result){
if(!keepSpinning) setActionProgressVisible(vh, false);
cb.run();
cb.accept(null);
}
@Override
public void onError(ErrorResponse error){
@ -130,7 +146,7 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
@Override
public void onSuccess(Status result){
if(!keepSpinning) setActionProgressVisible(vh, false);
cb.run();
cb.accept(result);
}
@Override
public void onError(ErrorResponse error){
@ -151,6 +167,8 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
private final ProgressBar progress;
private final EmojiReactionsAdapter adapter;
private final ListImageLoaderWrapper imgLoader;
private int meReactionCount=0;
private Instance instance;
public Holder(Activity activity, ViewGroup parent) {
super(activity, R.layout.display_item_emoji_reactions, parent);
@ -171,6 +189,18 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
if(emojiKeyboard != null) root.removeView(emojiKeyboard.getView());
addButton.setSelected(false);
AccountSession session=item.parentFragment.getSession();
instance=item.parentFragment.getInstance().get();
if(instance.configuration!=null && instance.configuration.reactions!=null && instance.configuration.reactions.maxReactions!=0){
meReactionCount=(int) item.status.reactions.stream().filter(r->r.me).count();
boolean canReact;
if (instance.isIceshrimp()){
canReact = true;
}else{
canReact=meReactionCount<instance.configuration.reactions.maxReactions;
}
addButton.setClickable(canReact);
addButton.setAlpha(canReact ? 1 : ALPHA_DISABLED);
}
item.status.reactions.forEach(r->r.request=r.getUrl(item.playGifs)!=null
? new UrlImageLoaderRequest(r.getUrl(item.playGifs), 0, V.sp(24))
: null);
@ -182,18 +212,34 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
emojiKeyboard.setListener(this);
space.setVisibility(View.GONE);
root.addView(emojiKeyboard.getView());
boolean hidden=item.isHidden();
root.setVisibility(hidden ? View.GONE : View.VISIBLE);
line.setVisibility(hidden ? View.GONE : View.VISIBLE);
updateVisibility(item.isHidden(), true);
imgLoader.updateImages();
adapter.notifyDataSetChanged();
if(!GlobalUserPreferences.showDividers || item.isHidden())
return;
StatusDisplayItem next=getNextVisibleDisplayItem().orElse(null);
if(next!=null && !next.parentID.equals(item.parentID)) next=null;
if(next instanceof ExtendedFooterStatusDisplayItem)
itemView.setPadding(0, 0, 0, V.dp(12));
else
itemView.setPadding(0, 0, 0, 0);
}
private void updateVisibility(boolean hidden, boolean force){
int visibility=hidden ? View.GONE : View.VISIBLE;
if(!force && visibility==root.getVisibility())
return;
root.setVisibility(visibility);
line.setVisibility(visibility);
line.setPadding(
list.getPaddingLeft(),
hidden ? 0 : V.dp(8),
list.getPaddingRight(),
item.forAnnouncement ? V.dp(8) : 0
);
imgLoader.updateImages();
adapter.notifyDataSetChanged();
}
}
private void hideEmojiKeyboard(){
space.setVisibility(View.GONE);
@ -244,19 +290,32 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
}
}
EmojiReaction finalExisting=existing;
item.createRequest(emoji, existing==null ? 1 : existing.count, false, null, ()->{
item.createRequest(emoji, existing==null ? 1 : existing.count, false, null, (status)->{
resetBtn.run();
if(finalExisting==null){
int pos=item.status.reactions.size();
int pos=status.reactions.stream()
.filter(r->r.name.equals(info!=null ? info.shortcode : emoji))
.findFirst()
.map(r->status.reactions.indexOf(r))
.orElse(item.status.reactions.size());
boolean previouslyEmpty=item.status.reactions.isEmpty();
item.status.reactions.add(pos, info!=null ? EmojiReaction.of(info, me) : EmojiReaction.of(emoji, me));
adapter.notifyItemRangeInserted(pos, 1);
if(previouslyEmpty)
adapter.notifyItemChanged(pos);
else
adapter.notifyItemInserted(pos);
RecyclerView.SmoothScroller scroller=new LinearSmoothScroller(list.getContext());
scroller.setTargetPosition(pos);
list.getLayoutManager().startSmoothScroll(scroller);
updateMeReactionCount(false);
}else{
finalExisting.add(me);
adapter.notifyItemChanged(item.status.reactions.indexOf(finalExisting));
}
if(instance.isIceshrimpJs() && status!=null){
item.parentFragment.onFavoriteChanged(status, getItemID());
E.post(new StatusCountersUpdatedEvent(status));
}
E.post(new EmojiReactionsUpdatedEvent(item.status.id, item.status.reactions, countBefore==0, adapter.parentHolder));
}, resetBtn).exec(item.accountID);
}
@ -265,7 +324,7 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
public void onBackspace() {}
private void onReactClick(View v){
emojiKeyboard.toggleKeyboardPopup(null);
emojiKeyboard.customToggleKeyboardPopup();
v.setSelected(emojiKeyboard.isVisible());
space.setVisibility(emojiKeyboard.isVisible() ? View.VISIBLE : View.GONE);
DisplayMetrics displayMetrics = new DisplayMetrics();
@ -278,6 +337,99 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
}
}
private void updateAddButtonClickable() {
if(instance==null || instance.configuration==null || instance.configuration.reactions==null || instance.configuration.reactions.maxReactions==0)
return;
boolean canReact=meReactionCount<instance.configuration.reactions.maxReactions;
addButton.setClickable(canReact);
ObjectAnimator anim=ObjectAnimator.ofFloat(
addButton, View.ALPHA,
canReact ? ALPHA_DISABLED : 1,
canReact ? 1 : ALPHA_DISABLED);
anim.setDuration(200);
anim.start();
}
private void updateMeReactionCount(boolean deleting) {
meReactionCount=Math.max(0, meReactionCount + (deleting ? -1 : 1));
updateAddButtonClickable();
}
public void updateReactions(List<EmojiReaction> reactions){
item.status.reactions=new ArrayList<>(item.status.reactions); // I don't know how, but this seemingly fixes a bug
List<EmojiReaction> toRemove=new ArrayList<>();
for(int i=0;i<item.status.reactions.size();i++){
EmojiReaction reaction=item.status.reactions.get(i);
Optional<EmojiReaction> newReactionOptional=reactions.stream().filter(r->r.name.equals(reaction.name)).findFirst();
if(newReactionOptional.isEmpty()){ // deleted reactions
toRemove.add(reaction);
continue;
}
// changed reactions
EmojiReaction newReaction=newReactionOptional.get();
if(reaction.count!=newReaction.count || reaction.me!=newReaction.me || reaction.pendingChange!=newReaction.pendingChange){
if(newReaction.pendingChange){
View holderView=list.getChildAt(i);
if(holderView!=null){
EmojiReactionViewHolder reactionHolder=(EmojiReactionViewHolder) list.getChildViewHolder(holderView);
item.setActionProgressVisible(reactionHolder, true);
}
}else{
item.status.reactions.set(i, newReaction);
adapter.notifyItemChanged(i);
}
}
}
Collections.reverse(toRemove);
for(EmojiReaction r:toRemove){
int index=item.status.reactions.indexOf(r);
item.status.reactions.remove(index);
adapter.notifyItemRemoved(index);
}
boolean pendingAddReaction=false;
for(int i=0;i<reactions.size();i++){
EmojiReaction reaction=reactions.get(i);
if(item.status.reactions.stream().anyMatch(r->r.name.equals(reaction.name)))
continue;
// new reactions
if(reaction.pendingChange){
pendingAddReaction=true;
item.forceShow=true;
continue;
}
boolean previouslyEmpty=item.status.reactions.isEmpty();
item.status.reactions.add(i, reaction);
if(previouslyEmpty)
adapter.notifyItemChanged(i);
else
adapter.notifyItemInserted(i);
RecyclerView.SmoothScroller scroller=new LinearSmoothScroller(list.getContext());
scroller.setTargetPosition(i);
list.getLayoutManager().startSmoothScroll(scroller);
}
if(pendingAddReaction){
progress.setVisibility(View.VISIBLE);
addButton.setClickable(false);
addButton.setAlpha(ALPHA_DISABLED);
}else{
progress.setVisibility(View.GONE);
}
int newMeReactionCount=(int) reactions.stream().filter(r->r.me || r.pendingChange).count();
if (newMeReactionCount!=meReactionCount){
meReactionCount=newMeReactionCount;
updateAddButtonClickable();
}
updateVisibility(reactions.isEmpty() && item.hideEmpty, false);
}
@Override
public void setImage(int index, Drawable image){
View child=list.getChildAt(index);
@ -330,7 +482,7 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
}
private static class EmojiReactionViewHolder extends BindableViewHolder<Pair<EmojiReactionsStatusDisplayItem, EmojiReaction>> implements ImageLoaderViewHolder{
private final ProgressBarButton btn;
private final EmojiReactionButton btn;
private final ProgressBar progress;
public EmojiReactionViewHolder(Context context, RecyclerView list){
@ -356,6 +508,12 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
@Override
public void onBind(Pair<EmojiReactionsStatusDisplayItem, EmojiReaction> item){
if(item.second.pendingChange){
itemView.setVisibility(View.GONE);
return;
}else{
itemView.setVisibility(View.VISIBLE);
}
item.first.setActionProgressVisible(this, false);
EmojiReactionsStatusDisplayItem parent=item.first;
EmojiReaction reaction=item.second;
@ -371,10 +529,25 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
btn.setCompoundDrawablesRelative(item.first.placeholder, null, null, null);
}
btn.setSelected(reaction.me);
if(parent.parentFragment.isInstanceIceshrimpJs() && reaction.name.contains("@")){
btn.setEnabled(false);
btn.setClickable(false);
btn.setLongClickable(true);
}else{
btn.setEnabled(true);
btn.setClickable(true);
}
btn.setOnClickListener(e->{
EmojiReactionsAdapter adapter = (EmojiReactionsAdapter) getBindingAdapter();
Instance instance = adapter.parentHolder.instance;
if(instance.configuration!=null && instance.configuration.reactions!=null && instance.configuration.reactions.maxReactions!=0 &&
adapter.parentHolder.meReactionCount >= instance.configuration.reactions.maxReactions &&
!reaction.me){
return;
}
boolean deleting=reaction.me;
parent.createRequest(reaction.name, reaction.count, deleting, this, ()->{
EmojiReactionsAdapter adapter = (EmojiReactionsAdapter) getBindingAdapter();
parent.createRequest(reaction.name, reaction.count, deleting, this, (status)->{
for(int i=0; i<parent.status.reactions.size(); i++){
EmojiReaction r=parent.status.reactions.get(i);
if(!r.name.equals(reaction.name)) continue;
@ -394,12 +567,20 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
adapter.parentHolder.root.setVisibility(View.GONE);
adapter.parentHolder.line.setVisibility(View.GONE);
}
if(instance.configuration!=null && instance.configuration.reactions!=null && instance.configuration.reactions.maxReactions!=0){
adapter.parentHolder.updateMeReactionCount(deleting);
}
if(instance.isIceshrimpJs() && status!=null){
parent.parentFragment.onFavoriteChanged(status, adapter.parentHolder.getItemID());
E.post(new StatusCountersUpdatedEvent(status));
}
E.post(new EmojiReactionsUpdatedEvent(parent.status.id, parent.status.reactions, parent.status.reactions.isEmpty(), adapter.parentHolder));
adapter.parentHolder.imgLoader.updateImages();
}, null).exec(parent.parentFragment.getAccountID());
});
if (parent.parentFragment.isInstanceAkkoma()) {
if (parent.parentFragment.isInstanceAkkoma() || parent.parentFragment.isInstanceIceshrimp()) {
// glitch-soc doesn't have this, afaik
btn.setOnLongClickListener(e->{
EmojiReaction emojiReaction=parent.status.reactions.get(getAbsoluteAdapterPosition());
@ -410,6 +591,9 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
args.putString("emoji", atSymbolIndex != -1 ? emojiReaction.name.substring(0, atSymbolIndex) : emojiReaction.name);
args.putString("url", emojiReaction.getUrl(parent.playGifs));
args.putInt("count", emojiReaction.count);
if (emojiReaction.url != null) {
Toast.makeText(e.getContext(), ":" + emojiReaction.name + ":", Toast.LENGTH_SHORT).show();
}
Nav.go(parent.parentFragment.getActivity(), StatusEmojiReactionsListFragment.class, args);
return true;
});

View file

@ -39,6 +39,16 @@ public class ErrorStatusDisplayItem extends StatusDisplayItem{
findViewById(R.id.button_copy_error_details).setOnClickListener(this::copyErrorDetails);
}
@Override
public void onClick(){
// explicitly do nothing when clicked
}
@Override
public boolean isEnabled(){
return false;
}
@Override
public void onBind(ErrorStatusDisplayItem item) {
openInBrowserButton.setEnabled(item.status!=null && item.status.url!=null);

View file

@ -46,7 +46,6 @@ import me.grishka.appkit.utils.CubicBezierInterpolator;
import me.grishka.appkit.utils.V;
public class FooterStatusDisplayItem extends StatusDisplayItem{
public final Status status;
private final String accountID;
public boolean hideCounts;
@ -316,17 +315,16 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
UiUtils.opacityIn(v);
Bundle args=new Bundle();
args.putString("account", item.accountID);
AccountSession accountSession=AccountSessionManager.getInstance().getAccount(item.accountID);
Instance instance=AccountSessionManager.getInstance().getInstanceInfo(accountSession.domain);
if(instance.pleroma == null){
Instance instance=AccountSessionManager.get(item.accountID).getInstance().get();
if(instance.isAkkoma() || instance.isIceshrimp()){
args.putParcelable("quote", Parcels.wrap(item.status));
}else{
StringBuilder prefilledText = new StringBuilder().append("\n\n");
String ownID = AccountSessionManager.getInstance().getAccount(item.accountID).self.id;
if (!item.status.account.id.equals(ownID)) prefilledText.append('@').append(item.status.account.acct).append(' ');
prefilledText.append(item.status.url);
args.putString("prefilledText", prefilledText.toString());
args.putInt("selectionStart", 0);
}else{
args.putParcelable("quote", Parcels.wrap(item.status));
}
Nav.go(item.parentFragment.getActivity(), ComposeFragment.class, args);
});
@ -335,6 +333,20 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
return true;
}
public void onFavoriteClick() {
favorite.setSelected(item.status.favourited);
favorite.animate().scaleX(0.95f).scaleY(0.95f).setInterpolator(CubicBezierInterpolator.DEFAULT).setDuration(75).start();
UiUtils.opacityOut(favorite);
favorite.postDelayed(() -> {
favorite.animate().scaleX(1).scaleY(1).setInterpolator(CubicBezierInterpolator.DEFAULT).setDuration(150).start();
UiUtils.opacityIn(favorite);
if(item.status.favourited && !GlobalUserPreferences.reduceMotion && !GlobalUserPreferences.likeIcon) {
favorite.startAnimation(spin);
}
}, 300);
bindText(favorites, item.status.favouritesCount);
}
private void onFavoriteClick(View v){
if(item.status.preview) return;
applyInteraction(v, status -> {

View file

@ -22,9 +22,12 @@ import android.widget.TextView;
import android.widget.Toast;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.MastodonApp;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.accounts.BiteAccount;
import org.joinmastodon.android.api.requests.accounts.GetAccountRelationships;
import org.joinmastodon.android.api.requests.announcements.DismissAnnouncement;
import org.joinmastodon.android.api.requests.statuses.BitePost;
import org.joinmastodon.android.api.requests.statuses.CreateStatus;
import org.joinmastodon.android.api.requests.statuses.GetStatusSourceText;
import org.joinmastodon.android.api.session.AccountSession;
@ -113,7 +116,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
}
public static HeaderStatusDisplayItem fromAnnouncement(Announcement a, Status fakeStatus, Account instanceUser, BaseStatusListFragment parentFragment, String accountID, Consumer<String> consumeReadID) {
HeaderStatusDisplayItem item = new HeaderStatusDisplayItem(a.id, instanceUser, a.startsAt, parentFragment, accountID, fakeStatus, null, null, null);
HeaderStatusDisplayItem item = new HeaderStatusDisplayItem(a.id, instanceUser, a.startsAt!=null ? a.startsAt : fakeStatus.createdAt, parentFragment, accountID, fakeStatus, null, null, null);
item.announcement = a;
item.consumeReadAnnouncement = consumeReadID;
return item;
@ -263,6 +266,18 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
UiUtils.launchWebBrowser(activity, item.status.url);
}else if(id==R.id.copy_link){
UiUtils.copyText(parent, item.status.url);
}else if(id==R.id.bitepost_btn){
new BitePost(item.status.id).setCallback(new Callback<>(){
@Override
public void onSuccess(Object result){
Toast.makeText(MastodonApp.context, "Post was bitten", Toast.LENGTH_SHORT).show();
}
@Override
public void onError(ErrorResponse error){
error.showToast(MastodonApp.context);
}
}).exec(item.parentFragment.getAccountID()).setRequestBody(new Object());
}else if(id==R.id.follow){
if(relationship==null)
return true;
@ -279,7 +294,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
Toast.makeText(activity, activity.getString(rel.following ? R.string.followed_user : rel.requested ? R.string.following_user_requested : R.string.unfollowed_user, account.getDisplayUsername()), Toast.LENGTH_SHORT).show();
});
}else if(id==R.id.block_domain){
UiUtils.confirmToggleBlockDomain(activity, item.parentFragment.getAccountID(), account.getDomain(), relationship!=null && relationship.domainBlocking, ()->{});
UiUtils.confirmToggleBlockDomain(activity, item.parentFragment.getAccountID(), account, relationship!=null && relationship.domainBlocking, ()->{});
}else if(id==R.id.bookmark){
AccountSessionManager.getInstance().getAccount(item.accountID).getStatusInteractionController().setBookmarked(item.status, !item.status.bookmarked);
}else if(id==R.id.manage_user_lists){
@ -513,6 +528,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
menu.findItem(R.id.unmute_conversation).setVisible(item.status!=null && item.status.muted);
menu.findItem(R.id.open_in_browser).setVisible(!isPostScheduled && item.status!=null);
menu.findItem(R.id.copy_link).setVisible(!isPostScheduled && item.status!=null);
menu.findItem(R.id.bitepost_btn).setVisible(!isOwnPost && !isPostScheduled && item.status!=null);
MenuItem blockDomain=menu.findItem(R.id.block_domain);
MenuItem mute=menu.findItem(R.id.mute);
MenuItem block=menu.findItem(R.id.block);

View file

@ -75,6 +75,7 @@ public class NotificationHeaderStatusDisplayItem extends StatusDisplayItem{
case REPORT -> R.string.sk_reported;
case REACTION, PLEROMA_EMOJI_REACTION ->
!TextUtils.isEmpty(notification.emoji) ? R.string.sk_reacted_with : R.string.sk_reacted;
case BITE -> R.string.sk_bit_you;
default -> throw new IllegalStateException("Unexpected value: "+notification.type);
});
@ -170,6 +171,7 @@ public class NotificationHeaderStatusDisplayItem extends StatusDisplayItem{
case SIGN_UP -> R.drawable.ic_fluent_person_available_24_filled;
case UPDATE -> R.drawable.ic_fluent_edit_24_filled;
case REACTION, PLEROMA_EMOJI_REACTION -> R.drawable.ic_fluent_add_24_filled;
case BITE -> R.drawable.ic_fluent_animal_cat_24_regular;
default -> throw new IllegalStateException("Unexpected value: "+item.notification.type);
});
icon.setImageTintList(ColorStateList.valueOf(UiUtils.getThemeColor(item.parentFragment.getActivity(), switch(item.notification.type){

View file

@ -274,8 +274,10 @@ public abstract class StatusDisplayItem{
contentItems=items;
}
if(statusForContent.quote!=null){
if(statusForContent.quote!=null) {
int quoteInlineIndex=statusForContent.content.lastIndexOf("<span class=\"quote-inline\"><br/><br/>RE:");
if(quoteInlineIndex==-1)
quoteInlineIndex=statusForContent.content.lastIndexOf("<span class=\"quote-inline\"><br><br>RE:");
if(quoteInlineIndex!=-1)
statusForContent.content=statusForContent.content.substring(0, quoteInlineIndex);
else {
@ -341,7 +343,7 @@ public abstract class StatusDisplayItem{
if(!statusForContent.mediaAttachments.isEmpty() && statusForContent.poll==null) // add spacing if immediately preceded by attachment
contentItems.add(new DummyStatusDisplayItem(parentID, fragment));
contentItems.addAll(buildItems(fragment, statusForContent.quote, accountID, parentObject, knownAccounts, filterContext, FLAG_NO_FOOTER|FLAG_INSET|FLAG_NO_EMOJI_REACTIONS|FLAG_IS_FOR_QUOTE));
} else if((flags & FLAG_INSET)==0 && statusForContent.mediaAttachments.isEmpty()){
} else if((flags & FLAG_INSET)==0 && statusForContent.mediaAttachments.isEmpty() && statusForContent.account!=null){
tryAddNonOfficialQuote(statusForContent, fragment, accountID, filterContext);
}
if(contentItems!=items && statusForContent.spoilerRevealed){
@ -431,6 +433,7 @@ public abstract class StatusDisplayItem{
return;
String quoteURL=matcher.group();
// account may be null for scheduled posts
if (!UiUtils.looksLikeFediverseUrl(quoteURL))
return;

View file

@ -1,5 +1,6 @@
package org.joinmastodon.android.ui.sheets;
import android.app.AlertDialog;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.drawable.ColorDrawable;
@ -15,6 +16,7 @@ import android.widget.TextView;
import org.joinmastodon.android.R;
import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
import org.joinmastodon.android.ui.drawables.EmptyDrawable;
import org.joinmastodon.android.ui.utils.UiUtils;
import org.joinmastodon.android.ui.views.AutoOrientationLinearLayout;
@ -23,6 +25,11 @@ import org.joinmastodon.android.ui.views.ProgressBarButton;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import java.time.Duration;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import me.grishka.appkit.utils.V;
import me.grishka.appkit.views.BottomSheet;
@ -108,6 +115,51 @@ public abstract class AccountRestrictionConfirmationSheet extends BottomSheet{
addRow(icon, getContext().getString(text));
}
public void addDurationRow(@NonNull Context context, AtomicReference<Duration> muteDuration) {
//Moshidon: add row to choose a duration, e.g. for muting accounts
Button muteDurationBtn=new Button(getContext());
muteDurationBtn.setOnClickListener(v->getMuteDurationDialog(context, muteDuration, muteDurationBtn).show());
muteDurationBtn.setText(R.string.sk_duration_indefinite);
addRow(R.drawable.ic_fluent_clock_20_regular, R.string.sk_mute_label, muteDurationBtn);
}
@NonNull
private M3AlertDialogBuilder getMuteDurationDialog(@NonNull Context context, AtomicReference<Duration> muteDuration, Button button){
M3AlertDialogBuilder builder=new M3AlertDialogBuilder(context);
builder.setTitle(R.string.sk_mute_label);
builder.setIcon(R.drawable.ic_fluent_clock_20_regular);
List<Duration> durations =List.of(Duration.ZERO,
Duration.ofMinutes(5),
Duration.ofMinutes(30),
Duration.ofHours(1),
Duration.ofHours(6),
Duration.ofDays(1),
Duration.ofDays(3),
Duration.ofDays(7),
Duration.ofDays(7));
String[] choices = {context.getString(R.string.sk_duration_indefinite),
context.getString(R.string.sk_duration_minutes_5),
context.getString(R.string.sk_duration_minutes_30),
context.getString(R.string.sk_duration_hours_1),
context.getString(R.string.sk_duration_hours_6),
context.getString(R.string.sk_duration_days_1),
context.getString(R.string.sk_duration_days_3),
context.getString(R.string.sk_duration_days_7)};
builder.setSingleChoiceItems(choices, durations.indexOf(muteDuration.get()), (dialog, which) -> {});
builder.setPositiveButton(R.string.ok, (dialog, which)->{
int selected = ((AlertDialog) dialog).getListView().getCheckedItemPosition();
muteDuration.set(durations.get(selected));
button.setText(choices[selected]);
});
builder.setNegativeButton(R.string.cancel, null);
return builder;
}
public interface ConfirmCallback{
void onConfirmed(Runnable onSuccess, Runnable onError);
}

View file

@ -0,0 +1,36 @@
package org.joinmastodon.android.ui.sheets;
import android.content.Context;
import android.view.View;
import org.joinmastodon.android.R;
import org.joinmastodon.android.model.Account;
import androidx.annotation.NonNull;
public class BlockDomainConfirmationSheet extends AccountRestrictionConfirmationSheet{
public BlockDomainConfirmationSheet(@NonNull Context context, Account user, ConfirmCallback confirmCallback, ConfirmCallback blockUserConfirmCallback){
super(context, user, confirmCallback);
titleView.setText(R.string.block_domain_confirm_title);
confirmBtn.setText(R.string.do_block_server);
secondaryBtn.setText(context.getString(R.string.block_user_x_instead, user.getDisplayUsername()));
icon.setImageResource(R.drawable.ic_fluent_shield_24_regular);
subtitleView.setText(user.getDomain());
addRow(R.drawable.ic_campaign_24px, R.string.users_cant_see_blocked);
addRow(R.drawable.ic_fluent_eye_off_24_regular, R.string.you_wont_see_server_posts);
addRow(R.drawable.ic_fluent_person_delete_24_regular, R.string.server_followers_will_be_removed);
addRow(R.drawable.ic_fluent_arrow_reply_24_regular, R.string.server_cant_mention_or_follow_you);
addRow(R.drawable.ic_fluent_history_24_regular, R.string.server_can_interact_with_older);
secondaryBtn.setOnClickListener(v->{
if(loading)
return;
loading=true;
secondaryBtn.setProgressBarVisible(true);
blockUserConfirmCallback.onConfirmed(this::dismiss, ()->{
secondaryBtn.setProgressBarVisible(false);
loading=false;
});
});
}
}

View file

@ -1,19 +1,10 @@
package org.joinmastodon.android.ui.sheets;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Typeface;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.PopupMenu;
import android.widget.TextView;
import android.widget.Toast;
import org.joinmastodon.android.R;
import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
import org.joinmastodon.android.ui.views.M3Switch;
import java.time.Duration;
@ -44,59 +35,6 @@ public class MuteAccountConfirmationSheet extends AccountRestrictionConfirmation
addRow(R.drawable.ic_fluent_alert_off_24_regular, R.string.mo_mute_notifications, m3Switch);
// add mute duration (Moshidon)
secondaryBtn.setVisibility(View.VISIBLE);
secondaryBtn.setOnClickListener(v->getMuteDurationDialog(context, muteDuration, secondaryBtn).show());
secondaryBtn.setText(R.string.sk_duration_indefinite);
secondaryBtn.setTypeface(null, Typeface.BOLD_ITALIC);
addDurationRow(context, muteDuration);
}
@NonNull
private M3AlertDialogBuilder getMuteDurationDialog(@NonNull Context context, AtomicReference<Duration> muteDuration, Button button){
M3AlertDialogBuilder builder=new M3AlertDialogBuilder(context);
builder.setTitle(R.string.sk_mute_label);
builder.setIcon(R.drawable.ic_fluent_clock_20_regular);
String[] choices = {context.getString(R.string.sk_duration_indefinite),
context.getString(R.string.sk_duration_minutes_5),
context.getString(R.string.sk_duration_minutes_30),
context.getString(R.string.sk_duration_hours_1),
context.getString(R.string.sk_duration_hours_6),
context.getString(R.string.sk_duration_days_1),
context.getString(R.string.sk_duration_days_3),
context.getString(R.string.sk_duration_days_7)};
builder.setSingleChoiceItems(choices, 0, (dialog, which) -> {});
builder.setPositiveButton(R.string.ok, (dialog, which)->{
int selected = ((AlertDialog) dialog).getListView().getCheckedItemPosition();
if(selected==0){
muteDuration.set(Duration.ZERO);
}else if(selected==1){
muteDuration.set(Duration.ofMinutes(5));
}else if(selected==2){
muteDuration.set(Duration.ofMinutes(30));
}else if(selected==3){
muteDuration.set(Duration.ofHours(1));
}else if(selected==4){
muteDuration.set(Duration.ofHours(6));
}else if(selected==5){
muteDuration.set(Duration.ofDays(1));
}else if(selected==6){
muteDuration.set(Duration.ofDays(3));
}else if(selected==7){
muteDuration.set(Duration.ofDays(7));
}
if(selected >= 0 && selected <= 7){
button.setText(choices[selected]);
} else {
Toast.makeText(context, "" + selected, Toast.LENGTH_SHORT).show();
}
});
builder.setNegativeButton(R.string.cancel, ((dialogInterface, i) -> {}));
return builder;
}
}

View file

@ -0,0 +1,30 @@
package org.joinmastodon.android.ui.sheets;
import android.content.Context;
import android.view.View;
import androidx.annotation.NonNull;
import org.joinmastodon.android.R;
import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.Hashtag;
import java.time.Duration;
import java.util.concurrent.atomic.AtomicReference;
// MOSHIDON
public class MuteHashtagConfirmationSheet extends AccountRestrictionConfirmationSheet{
public MuteHashtagConfirmationSheet(@NonNull Context context, Account user, AtomicReference<Duration> muteDuration, Hashtag hashtag, ConfirmCallback confirmCallback){
super(context, user, confirmCallback);
titleView.setText(R.string.mo_mute_hashtag);
confirmBtn.setText(R.string.do_mute);
secondaryBtn.setVisibility(View.GONE);
icon.setImageResource(R.drawable.ic_fluent_speaker_off_24_regular);
subtitleView.setText("#"+hashtag.name);
addRow(R.drawable.ic_fluent_number_symbol_24_regular, R.string.mo_mute_hashtag_explanation_muted_home);
addRow(R.drawable.ic_fluent_eye_off_24_regular, R.string.mo_mute_hashtag_explanation_discreet);
addRow(R.drawable.ic_fluent_search_24_regular, R.string.mo_mute_hashtag_explanation_search);
addDurationRow(context, muteDuration);
}
}

View file

@ -140,7 +140,7 @@ public class HtmlParser{
String href=el.attr("href");
LinkSpan.Type linkType;
String text=el.text();
if(el.hasClass("hashtag") || text.startsWith("#")){
if(!TextUtils.isEmpty(text) && (el.hasClass("hashtag") || text.startsWith("#"))){
// MOSHIDON: we have slightly refactored this so that the hashtags properly work in akkoma
// TODO: upstream this
linkType=LinkSpan.Type.HASHTAG;

View file

@ -123,6 +123,7 @@ import org.joinmastodon.android.ui.Snackbar;
import org.joinmastodon.android.ui.sheets.AccountSwitcherSheet;
import org.joinmastodon.android.ui.sheets.BlockAccountConfirmationSheet;
import org.joinmastodon.android.ui.sheets.MuteAccountConfirmationSheet;
import org.joinmastodon.android.ui.sheets.BlockDomainConfirmationSheet;
import org.joinmastodon.android.ui.text.CustomEmojiSpan;
import org.joinmastodon.android.ui.text.HtmlParser;
import org.joinmastodon.android.utils.Tracking;
@ -574,27 +575,61 @@ public class UiUtils {
);
}
public static void confirmToggleBlockDomain(Activity activity, String accountID, String domain, boolean currentlyBlocked, Runnable resultCallback) {
showConfirmationAlert(activity, activity.getString(currentlyBlocked ? R.string.confirm_unblock_domain_title : R.string.confirm_block_domain_title),
activity.getString(currentlyBlocked ? R.string.confirm_unblock : R.string.confirm_block, domain),
activity.getString(currentlyBlocked ? R.string.do_unblock : R.string.do_block),
R.drawable.ic_fluent_shield_28_regular,
() -> {
new SetDomainBlocked(domain, !currentlyBlocked)
.setCallback(new Callback<>() {
@Override
public void onSuccess(Object result) {
resultCallback.run();
}
public static void confirmToggleBlockDomain(Activity activity, String accountID, Account account, boolean currentlyBlocked, Runnable resultCallback){
if(!currentlyBlocked){
new BlockDomainConfirmationSheet(activity, account, (onSuccess, onError)->{
new SetDomainBlocked(account.getDomain(), true)
.setCallback(new Callback<>(){
@Override
public void onSuccess(Object result){
resultCallback.run();
onSuccess.run();
}
@Override
public void onError(ErrorResponse error) {
error.showToast(activity);
}
})
.wrapProgress(activity, R.string.loading, false)
.exec(accountID);
});
@Override
public void onError(ErrorResponse error){
error.showToast(activity);
onError.run();
}
})
.exec(accountID);
}, (onSuccess, onError)->{
new SetAccountBlocked(account.id, true)
.setCallback(new Callback<>(){
@Override
public void onSuccess(Relationship result){
resultCallback.run();
onSuccess.run();
E.post(new RemoveAccountPostsEvent(accountID, account.id, false));
}
@Override
public void onError(ErrorResponse error){
error.showToast(activity);
onError.run();
}
})
.exec(accountID);
}).show();
}else{
new SetDomainBlocked(account.getDomain(), false)
.setCallback(new Callback<>(){
@Override
public void onSuccess(Object result){
resultCallback.run();
new Snackbar.Builder(activity)
.setText(activity.getString(R.string.unblocked_domain_x, account.getDomain()))
.show();
}
@Override
public void onError(ErrorResponse error){
error.showToast(activity);
}
})
.wrapProgress(activity, R.string.loading, false)
.exec(accountID);
}
}
public static void confirmToggleMuteUser(Context context, String accountID, Account account, boolean currentlyMuted, Consumer<Relationship> resultCallback){
if(!currentlyMuted){
@ -1183,6 +1218,10 @@ public class UiUtils {
return false;
}
// Akkoma somehow makes this necessary, because youtube links look like posts. And because it may trigger too many requests.
if (uri.getHost().toLowerCase().contains("youtube.com") || uri.getHost().toLowerCase().contains("youtu.be"))
return false;
if (uri.getQuery() != null || uri.getFragment() != null || uri.getPath() == null)
return false;

View file

@ -3,7 +3,6 @@ package org.joinmastodon.android.ui.viewholders;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.os.Build;
@ -25,6 +24,7 @@ import android.widget.TextView;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.accounts.BiteAccount;
import org.joinmastodon.android.api.requests.accounts.SetAccountFollowed;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.fragments.AddAccountToListsFragment;
@ -66,6 +66,7 @@ public class AccountViewHolder extends BindableViewHolder<AccountViewModel> impl
private final View checkbox;
private final ProgressBar actionProgress;
private final ImageButton menuButton;
private final ImageButton biteUserButton;
private final String accountID;
private final Fragment fragment;
@ -102,6 +103,7 @@ public class AccountViewHolder extends BindableViewHolder<AccountViewModel> impl
checkbox=findViewById(R.id.checkbox);
actionProgress=findViewById(R.id.action_progress);
menuButton=findViewById(R.id.options_btn);
biteUserButton=findViewById(R.id.biteuser_btn);
avatar.setOutlineProvider(OutlineProviders.roundedRect(10));
avatar.setClipToOutline(true);
@ -112,7 +114,7 @@ public class AccountViewHolder extends BindableViewHolder<AccountViewModel> impl
contextMenu=new PopupMenu(fragment.getActivity(), menuAnchor);
contextMenu.inflate(R.menu.profile);
contextMenu.setOnMenuItemClickListener(this::onContextMenuItemSelected);
menuButton.setOnClickListener(v->showMenuFromButton());
menuButton.setOnClickListener(v -> showMenuFromButton());
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.P && !UiUtils.isEMUI() && !UiUtils.isMagic())
contextMenu.getMenu().setGroupDividerEnabled(true);
UiUtils.enablePopupMenuIcons(fragment.getContext(), contextMenu);
@ -312,7 +314,7 @@ public class AccountViewHolder extends BindableViewHolder<AccountViewModel> impl
}else if(id==R.id.open_in_browser){
UiUtils.launchWebBrowser(fragment.getActivity(), account.url);
}else if(id==R.id.block_domain){
UiUtils.confirmToggleBlockDomain(fragment.getActivity(), accountID, account.getDomain(), relationship.domainBlocking, ()->{
UiUtils.confirmToggleBlockDomain(fragment.getActivity(), accountID, account, relationship.domainBlocking, ()->{
relationship.domainBlocking=!relationship.domainBlocking;
bindRelationship();
});

View file

@ -0,0 +1,34 @@
package org.joinmastodon.android.ui.views;
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
public class EmojiReactionButton extends ProgressBarButton {
private final Handler handler=new Handler();
public EmojiReactionButton(Context context){
super(context);
}
public EmojiReactionButton(Context context, AttributeSet attrs){
super(context, attrs);
}
public EmojiReactionButton(Context context, AttributeSet attrs, int defStyleAttr){
super(context, attrs, defStyleAttr);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// allow long click even if button is disabled
int action=event.getAction();
if(action==MotionEvent.ACTION_DOWN && !isEnabled())
handler.postDelayed(this::performLongClick, ViewConfiguration.getLongPressTimeout());
if(action==MotionEvent.ACTION_UP)
handler.removeCallbacksAndMessages(null);
return super.onTouchEvent(event);
}
}

View file

@ -0,0 +1,51 @@
package org.joinmastodon.android.utils;
import android.content.Context;
import androidx.annotation.NonNull;
import org.joinmastodon.android.api.session.AccountSession;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.unifiedpush.android.connector.UnifiedPush;
public class UnifiedPushHelper {
/**
* @param context
* @return `true` if UnifiedPush is used
*/
public static boolean isUnifiedPushEnabled(@NonNull Context context) {
return UnifiedPush.getAckDistributor(context) != null;
}
/**
* If any distributor is installed on the device
* @param context
* @return `true` if at least one is installed
*/
public static boolean hasAnyDistributorInstalled(@NonNull Context context) {
return !UnifiedPush.getDistributors(context).isEmpty();
}
public static void registerAllAccounts(@NonNull Context context) {
for (AccountSession accountSession : AccountSessionManager.getInstance().getLoggedInAccounts()){
UnifiedPush.register(
context,
accountSession.getID(),
null,
accountSession.app.vapidKey.replaceAll("=","")
);
}
}
public static void unregisterAllAccounts(@NonNull Context context) {
for (AccountSession accountSession : AccountSessionManager.getInstance().getLoggedInAccounts()){
UnifiedPush.unregister(
context,
accountSession.getID()
);
// use FCM again
accountSession.getPushSubscriptionManager().registerAccountForPush(null);
}
}
}

View file

@ -567,6 +567,7 @@
android:layout_marginEnd="16dp"
android:textAppearance="@style/m3_label_large"
android:textColor="?colorM3OnSurface"
android:visibility="gone"
tools:text="500"/>
<ImageButton

View file

@ -15,7 +15,7 @@
android:indeterminate="true"
android:outlineProvider="none"
android:visibility="gone"/>
<org.joinmastodon.android.ui.views.ProgressBarButton
<org.joinmastodon.android.ui.views.EmojiReactionButton
android:id="@+id/btn"
style="@style/Widget.Mastodon.M3.Button.Outlined.Icon"
android:layout_width="wrap_content"

View file

@ -8,6 +8,7 @@
<item android:id="@+id/unpin" android:title="@string/sk_unpin_post" android:icon="@drawable/ic_fluent_pin_off_24_regular"/>
</group>
<group android:id="@+id/menu_group2">
<item android:id="@+id/bitepost_btn" android:title="@string/sk_bite_post" android:icon="@drawable/ic_fluent_animal_cat_24_regular"/>
<item android:id="@+id/manage_user_lists" android:title="@string/add_user_to_list" android:icon="@drawable/ic_fluent_people_24_regular"/>
<item android:id="@+id/follow" android:title="@string/follow_user" android:icon="@drawable/ic_fluent_person_add_24_regular"/>
<item android:id="@+id/mute" android:title="@string/mute_user" android:icon="@drawable/ic_fluent_speaker_off_24_regular"/>

View file

@ -2,6 +2,7 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:id="@+id/menu_group1">
<item android:id="@+id/edit_note" android:title="@string/sk_add_note" android:icon="@drawable/ic_fluent_notepad_24_regular" android:showAsAction="ifRoom" />
<item android:id="@+id/biteuser_btn" android:title="@string/sk_bite_user" android:icon="@drawable/ic_fluent_animal_cat_24_regular" android:showAsAction="ifRoom" />
</group>
<group android:id="@+id/menu_group2">
<item android:id="@+id/manage_user_lists" android:title="@string/add_user_to_list" android:icon="@drawable/ic_fluent_people_24_regular"/>

View file

@ -94,4 +94,15 @@
<string name="mo_swap_bookmark_with_reblog">استبدال إجراء الإضافة إلى الفواصل المرجعية بإعادة النشر</string>
<string name="mo_setting_haptic_feedback_summary">اهتز عند التفاعل مع المنشورات</string>
<string name="mo_notification_filter_reset">إعادة التعيين إلى الإفتراضية</string>
<string name="mo_instance_view_info">إظهار معلومات الخادم</string>
<string name="mo_settings_remove_tracking_params">روابط ذات خصوصية</string>
<string name="mo_personal_note_saved">تم حفظ الملاحظة</string>
<string name="mo_settings_unifiedpush_enable">تمكين</string>
<string name="import_settings_failed">فشل في استيراد الإعدادات</string>
<string name="export_settings_share">تصدير الإعدادات</string>
<string name="export_settings_fail">فشل في تصدير الإعدادات</string>
<string name="export_settings_title">تصدير الإعدادات</string>
<string name="import_settings_title">استيراد الإعدادات</string>
<string name="mo_error_display_copy_error_details">نسخ التفاصيل</string>
<string name="mo_trending_link_read">قراءة</string>
</resources>

View file

@ -170,4 +170,23 @@
<string name="sk_icon_microscope">مجهر</string>
<string name="sk_delete_notification_confirm_action">احذف الإشعار</string>
<string name="sk_notification_mention">أشار إليك %s</string>
<string name="sk_settings_show_interaction_counts">إظهار عدد التفاعلات</string>
<string name="sk_timeline_bubble">فقاعة</string>
<string name="sk_do_remove_follower">حذف</string>
<string name="sk_remove">حذف</string>
<string name="sk_icon_bot">آلي</string>
<string name="sk_icon_location">الموضع</string>
<string name="sk_icon_laugh">ضحك</string>
<string name="sk_icon_code">شفرة</string>
<string name="sk_icon_bug">حشرة</string>
<string name="sk_icon_pizza">بيتزا</string>
<string name="sk_icon_gavel">مطرقة</string>
<string name="sk_icon_feed">موجز حي</string>
<string name="sk_icon_diamond">ألماس</string>
<string name="sk_icon_umbrella">مطارية</string>
<string name="sk_icon_water">ماء</string>
<string name="sk_icon_sun">شمس</string>
<string name="sk_icon_sunset">شروق الشمس</string>
<string name="sk_icon_cloud">سحاب</string>
<string name="sk_icon_rain">مطر</string>
</resources>

View file

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="mo_hide_compose_button_while_scrolling_setting">Ancultar el botón d\'escritura mientres te desplaces</string>
<string name="mo_settings_contribute">Contribuyir a Moshidon</string>
<string name="mo_instance_status">Estáu</string>
<string name="mo_mute_label">Duración:</string>
<string name="mo_share_open_url">Abrir na aplicación</string>
<string name="mo_duration_hours_6">6 hores</string>
<string name="mo_instance_users">Usuarios</string>
<string name="mo_setting_uniform_summary">Usar l\'iconu de la aplicación pa toles notificaciones</string>
<string name="mo_settings_show_posts_without_alt">Amosar artículos con multimedia que-yos falta\'l testu alternativu</string>
<string name="mo_settings_unifiedpush_warning_disabled">UnifiedPush nun ta habilitáu. Nun vas recibir nenguna notificación.</string>
<string name="mo_trending_link_read">Leer</string>
<string name="mo_settings_show_posts_without_alt_summary">Los artículos tarán ancultos en toles cronoloxíes, pero puen amosase nos filos y los avisos</string>
<string name="mo_color_palette_nord">Nord</string>
<string name="mo_color_palette_black_and_white">Blancu y Negru</string>
<string name="mo_enable_dividers">Amosar divisores ente artículos</string>
<string name="mo_relocate_publish_button">Mover el botón d\'espublizar</string>
<string name="mo_welcome_text">Pa entamar, introduz el nome del dominiu de la to instancia embaxo, por favor.</string>
<string name="mo_personal_note">Amestar una nota sobre esti perfil</string>
<string name="mo_personal_note_saved">Nota guardada</string>
<string name="mo_personal_note_confirm">Confirmar los cambeos a la nota</string>
<string name="mo_update_available">Moshidon %s ta llistu pa descargar.</string>
<string name="mo_update_ready">Moshidon %s ta descargáu y llistu pa instalar.</string>
<string name="mo_no_image_desc_title">Ensin descripción de la semeya</string>
<string name="mo_disable_reminder_to_add_alt_text">Desactivar el recordatoriu pa amestar el testu alternativu</string>
<string name="mo_personal_note_update_failed">Fallu al guardar la nota</string>
<string name="mo_emoji_recent">Recién usaos</string>
<string name="mo_open_camera">Facer una semeya</string>
<string name="mo_camera_not_available">Nun hai una cámara disponible!</string>
<string name="mo_poll_option_add">Amestar una nueva opción a la encuesta</string>
<string name="mo_fab_compose">Redactar</string>
<string name="mo_sending_error">Erru espublizando</string>
<string name="mo_duration_indefinite">Indefiníu</string>
<string name="mo_duration_minutes_5">5 minutos</string>
<string name="mo_duration_minutes_30">30 minutos</string>
<string name="mo_duration_hours_1">1 hora</string>
<string name="mo_duration_days_1">1 día</string>
<string name="mo_duration_days_3">3 díes</string>
<string name="mo_duration_days_7">7 díes</string>
<string name="mo_instance_view_info">Ver versión del servidor</string>
<string name="mo_instance_admin">Alministráu por</string>
<string name="mo_instance_contact">Contautu</string>
<string name="mo_instance_registration">Rexistru</string>
<string name="mo_instance_registration_open">Abiertu</string>
<string name="mo_instance_registration_approval">Requier aprobación</string>
<string name="mo_instance_info_open_timeline">Cronoloxía llocal</string>
<string name="mo_instance_info_moderated_servers">Servidores moderaos</string>
<string name="mo_severity_suspend">Bloquiáu</string>
<string name="mo_setting_true_black_summary">Podría aforrar enerxía en pantalles AMOLED</string>
<string name="mo_setting_remote_follower_summary">Amosar siguidores dende otres instancies</string>
<string name="mo_setting_relocate_publish_summary">Mover el botón d\'espublizar a la barra inferior</string>
<string name="mo_setting_interaction_count_summary">Amosar cuánta xente interactuó con un artículu na cronoloxía</string>
<string name="mo_setting_disable_swipe_summary">Eslizar pa camudar de cronoloxía</string>
<string name="mo_swap_bookmark_with_reblog_summary">Meter en marcadores o impulsar artículos dende l\'avisu</string>
<string name="mo_setting_haptic_feedback_summary">Vibrar cuando interactues colos artículos</string>
<string name="mo_double_tap_to_swipe_between_tabs">Doble toque pa camudar ente pestañes</string>
<string name="mo_haptic_feedback">Respuesta táctil</string>
<string name="mo_show_media_preview">Amosar previsualización multimedia nes cronoloxíes</string>
<string name="mo_settings_unifiedpush_warning">UnifiedPush nun ta habilitáu</string>
<string name="mo_confirm_unfollow_title">Dexar de siguir</string>
<string name="mo_confirm_unfollow">Confirma pa dexar de siguir a %s</string>
<string name="mo_settings_unifiedpush_enable">Habilitar</string>
<string name="mo_blocked_accounts">Cuentes bloquiaes</string>
<string name="mo_settings_remove_tracking_params">Enllaces privaos</string>
<string name="mo_add_custom_server_local_timeline">Amestar la cronoloxía llocal d\'otru sirvidor</string>
<string name="mo_notification_action_replied">Respondisti al artículu de %s</string>
<string name="mo_change_default_reply_visibility_to_unlisted">Responder como \'Non llistáu\' por defeutu</string>
<string name="mo_notification_management_settings">Xestionar avisos</string>
<string name="mo_composer_behavior">Comportamientu del editor</string>
<string name="mo_load_remote_followers">Cargar los siguíos y siguidores del perfil remotu</string>
<string name="export_settings_title">Esportar axustes</string>
<string name="import_settings_title">Importar axustes</string>
<string name="mo_error_display_title">Nun se pudo amosar l\'artículu</string>
<string name="mo_error_display_copy_error_details">Copiar detalles</string>
<string name="import_settings_confirm">¿Confirmes la importación de los axustes?</string>
<string name="export_settings_share">Esportar Axustes</string>
<string name="export_settings_fail">Nun se pudieron esportar los axustes</string>
<string name="import_settings_failed">Nun se pudieron importar los axustes</string>
</resources>

View file

@ -0,0 +1,336 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="sk_icon_weather">Tiempu</string>
<string name="sk_settings_allow_remote_loading">Cargando información dende instancies remotes</string>
<string name="sk_exclusive_list">Llista escluyente</string>
<string name="sk_icon_bicycle">Bicicleta</string>
<string name="sk_save_draft">¿Guardar el borrador?</string>
<string name="sk_settings_default_content_type">Tipu de conteníu per defeutu</string>
<string name="sk_search_fediverse">Buscar nel Fediversu</string>
<string name="sk_settings_display_pronouns_in_user_listings">Amosar los pronomes nos llistaos d\'usuarios</string>
<string name="sk_edit_alt_text">Editar el testu alternativu</string>
<string name="sk_hashtag_timeline_local_only_switch">¿Amosar namás los artículos llocales?</string>
<string name="sk_follow_as">Siguir dende otra cuenta</string>
<string name="sk_content_type_markdown">Markdown</string>
<plurals name="sk_posts_count_label">
<item quantity="one">artículu</item>
<item quantity="other">artículos</item>
</plurals>
<string name="sk_timeline_home">Aniciu</string>
<string name="sk_settings_show_labels_in_navigation_bar">Amosar etiquetes de pestañes na barra de navegación</string>
<plurals name="sk_time_minutes">
<item quantity="one">%d minutu</item>
<item quantity="other">%d minutos</item>
</plurals>
<string name="sk_poll_show_results">Amosar resultaos</string>
<string name="sk_announcements">Anuncios</string>
<string name="sk_your_lists">Les tos llistes</string>
<string name="sk_confirm_unpin_post">¿De xuru que quies desapegar esti artículu?</string>
<string name="sk_create">Crear</string>
<string name="sk_pinned_posts">Fixáu</string>
<string name="sk_delete_and_redraft">Desaniciar y reeditar</string>
<string name="sk_confirm_delete_and_redraft_title">Desaniciar y reeditar artículu</string>
<string name="sk_pinning">Fixando l\'artículu…</string>
<string name="sk_image_description">Descripción de la semeya</string>
<string name="sk_settings_show_replies">Amosar respuestes</string>
<string name="sk_quoting_user">Mentando %s</string>
<string name="sk_settings_reply_visibility">Visibilidá de la respuesta</string>
<string name="sk_settings_reply_visibility_all">Toles respuestes</string>
<string name="sk_settings_reply_visibility_self">Respuestes pa mi</string>
<string name="sk_settings_load_new_posts">Cargar artículos nuevos automáticamente</string>
<string name="sk_settings_show_interaction_counts">Amosar la cuenta d\'interaiciones</string>
<string name="sk_settings_app_version">Megalodon v%1$s (%2$d)</string>
<string name="sk_visibility_unlisted">Non llistáu</string>
<string name="sk_settings_show_boosts">Amosar impulsos</string>
<string name="sk_unpin_post">Desapegar del perfil</string>
<string name="sk_confirm_unpin_post_title">Desapegar artículu del perfil</string>
<string name="sk_unpinning">Desapegando artículu…</string>
<string name="sk_settings_continues_playback">Superposición d\'audiu</string>
<string name="sk_user_post_notifications_on">Activaes les notificaciones d\'artículos pa %s</string>
<string name="sk_user_post_notifications_off">Desactivaes les notificaciones d\'artículos pa %s</string>
<string name="sk_federated_timeline">Federación</string>
<string name="sk_trending_posts_info_banner">Estos artículos tan ganando tracción nel Fediversu.</string>
<string name="sk_update_available">Megalodon %s ta llistu pa descargar.</string>
<string name="sk_update_ready">Megalodon %s ta descargáu y llistu pa instalar.</string>
<string name="sk_check_for_update">Buscar actualizaciones</string>
<string name="sk_no_update_available">Nun hai actualizaciones disponibles</string>
<string name="sk_accept_follow_request">Aceptar solicitúes de siguimientu</string>
<string name="sk_reject_follow_request">Refugar solicitúes de siguimientu</string>
<string name="sk_lists_with_user">Llistes con %s</string>
<string name="sk_list_timelines">Llistes</string>
<string name="sk_follow_requests">Solicitúes de siguimientu</string>
<string name="sk_notification_type_status">Artículos</string>
<string name="sk_notification_type_posts">Avisos d\'artículos</string>
<string name="sk_settings_color_palette">Paleta de color</string>
<string name="sk_settings_show_federated_timeline">Amosar la llínea del tiempu federada</string>
<string name="sk_color_palette_material3">Sistema</string>
<string name="sk_color_palette_pink">Rosa</string>
<string name="sk_color_palette_purple">Morao</string>
<string name="sk_color_palette_brown">Marrón</string>
<string name="sk_color_palette_red">Coloráu</string>
<string name="sk_color_palette_yellow">Mariellu</string>
<string name="sk_translate_post">Traducir</string>
<string name="sk_translate_show_original">Amosar l\'orixinal</string>
<string name="sk_post_language">Idioma: %s</string>
<string name="sk_language_name">%1$s (%2$s)</string>
<string name="sk_clear_recent_languages">Desaniciar llingües usaes apocayá</string>
<string name="sk_welcome_title">¡Bienveníu!</string>
<string name="sk_welcome_text">¡El tiburón te saluda! Pa entamar, introduz el nome del dominiu de la to instancia embaxo.</string>
<string name="sk_example_domain">exemplu.social</string>
<string name="sk_settings_posting">Preferencies d\'espublizamientu</string>
<string name="sk_settings_filters">Configurar filtros</string>
<string name="sk_settings_auth">Configuraciones de seguridá</string>
<string name="sk_settings_rules">Regles</string>
<string name="sk_settings_profile">Configurar el perfil</string>
<string name="sk_delete_notification_confirm_action">Desaniciar l\'avisu</string>
<string name="sk_settings_donate">Donar</string>
<string name="sk_settings_translation_availability_note_available">¡%s almite traducción!</string>
<string name="sk_settings_translation_availability_note_unavailable">%s paez que nun almite traducción.</string>
<string name="sk_undo_reblog">Desfaer impulsu</string>
<string name="sk_clear_all_notifications">Desaniciar tolos avisos</string>
<string name="sk_clear_all_notifications_confirm">¿De xuru que quies desaniciar tolos avisos?</string>
<string name="sk_loading_fediverse_resource_title">Buscando nel Fediversu</string>
<string name="sk_loading_resource_on_instance_title">Buscando en %s</string>
<string name="sk_settings_publish_button_text_title">Personalizar el testu del botón d\'Espublizar</string>
<string name="sk_reblog_with_visibility">Impulsa con visibilidá</string>
<string name="sk_hashtags_you_follow">Etiquetes que sigues</string>
<string name="sk_copy_link_to_post">Copiar l\'enllaz al artículu</string>
<string name="sk_open_with_account">Abrir con otra cuenta</string>
<string name="sk_resource_not_found">Nun pudo atopase el recursu</string>
<string name="sk_quote_post">Espublizar sobre esto</string>
<string name="sk_bookmark_as">Meter en marcadores con otra cuenta</string>
<string name="sk_reblogged_as">Impulsáu como %s</string>
<string name="sk_already_reblogged">Yá impulsáu</string>
<string name="sk_reply_as">Responder con otra cuenta</string>
<string name="sk_unsent_posts">Artículos non espublizáos</string>
<string name="sk_draft">Borrador</string>
<string name="sk_schedule">Programar</string>
<string name="sk_confirm_delete_draft_title">Desaniciar borrador</string>
<string name="sk_confirm_delete_draft">¿De xuru que quies desaniciar esti borrador?</string>
<string name="sk_confirm_delete_scheduled_post">¿De xuru que quies desaniciar esti artículu programáu?</string>
<string name="sk_draft_or_schedule">Borrador o programar</string>
<string name="sk_compose_scheduled">Programáu para</string>
<string name="sk_draft_saved">Borrador guardáu</string>
<string name="sk_post_scheduled">Artículu programáu</string>
<string name="sk_confirm_save_draft">¿Guardar el borrador?</string>
<string name="sk_confirm_save_changes">¿Guardar cambeos?</string>
<string name="sk_mark_as_draft">Marcar como borrador</string>
<string name="sk_mark_as_read">Marcar como lleíu</string>
<string name="sk_settings_single_notification">Amosar namás un avisu</string>
<string name="sk_settings_unifiedpush">Usar UnifiedPush</string>
<string name="sk_create_list_title">Crear llista</string>
<string name="sk_list_name_hint">Nome de la llista</string>
<string name="sk_list_replies_policy_list">miembros de la llista</string>
<string name="sk_list_replies_policy_followed">usuarios siguíos</string>
<string name="sk_list_replies_policy_none">nengunu</string>
<string name="sk_delete_list">Desaniciar llista</string>
<string name="sk_delete_list_confirm">¿De xuru que quies desaniciar la llista “%s”?</string>
<string name="sk_edit_list_title">Editar llista</string>
<string name="sk_timeline_local">Llocal</string>
<string name="sk_timeline_federated">Federada</string>
<string name="sk_timeline_bubble">Burbuya</string>
<string name="sk_recent_searches_placeholder">Escribe pa entamar a buscar</string>
<string name="sk_do_remove_follower">Desaniciar</string>
<string name="sk_remove_follower_success">Siguidor desaniciáu con ésitu</string>
<string name="sk_changelog">Llista de cambeos</string>
<string name="sk_alt_text_missing_title">Falta\'l testu alternativu</string>
<string name="sk_alt_text_missing">A lo menos falta-y la descripción a un archivu axuntu.</string>
<string name="sk_publish_anyway">Espublizar de toes formes</string>
<string name="sk_settings_disable_alt_text_reminder">Desactivar el recordatoriu pa amestar el testu alternativu</string>
<string name="sk_timelines">Cronoloxíes</string>
<string name="sk_timeline_posts">Artículos</string>
<string name="sk_list">Llista</string>
<string name="sk_pin_timeline">Fixar cronoloxía</string>
<string name="sk_remove">Desaniciar</string>
<string name="sk_timeline_icon">Iconu</string>
<string name="sk_icon_heart">Corazón</string>
<string name="sk_icon_star">Estrella</string>
<string name="sk_icon_city">Ciudá</string>
<string name="sk_icon_cat">Gatu</string>
<string name="sk_icon_dog">Perru</string>
<string name="sk_icon_rabbit">Conexu</string>
<string name="sk_icon_turtle">Tortuga</string>
<string name="sk_icon_balloon">Globu</string>
<string name="sk_icon_bot">Robó</string>
<string name="sk_icon_language">Llingüa</string>
<string name="sk_icon_megaphone">Megáfonu</string>
<string name="sk_icon_microphone">Micrófonu</string>
<string name="sk_icon_microscope">Microscopiu</string>
<string name="sk_icon_keyboard">Tecláu</string>
<string name="sk_icon_location">Llocalización</string>
<string name="sk_icon_news">Noticies</string>
<string name="sk_icon_tag">Etiqueta</string>
<string name="sk_icon_games">Xuegos</string>
<string name="sk_icon_light_bulb">Bombilla</string>
<string name="sk_icon_train">Tren</string>
<string name="sk_icon_leaves">Fueyes</string>
<string name="sk_icon_sport">Deporte</string>
<string name="sk_icon_music">Música</string>
<string name="sk_icon_people">Xente</string>
<string name="sk_icon_health">Salú</string>
<string name="sk_icon_important">Importante</string>
<string name="sk_icon_shield">Escudu</string>
<string name="sk_icon_book">Llibru</string>
<string name="sk_icon_code">Códigu</string>
<string name="sk_icon_map">Mapa</string>
<string name="sk_icon_backpack">Mochila</string>
<string name="sk_icon_fire">Fueu</string>
<string name="sk_icon_bug">Bichu</string>
<string name="sk_icon_pizza">Pizza</string>
<string name="sk_icon_gavel">Mazu</string>
<string name="sk_icon_verified">Verificáu</string>
<string name="sk_icon_water">Agua</string>
<string name="sk_icon_sun">Sol</string>
<string name="sk_icon_cloud">Nube</string>
<string name="sk_icon_thunderstorm">Tormenta</string>
<string name="sk_icon_rain">Lluvia</string>
<string name="sk_add_timeline_tag_error_empty">L\'etiqueta nun pue tar vacía</string>
<string name="sk_icon_human">Persona</string>
<string name="sk_icon_globe">Planeta</string>
<string name="sk_icon_bed">Cama</string>
<string name="sk_icon_diamond">Diamante</string>
<string name="sk_icon_umbrella">Paragües</string>
<string name="sk_edit_timeline">Editar cronoloxía</string>
<string name="sk_add_timeline">Amestar cronoloxía</string>
<string name="sk_edit_timelines">Editar cronoloxíes</string>
<string name="sk_edit_timeline_tag_any">...o dalguna d\'estes</string>
<string name="sk_edit_timeline_tag_all">...y toes estes</string>
<string name="sk_edit_timeline_tag_none">...pero nenguna d\'estes</string>
<string name="sk_edit_timeline_tag_hint">Introduz l\'etiqueta…</string>
<string name="sk_edit_timeline_tags_hint">Introduz les etiquetes…</string>
<string name="sk_alt_button">ALT</string>
<string name="sk_gif_badge">GIF</string>
<string name="sk_posted">%s espublizáu</string>
<string name="sk_post_edited">editáu</string>
<string name="sk_notification_type_update">Artículos editáos</string>
<string name="sk_notify_update">Editáu un artículu impulsáu</string>
<string name="sk_attach_file">Axuntar ficheru</string>
<string name="sk_searching">Buscando…</string>
<string name="sk_no_results">Ensin resultaos</string>
<string name="sk_no_alt_text">Nun hai testu alternativu disponible</string>
<string name="sk_settings_see_new_posts_button">Botón “Ver artículos nuevos”</string>
<string name="sk_separator">·</string>
<string name="sk_local_only">Namás l\'instancia llocal</string>
<string name="sk_settings_support_local_only">El servidor namás almite espublizar llocalmente</string>
<string name="sk_settings_show_alt_indicator">Indicador pa los testos alternativos</string>
<string name="sk_inline_local_only">Namás llocal</string>
<string name="sk_instance_features">Carauterístiques de l\'instancia</string>
<string name="sk_signed_up">rexistráu</string>
<string name="sk_reported">denunciáu</string>
<string name="sk_reacted_with">%1$s reaccionó con %2$s</string>
<string name="sk_reacted">%s reaccionó</string>
<string name="sk_settings_server_version">Versión de servidor: %s</string>
<string name="sk_notify_poll_results">Resultáos de la encuesta</string>
<string name="sk_sign_ups">Rexistru d\'usuarios</string>
<string name="sk_new_reports">Denuncies nueves</string>
<string name="sk_expand">Espandir</string>
<string name="sk_collapse">Encoyer</string>
<string name="sk_settings_collapse_long_posts">Encoyer artículos mui llargos</string>
<string name="sk_unfinished_attachments">Subiendo los archivos axuntos</string>
<string name="sk_unfinished_attachments_message">Dalgunos archivos axuntos nun acabaron de xubir.</string>
<string name="sk_settings_hide_interaction">Ancultar botones d\'interaición</string>
<string name="sk_followed_as">Siguíu dende %s</string>
<string name="sk_show_thread">Amosar filu</string>
<string name="sk_content_type">Tipu de conteníu</string>
<string name="sk_content_type_unspecified">Ensin especificar</string>
<string name="sk_content_type_plain">Testu planu</string>
<string name="sk_content_type_html">HTML</string>
<string name="sk_content_type_bbcode">BBCode</string>
<string name="sk_content_type_mfm">MFM</string>
<string name="sk_notification_action_replied">Respuesta unviada a %s</string>
<string name="sk_in_reply">En respuesta</string>
<string name="sk_settings_confirm_before_reblog">Confirma antes d\'impulsar</string>
<string name="sk_instance_info_unavailable">L\'información de la instancia nun ta disponible temporalmente</string>
<string name="sk_open_in_app">Abrir na aplicación</string>
<string name="sk_open_in_app_failed">Nun se pudo abrir na aplicación</string>
<string name="sk_settings_auto_reveal_nobody">Nunca</string>
<string name="sk_settings_auto_reveal_author">Respuestes del mesmu autor</string>
<string name="sk_settings_auto_reveal_anyone">Respuestes de toos</string>
<string name="sk_settings_prefix_replies_never">Nunca</string>
<string name="sk_advanced_options_show">Amosar opciones avanzaes</string>
<string name="sk_advanced_options_hide">Ancultar opciones avanzaes</string>
<string name="sk_spoiler_show">Amosar el conteníu</string>
<string name="sk_pronouns_label">Pronomes</string>
<string name="sk_settings_instance">Instancia</string>
<string name="sk_settings_display_pronouns_in_timelines">Amosar los pronomes nes cronoloxíes</string>
<string name="sk_settings_display_pronouns_in_threads">Amosar los pronomes nos filos</string>
<string name="sk_list_exclusive_switch">Facer que la llista seya esclusiva</string>
<string name="sk_switch_timeline">Camudar cronoloxía</string>
<string name="sk_tab_home">Aniciu</string>
<string name="sk_tab_notifications">Avisos</string>
<string name="sk_tab_profile">Perfil</string>
<string name="sk_settings_show_emoji_reactions_only_opened">Namás cuando s\'abre l\'artículu</string>
<plurals name="sk_users_reacted_with">
<item quantity="one">Un usuariu reaccionó con %2$s</item>
<item quantity="other">%1$,d usuarios reaccionaron con %2$s</item>
</plurals>
<string name="sk_duration_indefinite">Indefiníu</string>
<string name="sk_duration_minutes_5">5 minutos</string>
<string name="sk_duration_minutes_30">30 minutos</string>
<string name="sk_duration_hours_1">1 hora</string>
<string name="sk_duration_hours_6">6 hores</string>
<string name="sk_duration_days_1">1 día</string>
<string name="sk_duration_days_3">3 díes</string>
<string name="sk_duration_days_7">7 díes</string>
<string name="sk_suicide_search_terms">Suicidiu</string>
<string name="sk_tab_search">Busca</string>
<string name="sk_mute_label">Duración</string>
<string name="sk_load_missing_posts_above">Cargar artículos nuevos</string>
<string name="sk_load_missing_posts_below">Cargar artículos vieyos</string>
<plurals name="sk_time_seconds">
<item quantity="one">%d segundu</item>
<item quantity="other">%d segundos</item>
</plurals>
<plurals name="sk_time_hours">
<item quantity="one">%d hora</item>
<item quantity="other">%d hores</item>
</plurals>
<plurals name="sk_time_days">
<item quantity="one">%d día</item>
<item quantity="other">%d díes</item>
</plurals>
<string name="sk_blocked_accounts">Cuentes bloquiaes</string>
<string name="sk_post_contains_media">L\'artículu contien conteníu multimedia</string>
<string name="sk_poll_hide_results">Ancultar resultaos</string>
<string name="sk_open_post_preview">Vista previa del artículu</string>
<string name="sk_post_preview">Vista previa</string>
<string name="sk_app_name">Megalodon</string>
<string name="sk_confirm_delete_and_redraft">¿De xuru que quies desaniciar y reeditar esti artículu?</string>
<string name="sk_confirm_pin_post_title">Fixar l\'artículu nel perfil</string>
<string name="sk_color_palette_blue">Azul</string>
<string name="sk_translated_using">Traducíu usando %s</string>
<string name="sk_pin_post">Fixar nel perfil</string>
<string name="sk_delete_notification">Desaniciar avisu</string>
<string name="sk_confirm_pin_post">¿Quies fixar esti artículu al to perfil?</string>
<string name="sk_settings_reply_visibility_following">Respuestes a los mios siguidores</string>
<string name="sk_federated_timeline_info_banner">Estos son los artículos más recientes de la xente de la to federación.</string>
<string name="sk_settings_color_palette_default">Por defeutu (%s)</string>
<string name="sk_color_palette_green">Verde</string>
<string name="sk_settings_publish_button_text">Testu del botón d\'espublizamientu</string>
<string name="sk_confirm_delete_scheduled_post_title">Desaniciar artículu programáu</string>
<string name="sk_hashtag">Etiqueta</string>
<string name="sk_icon_image">Semeya</string>
<string name="sk_available_languages">Llingües disponibles</string>
<string name="sk_confirm_clear_recent_languages">¿De xuru que quies desaniciar les llingües usaes apocayá?</string>
<string name="sk_icon_coffee">Café</string>
<string name="sk_icon_color_palette">Paleta de colores</string>
<string name="sk_clear_all_notifications_confirm_action">Desaniciar tou</string>
<string name="sk_settings_uniform_icon_for_notifications">Mesmu icono pa tolos avisos</string>
<string name="sk_compose_draft">L\'artículu va guardase como borrador.</string>
<string name="sk_timelines_add">Amestar</string>
<string name="sk_icon_briefcase">Maletu</string>
<string name="sk_reblog_as">Impulsar con otra cuenta</string>
<string name="sk_pinned_timeline">Fixáu a aniciu</string>
<string name="sk_icon_headphones">Auriculares</string>
<string name="sk_save_draft_message">¿Quies guardar los tos cambios nesti borrador o espublizalo agora?</string>
<string name="sk_delete_notification_confirm">¿De xuru que quies desaniciar esti avisu?</string>
<string name="sk_already_bookmarked">Yá ta metíu en marcadores</string>
<string name="sk_compose_no_draft">Nun guardar borrador</string>
<string name="sk_remove_follower">Desaniciar como siguidor</string>
<string name="sk_bookmarked_as">Metíu en marcadores como %s</string>
<string name="sk_notification_mention">Fuisti mentáu por %s</string>
<string name="sk_settings_translate_only_opened">Namás traducir artículos abiertos</string>
<string name="sk_list_replies_policy">Amosar respuestes a</string>
<string name="sk_timeline">Cronoloxía</string>
<string name="sk_edit_timeline_tag_main">Artículos que contienen l\'etiqueta…</string>
</resources>

View file

@ -606,6 +606,7 @@
<string name="manage_list_members">Listenmitglieder verwalten</string>
<string name="list_no_members">Noch keine Mitglieder</string>
<string name="dont_remind_again">Nicht erneut erinnern</string>
<string name="reply_to_user">Antwort an %s</string>
<!-- %s is a time interval ("5 months") -->
<string name="old_post_sheet_title">Dieser Beitrag ist %s alt</string>
</resources>

View file

@ -121,4 +121,5 @@
<string name="export_settings_share">Einstellungen exportieren</string>
<string name="export_settings_fail">Exportieren der Einstellungen fehlgeschlagen</string>
<string name="export_settings_title">Einstellungen exportieren</string>
<string name="mo_personal_note_saved">Notiz gespeichert</string>
</resources>

View file

@ -185,7 +185,7 @@
<string name="sk_icon_location">Standort</string>
<string name="sk_icon_microphone">Mikrofon</string>
<string name="sk_icon_microscope">Mikroskop</string>
<string name="sk_icon_keyboard">Keyboard</string>
<string name="sk_icon_keyboard">Tastatur</string>
<string name="sk_icon_coffee">Kaffee</string>
<string name="sk_icon_laugh">Lachen</string>
<string name="sk_icon_news">Nachrichten</string>

View file

@ -113,4 +113,5 @@
<string name="mo_trending_link_read">Ανάγνωση</string>
<string name="mo_settings_remove_tracking_params_summary">Απομάκρυνση πληροφοριών ανίχνευσης από συνδέσμους</string>
<string name="mo_settings_remove_tracking_params">Ιδιωτικοί Σύνδεσμοι</string>
<string name="mo_personal_note_saved">Η σημείωση αποθηκεύτηκε</string>
</resources>

View file

@ -96,4 +96,22 @@
<string name="mo_trending_link_read">Legi</string>
<string name="mo_error_display_copy_error_details">Kopii informojn</string>
<string name="mo_settings_unifiedpush_enable">Ebligi</string>
<string name="mo_settings_remove_tracking_params">Malpublikaj Ligiloj</string>
<string name="import_settings_failed">Malsukcesis importi agordojn</string>
<string name="export_settings_share">Eksporti agordojn</string>
<string name="export_settings_fail">Malsukcesis eksporti agordojn</string>
<string name="export_settings_title">Eksportu agordojn</string>
<string name="export_settings_summary">Eksporti la agordojn kaj templinioj de ĉiuj ensalutitaj kontoj</string>
<string name="mo_settings_remove_tracking_params_summary">Foru gvitidintan informacion el ligiloj</string>
<string name="mo_personal_note_saved">Noto savita</string>
<string name="import_settings_confirm_body">Ĉiu nunaj agordoj kaj templinioj estos anstataŭitaj! Ĉi tiu ago ne povas malfarita.</string>
<string name="mo_settings_unifiedpush_warning">UnifiedPush ne estas ŝaltita</string>
<string name="mo_settings_unifiedpush_warning_no_distributors">Neniom da instalitaj distribuantoj de UnifiedPush. Vi ne recivos iajn sciigojn.</string>
<string name="mo_mute_notifications">Ĉu malmontru sciigojn de ĉi tiu uzanto?</string>
<string name="import_settings_confirm">Ĉu akceptu importi agordojn?</string>
<string name="mo_settings_unifiedpush_warning_disabled">UnifiedPush ne estas ŝaltita. Vi ne recivos iajn sciigojn.</string>
<string name="import_settings_title">Importi agordojn</string>
<string name="import_settings_summary">Importi antaŭitajn eksportitajn agordojn kaj templiniojn</string>
<string name="mo_error_display_title">Malsukcesis montri afiŝon</string>
<string name="mo_error_display_text">Io malsukcesis dum ŝarĝas ĉi tiun afiŝon. Se la problemo daŭras, bonvole raportu ĝin en nia paĝo de Issues kune kun la detalojn.</string>
</resources>

View file

@ -101,7 +101,7 @@
<string name="mo_mute_notifications">¿Ocultar las notificaciones de este usuario?</string>
<string name="mo_settings_unifiedpush_warning">UnifiedPush no habilitado</string>
<string name="mo_settings_unifiedpush_warning_disabled">UnifiedPush no está habilitado. No recibirás ninguna notificación.</string>
<string name="export_settings_share">Exportar configuración</string>
<string name="export_settings_share">Exportar ajustes</string>
<string name="mo_error_display_text">Algo salió mal al cargar esta publicación. Si el problema persiste, infórmelo en nuestra página de Problemas junto con los detalles del error.</string>
<string name="import_settings_summary">Importar configuraciones y líneas de tiempo previamente exportadas</string>
<string name="mo_settings_unifiedpush_warning_no_distributors">No hay distribuidores de UnifiedPush instalados. No recibirás ninguna notificación.</string>
@ -110,7 +110,7 @@
<string name="import_settings_confirm_body">¡Se sobrescribirán todas las configuraciones y líneas de tiempo actuales! Esta acción no se puede deshacer.</string>
<string name="import_settings_failed">No se pudo importar la configuración</string>
<string name="export_settings_fail">No se pudo exportar la configuración</string>
<string name="export_settings_title">Exportar configuración</string>
<string name="export_settings_title">Exportar ajustes</string>
<string name="export_settings_summary">Exportar configuraciones y cronogramas para todas las cuentas</string>
<string name="import_settings_title">Importar ajustes</string>
<string name="mo_error_display_title">No se pudo mostrar la publicación</string>
@ -118,4 +118,5 @@
<string name="mo_trending_link_read">Leer</string>
<string name="mo_settings_remove_tracking_params">Enlaces Privados</string>
<string name="mo_settings_remove_tracking_params_summary">Eliminar información de rastreo de los enlaces</string>
<string name="mo_personal_note_saved">Nota guardada</string>
</resources>

View file

@ -224,7 +224,7 @@
<string name="sk_timeline_posts">Publicaciones</string>
<string name="sk_timelines_add">Añadir</string>
<string name="sk_timeline">Línea de tiempo</string>
<string name="sk_hashtag">Hashtag</string>
<string name="sk_hashtag">Etiqueta</string>
<string name="sk_pin_timeline">Anclar cronología</string>
<string name="sk_unpin_timeline">Desanclar cronología</string>
<string name="sk_pinned_timeline">Anclado a inicio</string>

View file

@ -147,7 +147,7 @@
<string name="sk_publish_anyway">Argitaratu hala ere</string>
<string name="sk_settings_disable_alt_text_reminder">Desgaitu gogorarazlea testu alternatiboa gehitzeko</string>
<string name="sk_timelines">Denbora-lerroak</string>
<string name="sk_timeline_posts">Bidalketak</string>
<string name="sk_timeline_posts">Argitalpenak</string>
<string name="sk_timelines_add">Gehitu</string>
<string name="sk_timeline">Denbora-lerroa</string>
<string name="sk_list">Zerrenda</string>
@ -218,7 +218,7 @@
<string name="sk_alt_button">ALT</string>
<string name="sk_post_edited">Editatua</string>
<string name="sk_notification_type_update">Editatutako argitalpenak</string>
<string name="sk_notify_update">Bultzatutako bidalketa editatu da</string>
<string name="sk_notify_update">Bultzatutako argitalpena editatu da</string>
<string name="sk_no_results">Emaitzarik ez</string>
<string name="sk_save_draft">Zirriborroa gorde\?</string>
<string name="sk_no_alt_text">Ez dago testu alternatiborik eskuragarri</string>
@ -270,7 +270,7 @@
<string name="sk_quoting_user">%s aipatzen</string>
<string name="sk_settings_reply_visibility_self">Niri eginiko erantzunak</string>
<string name="sk_notification_action_replied">%s-(r)i erantzun</string>
<string name="sk_bubble_timeline_info_banner">Hauexek dira zure instantziako administratzaileek saretik aukeratutako azken bidalketak.</string>
<string name="sk_bubble_timeline_info_banner">Hauexek dira zure instantziako administratzaileek saretik aukeratutako azken argitalpenak.</string>
<string name="sk_content_type">Edukiaren mota</string>
<string name="sk_content_type_unspecified">Zehaztu gabea</string>
<string name="sk_content_type_plain">Testu arrunta</string>
@ -278,8 +278,8 @@
<string name="sk_content_type_markdown">Markdown</string>
<string name="sk_content_type_bbcode">BBCode</string>
<string name="sk_content_type_mfm">MFM</string>
<string name="sk_settings_content_types">Gaitu bidalketaren formateatzea</string>
<string name="sk_settings_content_types_explanation">Markdown bezalako eduki-mota ezartzea ahalbidetzen du bidalketa bat sortzerakoan. Gogoan izan instantzia guztiek ez dutela hau baimentzen.</string>
<string name="sk_settings_content_types">Gaitu argitalpenaren formateatzea</string>
<string name="sk_settings_content_types_explanation">Markdown bezalako eduki-mota ezartzea ahalbidetzen du argitalpen bat sortzerakoan. Gogoan izan instantzia guztiek ez dutela hau baimentzen.</string>
<string name="sk_settings_default_content_type">Eduki-mota lehenetsia</string>
<string name="sk_settings_confirm_before_reblog">Berretsi bultzatu aurretik</string>
<string name="sk_reacted_with">%1$s-(e)k honela erreakzionatu du: %2$s</string>
@ -290,9 +290,9 @@
<string name="sk_edit_timeline_tags_explanation">Jakin eragiketa hauek zerbitzariak kudeatzen dituela. Litekeena da konbinazioetarako euskarririk ez izatea.</string>
<string name="sk_settings_unifiedpush_no_distributor_body">Banatzaile bat instalatu behar duzu UnifiedPush jakinarazpenek funtzionatzeko. Informazio gehiago: https://unifiedpush.org/</string>
<string name="sk_icon_feed">Jarioa</string>
<string name="sk_edit_timeline_tag_main">Traola hau duten tootak…</string>
<string name="sk_edit_timeline_tag_main">Traola hau duten argitalpenak…</string>
<string name="sk_icon_verified">Egiaztatua</string>
<string name="sk_hashtag_timeline_local_only_switch">Erakutsi toot lokalak soilik\?</string>
<string name="sk_hashtag_timeline_local_only_switch">Erakutsi argitalpen lokalak soilik?</string>
<string name="sk_icon_umbrella">Euritakoa</string>
<string name="sk_settings_unifiedpush_no_distributor">Ez da banatzailerik aurkitu</string>
<string name="sk_edit_timeline_tag_any">...edo hauetako edozein</string>
@ -304,4 +304,23 @@
<string name="sk_icon_recycle_bin">Zakarrontzia</string>
<string name="sk_trending_links_info_banner">Hauek dira zure zerbitzarian komentatzen ari diren albisteak</string>
<string name="sk_add_timeline_tag_error_empty">Traola ezin da hutsik egon</string>
<string name="sk_icon_sun">Eguzkia</string>
<string name="sk_icon_sunset">Ilunabarra</string>
<string name="sk_icon_cloud">Lainoa</string>
<string name="sk_icon_rain">Euria</string>
<string name="sk_icon_snowflake">Elur maluta</string>
<string name="sk_gif_badge">GIF</string>
<string name="sk_posted">%s(e)k argitaratua</string>
<string name="sk_icon_thunderstorm">Ekaitza</string>
<string name="sk_trending_posts_info_banner">Argitalpen hauek garrantzia hartzen ari dira Fedibertsoan.</string>
<plurals name="sk_posts_count_label">
<item quantity="one">Argitalpena</item>
<item quantity="other">Argitalpenak</item>
</plurals>
<string name="sk_post_contains_media">Multimediadun argitalpena</string>
<string name="sk_load_missing_posts_below">Argitalpen zaharragoak kargatu</string>
<string name="sk_load_missing_posts_above">Argitalpen berriagoak kargatu</string>
<string name="sk_settings_default_visibility">Lehenetsitako argitalpenen ikusgarritasuna</string>
<string name="sk_open_post_preview">Aurreikusi argitalpena</string>
<string name="sk_post_preview">Aurrebista</string>
</resources>

View file

@ -1,4 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="mo_relocate_publish_button">Siirrä julkaisupainike uudelleen</string>
<string name="mo_color_palette_nord">Nord</string>
<string name="mo_color_palette_black_and_white">Mustavalkoinen</string>
<string name="mo_enable_dividers">Näytä postin jakajat</string>
</resources>

View file

@ -118,4 +118,5 @@
<string name="export_settings_fail">Échec de l\'export des paramètres</string>
<string name="export_settings_title">Export des paramètres</string>
<string name="mo_settings_unifiedpush_warning">UnifiedPush n\'est pas activé</string>
<string name="mo_personal_note_saved">La note a été enregistrée</string>
</resources>

View file

@ -414,4 +414,22 @@
<string name="sk_settings_lock_account">Approuver manuellement les nouveaux·elles abonné·e·s</string>
<string name="sk_timeline_cache_cleared">Cache du fil d\'accueil vidé</string>
<string name="sk_button_mutuals">Suivi mutuel</string>
<string name="sk_icon_water">Eau</string>
<string name="sk_icon_sunset">Crépuscule</string>
<string name="sk_icon_cloud">Nuage</string>
<string name="sk_icon_rain">Pluie</string>
<string name="sk_posted">%s a publié</string>
<string name="sk_confirm_changes">Confirmer les changements</string>
<string name="sk_icon_sun">Soleil</string>
<string name="sk_icon_snowflake">Flocon de neige</string>
<string name="sk_private_note_update_failed">Échec de la sauvegarde de la note</string>
<string name="sk_private_note_hint">Ajouter une note personnelle à propos du profil</string>
<string name="sk_private_note_confirm_delete">Effacer la note personnelle à propos de %s ?</string>
<string name="sk_delete_note">Supprimer la note personnelle</string>
<string name="sk_add_note">Ajouter une note personnelle</string>
<string name="sk_open_post_preview">Prévisualisation du message</string>
<string name="sk_poll_hide_results">Cacher les résultats</string>
<string name="sk_poll_show_results">Afficher les résultats</string>
<string name="sk_post_preview">Prévisualisation</string>
<string name="sk_poll_multiple_choice">Choix multiple</string>
</resources>

View file

@ -1,4 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="mo_settings_remove_tracking_params_summary">Stráice rianú faisnéise ó naisc</string>
<string name="mo_notification_audience_settings">Lucht Féachana Fógraí</string>
<string name="mo_color_palette_nord">Nord</string>
<string name="mo_color_palette_black_and_white">Dubh agus Bán</string>
<string name="mo_update_available">Tá Moshidon %s réidh le híoslódáil.</string>
<string name="mo_update_ready">Tá Moshidon %s íosluchtaithe agus réidh le suiteáil.</string>
<string name="mo_fab_compose">Cum</string>
<string name="mo_instance_admin">Arna riar ag</string>
<string name="mo_instance_status">Stádas</string>
<string name="mo_instance_contact">Teagmháil</string>
<string name="mo_relocate_publish_button">Cnaipe foilsithe a athlonnú</string>
<string name="mo_hide_compose_button_while_scrolling_setting">Folaigh an cnaipe cumadóireachta agus tú ag scrollú</string>
<string name="mo_welcome_text">Chun tús a chur leis, cuir isteach ainm fearainn do chás baile thíos.</string>
<string name="mo_personal_note">Cuir nóta leis faoin bpróifíl seo</string>
<string name="mo_personal_note_confirm">Deimhnigh na hathruithe atá le tabhairt faoi deara</string>
<string name="mo_emoji_recent">Le déanaí a úsáidtear</string>
<string name="mo_swap_bookmark_with_reblog">Babhtáil leabharmharc le gníomh reblog</string>
<string name="mo_filtered">Scagtha: %s</string>
<string name="mo_add_custom_server_local_timeline">Cuir amlíne áitiúil freastalaí saincheaptha leis</string>
<string name="mo_mute_label">Fad:</string>
<string name="mo_duration_indefinite">Éiginnte</string>
<string name="mo_duration_minutes_5">5 nóiméad</string>
<string name="mo_composer_behavior">Iompar an Chumadóir</string>
<string name="mo_download_latest_nightly_release">Íoslódáil an t-amhrán deireanach oíche</string>
<string name="mo_notification_management_settings">Bainistigh Fógraí</string>
<string name="mo_mention_reblogger_automatically">Luaigh go huathoibríoch an cuntas a rinne athbhlogáil ar an bpostáil i bhfreagraí</string>
<string name="mo_duration_days_3">3 lá</string>
<string name="mo_sending_error">Earráid foilsitheoireachta</string>
<string name="mo_unmute_hashtag">Díbhalbhaigh an hashtag</string>
<string name="mo_confirm_to_unmute_hashtag">An bhfuil tú cinnte gur mhaith leat an hashchlib seo a dhíbhalbhú?</string>
<string name="mo_share_open_url">Oscail san Aip</string>
<string name="mo_severity_silence">Ciúnaithe</string>
<string name="mo_blocked_accounts">Cuntais bactha</string>
<string name="mo_muted_accounts">Cuntais bhalbhaithe</string>
<string name="mo_show_media_preview">Taispeáin réamhamharc meán i línte ama</string>
<string name="mo_filter_notifications">Scag fógraí</string>
<string name="mo_recent_emoji_cleared">Glanadh emoji le déanaí</string>
<string name="mo_double_tap_to_search">Tapáil faoi dhó chun cuardach a oscailt</string>
<string name="mo_instance_users">Úsáideoirí</string>
<string name="mo_instance_registration_open">Oscail</string>
<string name="mo_instance_info_open_timeline">Amlíne áitiúil</string>
<string name="mo_setting_true_black_summary">D\'fhéadfadh sé cumhacht a shábháil ar thaispeántais AMOLED</string>
<string name="mo_setting_marquee_summary">Díchumasaítear an scrolláil teidil éilipsithe</string>
<string name="mo_setting_reduced_motion_summary">Díchumasaigh beochan na n-idirghníomhaíochtaí</string>
<string name="mo_enable_dividers">Taispeáin roinnteoirí postálacha</string>
<string name="mo_notification_action_replied">D\'éirigh le %s an postáil a fhreagairt</string>
<string name="mo_mute_hashtag">Balbhaigh hashtag</string>
<string name="mo_poll_option_add">Cuir rogha vótaíochta nua leis</string>
<string name="export_settings_fail">Theip ar easpórtáil na socruithe</string>
<string name="mo_no_image_desc_title">Gan cur síos ar an íomhá</string>
<string name="mo_no_image_desc">Níl aon chur síos ar na híomhánna atá san áireamh. Smaoinigh le do thoil ceann a chur leis, chun ligean do dhaoine lagamhairc a bheith rannpháirteach.</string>
<string name="mo_disable_reminder_to_add_alt_text">Díchumasaigh meabhrúchán chun téacs alt a chur leis</string>
<string name="mo_open_camera">Glac pictiúr</string>
<string name="mo_confirm_to_mute_hashtag">An bhfuil tú cinnte gur mhaith leat an hashchlib seo a bhalbhú?</string>
<string name="mo_setting_disable_swipe_summary">Svaidhpeáil chun amlíne amharc a athrú</string>
<string name="mo_settings_remove_tracking_params">Naisc Príobháideacha</string>
<string name="mo_camera_not_available">Níl ceamara ar fáil!</string>
<string name="mo_confirm_to_mute_conversation">An bhfuil tú cinnte gur mhaith leat an comhrá seo a bhalbhú?</string>
<string name="mo_confirm_to_unmute_conversation">An bhfuil tú cinnte gur mhaith leat an comhrá seo a dhíbhalbhú?</string>
<string name="mo_instance_registration_approval">Faomhadh ag teastáil</string>
<string name="mo_double_tap_to_swipe_between_tabs">Tapáil faoi dhó chun sleamhnú idir na cluaisíní</string>
<string name="mo_instance_view_info">Féach ar Fhaisnéis an Fhreastalaí</string>
<string name="mo_severity_suspend">Bactha</string>
<string name="mo_setting_uniform_summary">Bain úsáid as an deilbhín app do gach fógra</string>
<string name="mo_setting_remote_follower_summary">Taispeáin leantóirí ó chásanna eile</string>
<string name="mo_personal_note_saved">Nóta sábháilte</string>
<string name="mo_change_default_reply_visibility_to_unlisted">Freagair mar \'Neamhliostaithe\' de réir réamhshocraithe</string>
<string name="mo_setting_interaction_count_summary">Taispeáin cé mhéad duine a d\'idirghníomhaigh le postáil san amlíne</string>
<string name="mo_swap_bookmark_with_reblog_summary">Leabharmharc nó athbhlogáil postálacha ón bhfógra</string>
<string name="mo_load_remote_followers">Luchtaigh an phróifíl chianda seo a leanas agus na leantóirí</string>
<string name="mo_notification_filter_reset">Athshocraigh go réamhshocrú</string>
<string name="mo_mute_notifications">An bhfuil fonn ort fógraí ón úsáideoir seo a cheilt?</string>
<string name="mo_settings_unifiedpush_warning">Níl UnifiedPush cumasaithe</string>
<string name="mo_settings_unifiedpush_warning_no_distributors">Níl aon Dáileoirí UnifiedPush suiteáilte. Ní bhfaighidh tú aon fhógraí.</string>
<string name="mo_settings_unifiedpush_warning_disabled">Níl UnifiedPush cumasaithe. Ní bhfaighidh tú aon fhógraí.</string>
<string name="mo_settings_unifiedpush_enable">Cumasaigh</string>
<string name="import_settings_confirm">Deimhnigh na socruithe a iompórtáil?</string>
<string name="mo_personal_note_update_failed">Theip ar shábháil an nóta</string>
<string name="mo_settings_contribute">Cur le Moshidon</string>
<string name="mo_clear_recent_emoji">Glan emoji a úsáideadh le déanaí</string>
<string name="mo_disable_relocate_publish_button_to_enable_customization">Díchumasaigh an cnaipe Foilsithe Athlonnaigh chun oiriúnú a cheadú</string>
<string name="mo_muted_conversation_successfully">D\'éirigh le balbhú an chomhrá</string>
<string name="mo_unmuted_conversation_successfully">D\'éirigh le díbhalbhú an chomhrá</string>
<string name="mo_muting">Ag balbhú…</string>
<string name="mo_unmuting">Ag díbhalbhú…</string>
<string name="mo_mute_conversation">Balbhaigh an comhrá</string>
<string name="mo_unmute_conversation">Díbhalbhaigh an comhrá</string>
<string name="mo_duration_minutes_30">30 nóiméad</string>
<string name="mo_duration_hours_1">1 uair</string>
<string name="mo_duration_hours_6">6 huaire</string>
<string name="mo_duration_days_1">1 lá</string>
<string name="mo_duration_days_7">7 lá</string>
<string name="mo_instance_registration">Clárú</string>
<string name="mo_instance_info_moderated_servers">Freastalaithe modhnaithe</string>
<string name="mo_setting_play_gif_summary">Uathsheinn GIFanna in avatars agus emoji</string>
<string name="mo_setting_relocate_publish_summary">Bog an cnaipe foilsithe go dtí an barra bun</string>
<string name="mo_setting_default_reply_privacy_summary">Diúltófar do fhreagraí ó ghnéithe fionnachtana</string>
<string name="mo_setting_haptic_feedback_summary">Creathadh agus tú ag idirghníomhú le postálacha</string>
<string name="mo_settings_show_posts_without_alt_summary">Beidh postálacha i bhfolach i ngach amlíne, ach is féidir iad a nochtadh i snáitheanna agus i bhfógraí</string>
<string name="mo_settings_show_posts_without_alt">Taispeáin postálacha meán a bhfuil téacs alt in easnamh orthu</string>
<string name="mo_haptic_feedback">Aiseolas haptach</string>
<string name="mo_confirm_unfollow_title">Dílean an Cuntas</string>
<string name="mo_confirm_unfollow">Deimhnigh %s a dhíleanúint</string>
<string name="import_settings_confirm_body">Déanfar gach socrú agus amlíne reatha a fhorscríobh! Ní féidir an gníomh seo a chealú.</string>
<string name="import_settings_failed">Theip ar iompórtáil na socruithe</string>
<string name="export_settings_share">Socruithe Easpórtála</string>
<string name="export_settings_title">Socruithe easpórtála</string>
<string name="export_settings_summary">Easpórtáil socruithe agus línte ama gach cuntas logáilte isteach</string>
<string name="mo_error_display_title">Theip ar an bpostáil a thaispeáint</string>
<string name="mo_error_display_text">Tharla earráid agus an postáil seo á lódáil. Má leanann an fhadhb, cuir in iúl é ar ár leathanach Ceisteanna mar aon le sonraí na hearráide.</string>
<string name="mo_error_display_copy_error_details">Cóipeáil sonraí</string>
<string name="mo_trending_link_read">Léigh</string>
<string name="import_settings_title">Socruithe a allmhairiú</string>
<string name="import_settings_summary">Iompórtáil socruithe agus amlínte a easpórtáladh roimhe seo</string>
</resources>

View file

@ -1,3 +1,458 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="sk_app_name">Megalodon</string>
<string name="sk_pinned_posts">Pinned</string>
<string name="sk_delete_and_redraft">Scrios agus athdhréachtú</string>
<string name="sk_confirm_delete_and_redraft_title">Scrios agus athdhréachtaigh Post</string>
<string name="sk_pin_post">Pionnáil le próifíl</string>
<string name="sk_confirm_pin_post_title">Pionnáil an post le próifíl</string>
<string name="sk_confirm_pin_post">An bhfuil fonn ort an post seo a phionnáil le do phróifíl?</string>
<string name="sk_pinning">Post pinning…</string>
<string name="sk_unpin_post">Díphionnáil ón bpróifíl</string>
<string name="sk_confirm_unpin_post_title">Díphionnáil an post ón bpróifíl</string>
<string name="sk_confirm_unpin_post">An bhfuil tú cinnte go bhfuil fonn ort an post seo a dhíphionnáil?</string>
<string name="sk_unpinning">Post á dhíphionnáil…</string>
<string name="sk_image_description">Cur síos ar an íomhá</string>
<string name="sk_quoting_user">%s á lua</string>
<string name="sk_settings_reply_visibility">Infheictheacht freagra</string>
<string name="sk_mark_media_as_sensitive">Marcáil na meáin mar íogair</string>
<string name="sk_federated_timeline">Cónaidhm</string>
<string name="sk_federated_timeline_info_banner">Is iad seo na poist is déanaí ag na daoine i do chónaidhm.</string>
<string name="sk_bubble_timeline_info_banner">Is iad seo na poist is déanaí ón líonra coimeádaithe ag do admins shampla.</string>
<string name="sk_trending_posts_info_banner">Tá na poist seo ag tarraingt ar an Fediverse faoi láthair.</string>
<string name="sk_trending_links_info_banner">Tá na scéalta nuachta seo ag caint faoi ar fud na Fediverse.</string>
<string name="sk_update_available">Tá Megalodon %s réidh le híoslódáil.</string>
<string name="sk_reject_follow_request">Diúltaigh don iarratas seo a leanas</string>
<string name="sk_lists_with_user">Liostaí le %s</string>
<string name="sk_settings_always_reveal_content_warnings">Nocht rabhaidh inneachair i gcónaí</string>
<string name="sk_settings_enable_marquee">Cumasaigh téacs scrollaithe i mbarra teidil</string>
<string name="sk_settings_contribute">Cur le Megalodon</string>
<string name="sk_settings_color_palette_default">Réamhshocrú (%s)</string>
<string name="sk_color_palette_purple">Corcra</string>
<string name="sk_color_palette_brown">Donn</string>
<string name="sk_color_palette_red">Dearg</string>
<string name="sk_translate_show_original">Taispeáin an bunleagan</string>
<string name="sk_translated_using">Aistrithe ag úsáid %s</string>
<string name="sk_post_language">Teanga: %s</string>
<string name="sk_example_domain">sampla.social</string>
<string name="sk_settings_filters">Cumraigh scagairí</string>
<string name="sk_settings_auth">Socruithe slándála</string>
<string name="sk_settings_rules">Rialacha</string>
<string name="sk_settings_about">Maidir leis an aip</string>
<string name="sk_settings_donate">Deonaigh</string>
<string name="sk_delete_notification_confirm_action">Scrios fógra</string>
<string name="sk_delete_notification_confirm">An bhfuil tú cinnte go bhfuil fonn ort an fógra seo a scriosadh?</string>
<string name="sk_clear_all_notifications">Glan gach fógra</string>
<string name="sk_clear_all_notifications_confirm_action">Scrios gach rud</string>
<string name="sk_clear_all_notifications_confirm">An bhfuil tú cinnte go bhfuil fonn ort gach fógra a ghlanadh?</string>
<string name="sk_settings_enable_delete_notifications">Cumasaigh fógraí a scriosadh</string>
<string name="sk_settings_publish_button_text">Foilsigh téacs an chnaipe</string>
<string name="sk_quote_post">Post faoi seo</string>
<string name="sk_hashtags_you_follow">Hashtags a leanann tú</string>
<string name="sk_copy_link_to_post">Cóipeáil nasc leis an bpost</string>
<string name="sk_already_reblogged">Borradh curtha cheana féin</string>
<string name="sk_reply_as">Freagra le cuntas eile</string>
<string name="sk_settings_uniform_icon_for_notifications">Deilbhín aonfhoirmeach do gach fógra</string>
<string name="sk_forward_report_to">Ar aghaidh chuig %s</string>
<string name="sk_unsent_posts">Poist gan choinne</string>
<string name="sk_draft">Dréacht</string>
<string name="sk_schedule">Sceideal</string>
<string name="sk_confirm_delete_draft_title">Scrios dréacht</string>
<string name="sk_confirm_delete_scheduled_post_title">Scrios an post sceidealta</string>
<string name="sk_confirm_delete_scheduled_post">An bhfuil tú cinnte go bhfuil fonn ort an post sceidealta seo a scriosadh?</string>
<string name="sk_draft_or_schedule">Dréacht nó sceideal</string>
<string name="sk_compose_scheduled">Sceidealaithe le haghaidh</string>
<string name="sk_draft_saved">Dréacht sábháilte</string>
<string name="sk_post_scheduled">Post sceidealta</string>
<string name="sk_scheduled_too_soon_title">Tá an t-am sceidealta ró-luath</string>
<string name="sk_confirm_save_changes">Sábháil athruithe?</string>
<string name="sk_settings_reduce_motion">Laghdaigh gluaisne i mbeochan</string>
<string name="sk_announcements">Fógraí</string>
<string name="sk_settings_about_instance">Mar shampla,</string>
<string name="sk_settings_unifiedpush">Úsáid AontaithePush</string>
<string name="sk_settings_unifiedpush_no_distributor_body">Ní mór duit dáileoir a shuiteáil le haghaidh fógraí UnifiedPush a bheith ag obair. Chun tuilleadh eolais a fháil, tabhair cuairt ar https://unifiedpush.org/</string>
<string name="sk_create">Cruthaigh</string>
<string name="sk_create_list_title">Cruthaigh liosta</string>
<string name="sk_list_name_hint">Ainm an liosta</string>
<string name="sk_your_lists">Do liostaí</string>
<string name="sk_timelines">Amlínte</string>
<string name="sk_unpin_timeline">Díphionnáil amlíne</string>
<string name="sk_pinned_timeline">Pinned chun an bhaile</string>
<string name="sk_remove">Bain</string>
<string name="sk_timeline_icon">Deilbhín</string>
<string name="sk_icon_heart">Croí</string>
<string name="sk_icon_star">Réalta</string>
<string name="sk_icon_city">Cathair</string>
<string name="sk_icon_cat">Cat</string>
<string name="sk_icon_dog">Madra</string>
<string name="sk_icon_balloon">Balún</string>
<string name="sk_icon_language">Teanga</string>
<string name="sk_icon_location">Suíomh</string>
<string name="sk_icon_megaphone">Meigeafón</string>
<string name="sk_icon_coffee">Caife</string>
<string name="sk_icon_laugh">Gáire</string>
<string name="sk_icon_news">Nuacht</string>
<string name="sk_icon_backpack">Mála droma</string>
<string name="sk_icon_globe">Cruinneog</string>
<string name="sk_icon_pin">Biorán</string>
<string name="sk_icon_feed">Fotha</string>
<string name="sk_icon_beaker">Eascra</string>
<string name="sk_icon_bed">Leaba</string>
<string name="sk_icon_recycle_bin">Athchúrsáil an bosca bruscair</string>
<string name="sk_icon_verified">Fíoraithe</string>
<string name="sk_icon_doctor">Dochtúir</string>
<string name="sk_icon_diamond">Muileata</string>
<string name="sk_icon_umbrella">Scáth fearthainne</string>
<string name="sk_icon_water">Uisce</string>
<string name="sk_icon_sun">An Ghrian</string>
<string name="sk_icon_sunset">Luí na Gréine</string>
<string name="sk_icon_cloud">Scamall</string>
<string name="sk_icon_thunderstorm">Stoirm thoirní</string>
<string name="sk_icon_rain">Báisteach</string>
<string name="sk_icon_snowflake">Brat sneachta</string>
<string name="sk_edit_timeline">Cuir amlíne in eagar</string>
<string name="sk_edit_timeline_tag_none">… ach níl aon cheann de na</string>
<string name="sk_edit_timeline_tag_hint">Iontráil hashtag…</string>
<string name="sk_edit_timeline_tags_hint">Iontráil hashtags…</string>
<string name="sk_hashtag_timeline_local_only_switch">Ná taispeáin ach poist áitiúla?</string>
<string name="sk_notification_type_update">Poist curtha in eagar</string>
<string name="sk_settings_show_alt_indicator">Táscaire le haghaidh téacsanna alt</string>
<string name="sk_settings_show_no_alt_indicator">Táscaire le haghaidh téacsanna alt ar iarraidh</string>
<string name="sk_updater_enable_pre_releases">Cumasaigh réamh-eisiúintí</string>
<string name="sk_settings_see_new_posts_button">Cnaipe \"Féach poist nua\"</string>
<string name="sk_settings_hide_interaction">Folaigh cnaipí idirghníomhaíochta</string>
<string name="sk_compact_reblog_reply_line">Dlúth borradh / líne freagra</string>
<string name="sk_settings_confirm_before_reblog">Deimhnigh roimh threisiú</string>
<string name="sk_content_type_plain">Gnáth-théacs</string>
<string name="sk_content_type_html">HTML</string>
<string name="sk_content_type_markdown">Marcáil síos</string>
<string name="sk_content_type_bbcode">BBCodeGenericName</string>
<string name="sk_content_type_mfm">MFM</string>
<string name="sk_settings_content_types">Cumasaigh formáidiú an phoist</string>
<string name="sk_settings_default_content_type">Cineál inneachair réamhshocraithe</string>
<string name="sk_instance_info_unavailable">Níl faisnéis shamplach ar fáil go sealadach</string>
<string name="sk_open_in_app">Oscail san fheidhmchlár</string>
<string name="sk_settings_allow_remote_loading_explanation">Bain triail as liostaí níos cruinne a fháil do leanúna, is maith agus boosts tríd an bhfaisnéis a luchtú ón gcás tionscnaimh.</string>
<string name="sk_settings_auto_reveal_equal_spoilers">Nocht CWanna comhionanna go huathoibríoch i bhfreagraí</string>
<string name="sk_settings_auto_reveal_nobody">Riamh</string>
<string name="sk_settings_auto_reveal_author">Freagraí ón údar céanna</string>
<string name="sk_settings_auto_reveal_anyone">Freagraí ó gach duine</string>
<string name="sk_settings_prefix_replies_always">Mar fhreagra ar dhuine ar bith</string>
<string name="sk_settings_prefix_replies_never">Riamh</string>
<string name="sk_settings_prefix_replies_to_others">Ach amháin mar fhreagra ar dhaoine eile</string>
<string name="sk_settings_forward_report_default">Réamhshocrú lasca \"Tuarascáil ar Aghaidh\"</string>
<string name="sk_list_exclusive_switch_explanation">Ní thaispeánfaidh baill de liosta eisiach ar d\'amlíne baile má thacaíonn do chás leis.</string>
<string name="sk_advanced_options_show">Taispeáin ardroghanna</string>
<string name="sk_pronouns_label">Forainmneacha</string>
<string name="sk_switch_timeline">Athraigh amlíne</string>
<string name="sk_settings_true_black">Pic mód dubh</string>
<string name="sk_search_fediverse">Cuardaigh an Fediverse</string>
<string name="sk_settings_display_pronouns_in_timelines">Taispeáin forainmneacha in amlínte</string>
<string name="sk_settings_show_emoji_reactions">Taispeáin frithghníomhartha emoji in amlínte</string>
<plurals name="sk_users_reacted_with">
<item quantity="one">D\'fhreagair úsáideoir amháin le %2$s</item>
<item quantity="two">D\'fhreagair %1$,d úsáideoirí le %2$s</item>
<item quantity="few">D\'fhreagair %1$,d úsáideoirí le %2$s</item>
<item quantity="many">D\'fhreagair %1$,d úsáideoirí le %2$s</item>
<item quantity="other">D\'fhreagair %1$,d úsáideoirí le %2$s</item>
</plurals>
<plurals name="sk_posts_count_label">
<item quantity="one">teachtaireacht</item>
<item quantity="two">teachtaireachtaí</item>
<item quantity="few">teachtaireachtaí</item>
<item quantity="many">teachtaireachtaí</item>
<item quantity="other">teachtaireachtaí</item>
</plurals>
<string name="sk_post_contains_media">Tá meáin sa phost</string>
<plurals name="sk_time_seconds">
<item quantity="one">%d soicind</item>
<item quantity="two">%d soicindí</item>
<item quantity="few">%d soicindí</item>
<item quantity="many">%d soicindí</item>
<item quantity="other">%d soicindí</item>
</plurals>
<plurals name="sk_time_hours">
<item quantity="one">%d uair</item>
<item quantity="two">%d uair an chloig</item>
<item quantity="few">%d uair an chloig</item>
<item quantity="many">%d uair an chloig</item>
<item quantity="other">%d uair an chloig</item>
</plurals>
<string name="sk_muted_accounts">Cuntais muted</string>
<string name="sk_blocked_accounts">Cuntais bhlocáilte</string>
<string name="sk_settings_like_icon">Úsáid croí mar dheilbhín is fearr leat</string>
<plurals name="sk_time_days">
<item quantity="one">%d lá</item>
<item quantity="two">%d laethanta</item>
<item quantity="few">%d laethanta</item>
<item quantity="many">%d laethanta</item>
<item quantity="other">%d laethanta</item>
</plurals>
<string name="sk_settings_underlined_links">Naisc aibhsithe</string>
<string name="sk_set_as_default">Socraigh mar réamhshocrú</string>
<string name="sk_edit_alt_text">Cuir téacs alt in eagar</string>
<string name="sk_settings_clear_timeline_cache">Glan taisce amlíne baile</string>
<string name="sk_timeline_cache_cleared">Taisce amlíne baile glanta</string>
<string name="sk_settings_lock_account">Ceadaigh leanúna nua de láimh</string>
<string name="sk_settings_default_visibility">Infheictheacht réamhshocraithe postála</string>
<string name="sk_button_mutuals">Frithpháirteacha</string>
<string name="sk_private_note_hint">Cuir nóta pearsanta leis faoin bpróifíl seo</string>
<string name="sk_confirm_changes">Deimhnigh athruithe</string>
<string name="sk_private_note_update_failed">Theip ar shábháil an nóta</string>
<string name="sk_private_note_confirm_delete">Scrios nóta pearsanta faoi %s?</string>
<string name="sk_delete_note">Scrios nóta pearsanta</string>
<string name="sk_add_note">Cuir nóta pearsanta leis</string>
<string name="sk_settings_copy_crash_log">Cóipeáil an logchomhad tuairteála is déanaí</string>
<string name="sk_poll_show_results">Taispeáin torthaí</string>
<string name="sk_poll_hide_results">Folaigh torthaí</string>
<string name="sk_confirm_delete_and_redraft">An bhfuil tú cinnte go bhfuil fonn ort an post seo a scriosadh agus a athdhréachtú?</string>
<string name="sk_visibility_unlisted">Neamhliostaithe</string>
<string name="sk_settings_show_replies">Taispeáin freagraí</string>
<string name="sk_settings_continues_playback">Forleagan fuaime</string>
<string name="sk_settings_continues_playback_summary">Lig do na meáin atá ag imirt cheana féin leanúint ar aghaidh ag imirt, ag forleagan an athsheinm nua</string>
<string name="sk_settings_reply_visibility_all">Gach freagra</string>
<string name="sk_settings_reply_visibility_following">Freagraí ar mo chuid seo a leanas</string>
<string name="sk_settings_reply_visibility_self">Freagraí dom</string>
<string name="sk_settings_show_boosts">Taispeáin teanndáileoga</string>
<string name="sk_settings_load_new_posts">Luchtaigh poist nua go huathoibríoch</string>
<string name="sk_settings_show_interaction_counts">Taispeáin comhaireamh idirghníomhaíochta</string>
<string name="sk_settings_app_version">Megalodon v%1$s (%2$d)</string>
<string name="sk_user_post_notifications_on">Casta air fógraí poist le haghaidh %s</string>
<string name="sk_user_post_notifications_off">Múch fógraí poist le haghaidh %s</string>
<string name="sk_update_ready">Tá Megalodon %s íoslódáilte agus réidh le suiteáil.</string>
<string name="sk_check_for_update">Seiceáil le haghaidh nuashonrú</string>
<string name="sk_no_update_available">Níl aon nuashonrú ar fáil</string>
<string name="sk_list_timelines">Liostaí</string>
<plurals name="sk_time_minutes">
<item quantity="one">%d nóiméad</item>
<item quantity="two">%d nóiméad</item>
<item quantity="few">%d nóiméad</item>
<item quantity="many">%d nóiméad</item>
<item quantity="other">%d nóiméad</item>
</plurals>
<string name="sk_language_name">%1$s (%2$s)</string>
<string name="sk_follow_requests">Lean iarratais</string>
<string name="sk_accept_follow_request">Glac leis an iarratas seo a leanas</string>
<string name="sk_settings_show_federated_timeline">Taispeáin amlíne chónasctha</string>
<string name="sk_notification_type_status">Poist</string>
<string name="sk_notification_type_posts">Fógraí poist</string>
<string name="sk_settings_color_palette">Pailéad dathanna</string>
<string name="sk_color_palette_material3">Córas</string>
<string name="sk_color_palette_pink">Bándearg</string>
<string name="sk_translate_post">Aistrigh</string>
<string name="sk_available_languages">Teangacha atá ar fáil</string>
<string name="sk_clear_recent_languages">Glan teangacha a úsáideadh le déanaí</string>
<string name="sk_color_palette_green">Glas</string>
<string name="sk_color_palette_blue">Gorm</string>
<string name="sk_color_palette_yellow">Buí</string>
<string name="sk_confirm_clear_recent_languages">An bhfuil tú cinnte go bhfuil fonn ort do theangacha a úsáideadh le déanaí a ghlanadh?</string>
<string name="sk_welcome_title">Fáilte!</string>
<string name="sk_welcome_text">Salutes an siorc tú! Chun tús a chur leis, cuir isteach ainm fearainn do shampla baile thíos.</string>
<string name="sk_settings_tabs_disable_swipe">Díchumasaigh svaidhpeáil idir cluaisíní</string>
<string name="sk_settings_profile">Cumraigh próifíl</string>
<string name="sk_settings_posting">Sainroghanna postála</string>
<string name="sk_delete_notification">Scrios fógra</string>
<string name="sk_settings_publish_button_text_title">Saincheap Foilsigh téacs an chnaipe</string>
<string name="sk_settings_translate_only_opened">Ná aistrigh ach poist oscailte</string>
<string name="sk_settings_translation_availability_note_available">Tacaíonn %s le haistriúchán!</string>
<string name="sk_settings_translation_availability_note_unavailable">Ní cosúil go dtacaíonn %s leis an aistriúchán.</string>
<string name="sk_loading_fediverse_resource_title">Ag breathnú suas ar an Fediverse</string>
<string name="sk_loading_resource_on_instance_title">Á chuardach suas ar %s</string>
<string name="sk_undo_reblog">Cealaigh borradh</string>
<string name="sk_reblog_with_visibility">Borradh le hinfheictheacht</string>
<string name="sk_open_with_account">Oscail le cuntas eile</string>
<string name="sk_resource_not_found">Níorbh fhéidir acmhainn a aimsiú</string>
<string name="sk_bookmark_as">Leabharmharc le cuntas eile</string>
<string name="sk_bookmarked_as">Leabharmharc mar %s</string>
<string name="sk_already_bookmarked">Leabharmharcáilte cheana féin</string>
<string name="sk_favorite_as">Is fearr leat le cuntas eile</string>
<string name="sk_favorited_as">Ceanaithe mar %s</string>
<string name="sk_already_favorited">Ceanaithe cheana féin</string>
<string name="sk_reblog_as">Treisiú le cuntas eile</string>
<string name="sk_reblogged_as">Treisithe mar %s</string>
<string name="sk_confirm_delete_draft">An bhfuil tú cinnte go bhfuil fonn ort an post dréachtaithe seo a scriosadh?</string>
<string name="sk_compose_draft">Sábhálfar an post mar dhréacht.</string>
<string name="sk_scheduled_too_soon">Ní mór an post a sceidealú 10 nóiméad ar a laghad amach anseo.</string>
<string name="sk_confirm_save_draft">Sábháil dréacht?</string>
<string name="sk_mark_as_draft">Marcáil mar dhréacht</string>
<string name="sk_schedule_post">Sceideal an phoist</string>
<string name="sk_schedule_or_draft">Sceideal nó dréacht</string>
<string name="sk_compose_no_schedule">Ná sceideal</string>
<string name="sk_compose_no_draft">Ná dréachtaigh</string>
<string name="sk_mark_as_read">Marcáil mar léite</string>
<string name="sk_settings_single_notification">Ná taispeáin ach fógra amháin</string>
<string name="sk_settings_unifiedpush_choose">Roghnaigh dáileoir</string>
<string name="sk_settings_unifiedpush_no_distributor">Níor aimsíodh dáileoir ar bith</string>
<string name="sk_list_replies_policy">Taispeáin freagraí ar</string>
<string name="sk_list_replies_policy_list">Liostaigh Baill</string>
<string name="sk_list_replies_policy_followed">úsáideoirí a lean</string>
<string name="sk_list_replies_policy_none">Duine ar bith</string>
<string name="sk_delete_list">Scrios liosta</string>
<string name="sk_delete_list_confirm">An bhfuil tú cinnte go bhfuil fonn ort an liosta \"%s\" a scriosadh?</string>
<string name="sk_edit_list_title">Cuir liosta in eagar</string>
<string name="sk_timeline_home">Baile</string>
<string name="sk_timeline_local">Áitiúil</string>
<string name="sk_timeline_federated">Cónaidhm</string>
<string name="sk_timeline_bubble">Mboilgeog</string>
<string name="sk_recent_searches_placeholder">Cineál le tosú ag cuardach</string>
<string name="sk_remove_follower">Bain mar leantóir</string>
<string name="sk_remove_follower_confirm">Bain %s mar leantóir trí iad a bhlocáil agus a dhíbhlocáil láithreach?</string>
<string name="sk_do_remove_follower">Bain</string>
<string name="sk_remove_follower_success">D\' éirigh leis an leantóir a bhaint</string>
<string name="sk_changelog">ChangelogName</string>
<string name="sk_alt_text_missing_title">Téacs alt ar iarraidh</string>
<string name="sk_alt_text_missing">Níl tuairisc i gceangaltán amháin ar a laghad.</string>
<string name="sk_publish_anyway">Foilsigh ar aon nós</string>
<string name="sk_settings_disable_alt_text_reminder">Díchumasaigh meabhrúchán chun téacs alt a chur leis</string>
<string name="sk_notify_posts_info_banner">Má chumasaíonn tú fógraí poist do roinnt daoine, beidh a gcuid post nua le feiceáil anseo.</string>
<string name="sk_timeline_posts">Poist</string>
<string name="sk_timelines_add">Cuir Leis</string>
<string name="sk_timeline">Amlíne</string>
<string name="sk_list">Liosta</string>
<string name="sk_hashtag">Haischlib</string>
<string name="sk_pin_timeline">Amlíne bioráin</string>
<string name="sk_unpinned_timeline">Gan phioc ón mbaile</string>
<string name="sk_icon_rabbit">Coinín</string>
<string name="sk_icon_turtle">Turtar</string>
<string name="sk_icon_image">Íomhá</string>
<string name="sk_icon_bot">Róbónna</string>
<string name="sk_icon_microphone">Micreafón</string>
<string name="sk_icon_microscope">Micreascóp</string>
<string name="sk_icon_keyboard">Méarchlár</string>
<string name="sk_icon_pi">Pi</string>
<string name="sk_icon_color_palette">Pailéad dathanna</string>
<string name="sk_icon_academic_cap">Caipín acadúil</string>
<string name="sk_icon_tag"></string>
<string name="sk_icon_stethoscope">Stethoscope</string>
<string name="sk_icon_weather">Aimsir</string>
<string name="sk_icon_games">Cluichí</string>
<string name="sk_icon_code">Cód</string>
<string name="sk_icon_aperture">Cró</string>
<string name="sk_icon_music">Ceol</string>
<string name="sk_icon_light_bulb">Bolgán solais</string>
<string name="sk_icon_train">Traein</string>
<string name="sk_icon_clapper_board">Clár clapper</string>
<string name="sk_icon_leaves">Duilleoga</string>
<string name="sk_icon_sport">Spórt</string>
<string name="sk_icon_people">Daoine</string>
<string name="sk_icon_health">Sláinte</string>
<string name="sk_icon_important">Tábhachtach</string>
<string name="sk_icon_chat">Comhrá</string>
<string name="sk_icon_shield">Sciath</string>
<string name="sk_icon_book">Leabhar</string>
<string name="sk_icon_bicycle">Rothar</string>
<string name="sk_icon_map">Léarscáil</string>
<string name="sk_icon_math_formula">Foirmle mhata</string>
<string name="sk_icon_briefcase">Mála Cáipéisí</string>
<string name="sk_icon_fire">Dóiteán</string>
<string name="sk_icon_bug">Fabht</string>
<string name="sk_icon_pizza">Píotsa</string>
<string name="sk_icon_gavel">GavelName</string>
<string name="sk_icon_gauge">Tomhas</string>
<string name="sk_icon_headphones">Cluasáin</string>
<string name="sk_icon_human">An Duine</string>
<string name="sk_add_timeline">Cuir amlíne leis</string>
<string name="sk_edit_timelines">Cuir amlínte in eagar</string>
<string name="sk_edit_timeline_tag_main">Poist ina bhfuil hashtag…</string>
<string name="sk_edit_timeline_tag_any">… nó aon cheann de na</string>
<string name="sk_edit_timeline_tag_all">… agus gach ceann de na</string>
<string name="sk_edit_timeline_tags_explanation">Tabhair faoi deara go láimhseálann an freastalaí na hoibríochtaí seo. B\'fhéidir nach dtacófaí leo iad a chur le chéile.</string>
<string name="sk_add_timeline_tag_error_empty">Ní féidir leis an haischlib a bheith folamh</string>
<string name="sk_alt_button">SEAN</string>
<string name="sk_gif_badge">GIF</string>
<string name="sk_posted">%s sa phost</string>
<string name="sk_post_edited">curtha in eagar</string>
<string name="sk_notify_update">Cuir post treisithe in eagar</string>
<string name="sk_attach_file">Ceangail comhad</string>
<string name="sk_searching">Ag cuardach…</string>
<string name="sk_no_results">Gan torthaí</string>
<string name="sk_save_draft">Sábháil dréacht?</string>
<string name="sk_save_draft_message">An bhfuil fonn ort do chuid athruithe ar an dréacht seo a shábháil nó é a fhoilsiú anois?</string>
<string name="sk_no_alt_text">Níl téacs alt ar fáil</string>
<string name="sk_inline_local_only">áitiúil amháin</string>
<string name="sk_inline_direct">luaite amháin</string>
<string name="sk_separator">·</string>
<string name="sk_local_only">Sampla áitiúil amháin</string>
<string name="sk_instance_features">Gnéithe ásc</string>
<string name="sk_settings_support_local_only">Tacaíonn freastalaí le postáil áitiúil amháin</string>
<string name="sk_settings_glitch_instance">Glitch mód logánta-amháin</string>
<string name="sk_settings_glitch_mode_explanation">Cumasaigh é seo má ritheann do chás baile ar Glitch. Ní gá do Bhaile Dúchais nó Akkoma.</string>
<string name="sk_signed_up">Sínithe</string>
<string name="sk_reported">a tuairiscíodh</string>
<string name="sk_reacted_with">D\'fhreagair %1$s le %2$s</string>
<string name="sk_reacted">D\'fhreagair %s</string>
<string name="sk_sign_ups">Úsáideoirí ag clárú</string>
<string name="sk_new_reports">Tuarascálacha nua</string>
<string name="sk_settings_server_version">Leagan freastalaí: %s</string>
<string name="sk_notify_poll_results">Torthaí na pobalbhreithe</string>
<string name="sk_settings_prefix_reply_cw_with_re">Réimír CW le \"re:\" agus freagra á thabhairt</string>
<string name="sk_filtered">Scagtha: %s</string>
<string name="sk_expand">Leathnaigh</string>
<string name="sk_collapse">Laghdaigh</string>
<string name="sk_settings_collapse_long_posts">Laghdaigh poist an-fhada</string>
<string name="sk_unfinished_attachments">Iatáin á n- uasluchtú</string>
<string name="sk_unfinished_attachments_message">Níor chríochnaigh roinnt ceangaltán uaslódáil.</string>
<string name="sk_follow_as">Lean ó chuntas eile</string>
<string name="sk_followed_as">Leanadh ó %s</string>
<string name="sk_settings_hide_fab">Uathfholaigh Cum cnaipe</string>
<string name="sk_notification_action_replied">Seoladh freagra chuig %s</string>
<string name="sk_in_reply">Mar fhreagra ar</string>
<string name="sk_reply_line_above_avatar">\"Mar fhreagra ar\" líne os cionn avatar</string>
<string name="sk_show_thread">Taispeáin snáithe</string>
<string name="sk_content_type">Cineál inneachair</string>
<string name="sk_content_type_unspecified">Gan sonrú</string>
<string name="sk_settings_content_types_explanation">Ceadaíonn sé cineál ábhair a shocrú cosúil le Markdown agus post á chruthú. Coinnigh i gcuimhne nach dtacaíonn gach cás leis seo.</string>
<string name="sk_settings_default_content_type_explanation">Ligeann sé seo duit cineál ábhair a réamhroghnú agus poist nua á gcruthú agat, rud a sháraíonn an luach atá leagtha síos i \"Sainroghanna postála\".</string>
<string name="sk_open_in_app_failed">Níorbh fhéidir oscailt san fheidhmchlár</string>
<string name="sk_external_share_title">Comhroinn le cuntas</string>
<string name="sk_external_share_or_open_title">Comhroinn nó oscail le cuntas</string>
<string name="sk_no_remote_info_hint">Níl eolas cianda ar fáil</string>
<string name="sk_error_loading_profile">Theip ar luchtú na próifíle trí %s</string>
<string name="sk_settings_allow_remote_loading">Luchtaigh faisnéis ó chásanna cianda</string>
<string name="sk_exclusive_list">Liosta eisiach</string>
<string name="sk_list_exclusive_switch">Déan liosta eisiach</string>
<string name="sk_advanced_options_hide">Folaigh ardroghanna</string>
<string name="sk_spoiler_show">Taispeáin inneachar</string>
<string name="sk_settings_instance">Cuir i gcás</string>
<string name="sk_disable_pill_shaped_active_indicator">Díchumasaigh táscaire cluaisín gníomhach pill-chruthach</string>
<string name="sk_settings_display_pronouns_in_threads">Taispeáin forainmneacha i snáitheanna</string>
<string name="sk_settings_display_pronouns_in_user_listings">Taispeáin forainmneacha i liostaí úsáideora</string>
<string name="sk_tab_home">Baile</string>
<string name="sk_tab_search">Cuardaigh</string>
<string name="sk_tab_notifications">Fógraí</string>
<string name="sk_tab_profile">Próifíl</string>
<string name="sk_settings_show_labels_in_navigation_bar">Taispeáin lipéid na gcluaisíní sa bharra nascleanúna</string>
<string name="sk_settings_emoji_reactions">Cumasaigh frithghníomhartha emoji</string>
<string name="sk_settings_emoji_reactions_explanation">Taispeánann sé frithghníomhartha emoji do phoist agus ligeann duit mise a chur leis. Tacaíonn freastalaithe Fediverse éagsúla leis seo, ach ní dhéanann Mastodon.</string>
<string name="sk_settings_show_emoji_reactions_hide_empty">Folaigh frithghníomhartha emoji folamh</string>
<string name="sk_settings_show_emoji_reactions_only_opened">Ach amháin nuair a osclaítear an post</string>
<string name="sk_settings_show_emoji_reactions_always">Taispeáin cnaipe cuir leis i gcónaí</string>
<string name="sk_button_react">Imoibrigh le emoji</string>
<string name="sk_enter_emoji_toast">Clóscríobh emoji le do thoil</string>
<string name="sk_enter_emoji_hint">Clóscríobh emoji nó cuardaigh</string>
<string name="sk_mute_label">Fad ama</string>
<string name="sk_duration_indefinite">Éiginnte</string>
<string name="sk_duration_minutes_5">5 nóiméad</string>
<string name="sk_duration_minutes_30">30 nóiméad</string>
<string name="sk_duration_hours_1">1 uair an chloig</string>
<string name="sk_duration_hours_6">6 uair an chloig</string>
<string name="sk_duration_days_1">1 lá</string>
<string name="sk_duration_days_3">laethanta 3</string>
<string name="sk_search_suicide_title">Ar fhaitíos go mbeadh tú i gcruachás…</string>
<string name="sk_duration_days_7">laethanta 7</string>
<string name="sk_notification_mention">Luaigh %s thú</string>
<string name="sk_suicide_search_terms">Féinmharú</string>
<string name="sk_search_suicide_message">Má tá comhartha á lorg agat gan féinmharú a dhéanamh, seo é. Smaoinigh ar dhul i dteagmháil le beolíne fhéinmharaithe áitiúil má tá tú i gcruachás.</string>
<string name="sk_search_suicide_hotlines">Aimsigh líne chabhrach</string>
<string name="sk_do_not_show_again">Ná taispeáin arís</string>
<string name="sk_suicide_helplines_url">https://findahelpline.com</string>
<string name="sk_load_missing_posts_above">Luchtaigh poist níos nuaí</string>
<string name="sk_load_missing_posts_below">Luchtaigh poist níos sine</string>
<string name="sk_recently_used">Úsáidte le déanaí</string>
<string name="sk_settings_crash_log_unavailable">Níl aon cheann ar fáil... fós</string>
<string name="sk_crash_log_copied">Cóipeáladh logchomhad tuairteála</string>
<string name="sk_open_post_preview">Post réamhamhairc</string>
<string name="sk_post_preview">Réamhamharc</string>
<string name="sk_poll_multiple_choice">Roghanna éagsúla</string>
<string name="sk_settings_local_only_explanation">Ní mór le do chás baile tacú le postáil áitiúil amháin chun go n-oibreoidh sé seo. Déanann an chuid is mó de na leaganacha modhnaithe de Mastodon, ach ní dhéanann Mastodon.</string>
</resources>

View file

@ -76,4 +76,41 @@
<string name="mo_double_tap_to_swipe_between_tabs">Thoir gnogag dhùbailte airson grad-shlaighdeadh eadar tabaichean</string>
<string name="mo_confirm_unfollow">Dearbh nach lean thu %s tuilleadh</string>
<string name="mo_show_media_preview">Seall ro-sheallaidhean meadhain sna loidhnichean-ama</string>
<string name="mo_settings_remove_tracking_params_summary">Rùisg fiosrachadh tracaidh o cheanglaichean</string>
<string name="mo_settings_remove_tracking_params">Ceanglaichean prìobhaideach</string>
<string name="mo_error_display_copy_error_details">Dèan lethbhreac dhen mhion-fhiosrachadh</string>
<string name="mo_muted_conversation_successfully">Chaidh an còmhradh a mhùchadh</string>
<string name="mo_confirm_to_mute_conversation">A bheil thu cinnteach gu bheil thu airson an còmhradh seo a mhùchadh?</string>
<string name="mo_mute_hashtag">Mùch an taga hais</string>
<string name="mo_unmute_hashtag">Dì-mhùch an taga hais</string>
<string name="mo_confirm_to_mute_hashtag">A bheil thu cinnteach gu bheil thu airson an taga hais seo a mhùchadh?</string>
<string name="mo_confirm_to_unmute_hashtag">A bheil thu cinnteach gu bheil thu airson an taga hais seo a dhì-mhùchadh?</string>
<string name="mo_filter_notifications">Criathraich na brathan</string>
<string name="mo_notification_filter_reset">Ath-shuidhich air a bhun-roghainn</string>
<string name="mo_instance_view_info">Seall fiosrachadh an fhrithealaiche</string>
<string name="mo_personal_note_saved">Chaidh an nòta a shàbhaladh</string>
<string name="mo_unmuted_conversation_successfully">Chaidh an còmhradh a dhì-mhùchadh</string>
<string name="mo_muting">Ga mhùchadh…</string>
<string name="mo_unmuting">Ga dhì-mhùchadh…</string>
<string name="mo_mute_conversation">Mùch an còmhradh</string>
<string name="mo_unmute_conversation">Dì-mhùch an còmhradh</string>
<string name="mo_confirm_to_unmute_conversation">A bheil thu cinnteach gu bheil thu airson an còmhradh seo a dhì-mhùchadh?</string>
<string name="mo_settings_unifiedpush_warning">Chan eil UnifiedPush an comas</string>
<string name="mo_settings_unifiedpush_warning_no_distributors">Cha deach sgaoileadair UnifiedPush a stàladh. Chan fhaigh thu brath sam bith.</string>
<string name="mo_settings_unifiedpush_warning_disabled">Chan eil UnifiedPush an comas. Chan fhaigh thu brath sam bith.</string>
<string name="mo_settings_unifiedpush_enable">Cuir an comas</string>
<string name="mo_muted_accounts">Cunntasan mùchte</string>
<string name="mo_blocked_accounts">Cunntasan gam bacadh</string>
<string name="mo_mute_notifications">A bheil thu airson na brathan on chleachdaiche seo fhalach?</string>
<string name="import_settings_confirm">Dearbh ion-phortadh nan roghainnean</string>
<string name="import_settings_confirm_body">Thèid sgrìobhadh thairis air gach roghainn s loidhne-ama làithreach! Cha ghabh seo a neo-dhèanamh.</string>
<string name="import_settings_failed">Dhfhàillig ion-phortadh nan roghainnean</string>
<string name="export_settings_share">Às-phortaich na roghainnean</string>
<string name="export_settings_fail">Dhfhàillig às-phortadh nan roghainnean</string>
<string name="export_settings_title">Às-phortaich na roghainnean</string>
<string name="export_settings_summary">Às-phortaich na roghainnean s loidhnichean-ama aig gach cunntas a tha clàraichte a-staigh</string>
<string name="import_settings_title">Ion-phortaich roghainnean</string>
<string name="import_settings_summary">Ion-phortaich roghainnean s loidhnichean-ama a chaidh às-phortadh roimhe</string>
<string name="mo_error_display_title">Dhfhàillig le sealltainn a phuist</string>
<string name="mo_error_display_text">Chaidh rudeigin ceàrr le luchdadh a phuist. Ma mhaireas an duilgheadas, dèan aithris air duilleag nan Issues againn le mion-fhiosrachadh na mearachd.</string>
</resources>

View file

@ -161,7 +161,7 @@
<string name="sk_settings_prefix_reply_cw_with_re">Cuir ro-leasachan “re:” ris an rabhadh susbainte nuair a bhios tu a freagairt</string>
<string name="sk_expand">Leudaich</string>
<string name="sk_settings_collapse_long_posts">Co-theannaich postaichean glè fhada</string>
<string name="sk_unfinished_attachments">A bheil thu airson na ceanglachain a chàradh\?</string>
<string name="sk_unfinished_attachments">A luchdadh suas nan ceanglachan</string>
<string name="sk_unfinished_attachments_message">Chan eil luchdadh suas nan ceanglachan uile deiseil.</string>
<string name="sk_follow_as">Lean le cunntas eile</string>
<string name="sk_followed_as">Ga leantainn le %s</string>
@ -321,8 +321,8 @@
<string name="sk_settings_auto_reveal_anyone">Freagairtean le duine sam bith</string>
<string name="sk_settings_content_types_explanation">Leigidh seo leat seòrsa susbainte ma Markdown a shuidheachadh nuair a chruthaicheas tu post. Thoir an aire nach cuir gach ionstans taic ri seo.</string>
<string name="sk_tab_home">Dachaigh</string>
<string name="sk_settings_show_emoji_reactions_hide_empty">Falaich freagairtean Emoji falamh</string>
<string name="sk_settings_show_emoji_reactions">Seall freagairtean Emoji air loidhnichean-ama</string>
<string name="sk_settings_show_emoji_reactions_hide_empty">Falaich frith-ghnìomhan Emoji falamh</string>
<string name="sk_settings_show_emoji_reactions">Seall frith-ghnìomhan Emoji air loidhnichean-ama</string>
<plurals name="sk_posts_count_label">
<item quantity="one">phost</item>
<item quantity="two">phost</item>
@ -331,7 +331,7 @@
</plurals>
<string name="sk_notification_mention">Thug %s iomradh ort</string>
<string name="sk_open_in_app">Fosgail san aplacaid</string>
<string name="sk_settings_emoji_reactions">Cuir an comas freagairtean Emoji</string>
<string name="sk_settings_emoji_reactions">Cuir an comas frith-ghnìomhan Emoji</string>
<string name="sk_suicide_search_terms">Fèin-mhurt</string>
<string name="sk_duration_minutes_5">5 mionaidean</string>
<string name="sk_advanced_options_show">Seall na roghainnean adhartach</string>
@ -356,7 +356,7 @@
<string name="sk_advanced_options_hide">Falaich na roghainnean adhartach</string>
<string name="sk_duration_hours_1">Uair a thìde</string>
<string name="sk_duration_hours_6">6 uairean a thìde</string>
<string name="sk_enter_emoji_hint">Sgrìobh rudeigin airson freagairt le Emoji</string>
<string name="sk_enter_emoji_hint">Cuit a-steach Emoji no lorg</string>
<string name="sk_duration_days_7">Seachdain</string>
<string name="sk_settings_true_black">Modh dubh dorcha</string>
<string name="sk_no_remote_info_hint">chan eil am fiosrachadh cèin ri fhaighinn</string>
@ -366,13 +366,13 @@
<string name="sk_settings_display_pronouns_in_threads">Seall na riochdairean ann an snàithleanan</string>
<string name="sk_error_loading_profile">Dhfhàillig le luchdadh na pròifil slighe %s</string>
<string name="sk_enter_emoji_toast">Cuir a-steach Emoji</string>
<string name="sk_trending_posts_info_banner">Seo na postaichean fèillmhor air an fhrithealaiche agad.</string>
<string name="sk_trending_posts_info_banner">Seo na postaichean fèillmhor air a cho-shaoghal.</string>
<string name="sk_duration_minutes_30">Leth-uair a thìde</string>
<string name="sk_settings_display_pronouns_in_user_listings">Seall na riochdairean air liostaichean luchd-cleachdadh</string>
<string name="sk_button_react">Freagair le emoji</string>
<string name="sk_duration_days_1">Latha</string>
<string name="sk_load_missing_posts_below">Luchdaich na postaichean nas sine</string>
<string name="sk_settings_emoji_reactions_explanation">Seallaidh seo freagairtean Emoji do phostaichean is leigidh e leat an fheadhainn agad fhèin a chur ris. Cuiridh grunn fhrithealaichean a cho-shaoghail taic ri seo ach cha chuir Mastodon.</string>
<string name="sk_settings_emoji_reactions_explanation">Seallaidh seo frith-ghnìomhan Emoji do phostaichean is leigidh e leat an fheadhainn agad fhèin a chur ris. Cuiridh grunn fhrithealaichean a cho-shaoghail taic ri seo ach cha chuir Mastodon.</string>
<string name="sk_external_share_title">Co-roinn le cunntas</string>
<string name="sk_list_exclusive_switch">Dèan an liosta às-dùnach</string>
<string name="sk_duration_days_3">3 làithean</string>
@ -388,10 +388,45 @@
<item quantity="other">Fhreagair %1$,d luchd-cleachdaidh le %2$s</item>
</plurals>
<string name="sk_search_suicide_message">Ma tha thu a sireadh samhla nach cuir thu às dhiot fhèin, seo e. Saoil am bruidhinn thu ri loidhne theth ionadail mu fhèin-mhurt ma tha iomagain ort\?</string>
<string name="sk_trending_links_info_banner">Seo na sgeulachdan naidheachd air a bheilear a bruidhinn air an fhrithealaiche agad.</string>
<string name="sk_trending_links_info_banner">Seo na sgeulachdan naidheachd air a bheilear a bruidhinn air a cho-shaoghal.</string>
<string name="sk_search_fediverse">Lorg air a cho-shaoghal</string>
<string name="sk_post_contains_media">Tha meadhan sa phost</string>
<string name="sk_tab_notifications">Brathan</string>
<string name="sk_list_exclusive_switch_explanation">Cha nochd buill liosta às-dùnaich air loidhne-ama na dachaighe agad ma chuireas an t-ionstans agad taic ri seo.</string>
<string name="sk_pronouns_label">Riochdairean</string>
<string name="sk_settings_color_palette_default">Bun-roghainn (%s)</string>
<string name="sk_icon_water">Uisge</string>
<string name="sk_icon_sun">Grian</string>
<string name="sk_icon_sunset">Laighe na grèine</string>
<string name="sk_icon_cloud">Neul</string>
<string name="sk_icon_thunderstorm">Gailleann</string>
<string name="sk_icon_rain">An t-uisge</string>
<string name="sk_posted">Phostaich %s</string>
<string name="sk_edit_alt_text">Deasaich an roghainn teacsa</string>
<string name="sk_settings_clear_timeline_cache">Glan tasgadan na dachaigh</string>
<string name="sk_button_mutuals">Co-dhàimhean</string>
<string name="sk_icon_snowflake">Bleideag sneachda</string>
<string name="sk_muted_accounts">Cunntasan mùchte</string>
<string name="sk_blocked_accounts">Cunntasan gam bacadh</string>
<string name="sk_settings_like_icon">Cleachd cridhe na ìomhaigheag annsachd</string>
<string name="sk_recently_used">Air a chleachdadh o chionn goirid</string>
<string name="sk_settings_underlined_links">Fo-loidhnich ceanglaichean</string>
<string name="sk_set_as_default">Suidhich mar a bhun-roghainn</string>
<string name="sk_timeline_cache_cleared">Chaidh tasgadan na dachaigh a ghlanadh</string>
<string name="sk_settings_lock_account">Aontaich ri luchd-leantainn ùra a làimh</string>
<string name="sk_settings_default_visibility">Faicsinneachd bhunaiteach nam post</string>
<string name="sk_private_note_hint">Cuir ris nòta pearsanta mun phròifil seo</string>
<string name="sk_confirm_changes">Dearbh na h-atharraichean</string>
<string name="sk_private_note_update_failed">Dhfhàillig le sàbhaladh an nòta</string>
<string name="sk_private_note_confirm_delete">A bheil thu airson an nòta pearsanta mu %s a sguabadh às?</string>
<string name="sk_delete_note">Sguab às an nòta pearsanta</string>
<string name="sk_add_note">Cuir nòta pearsanta ris</string>
<string name="sk_settings_copy_crash_log">Dèan lethbhreac dhen loga tuislidh as ùire</string>
<string name="sk_settings_crash_log_unavailable">Chan eil gin ri fhaighinn… fhathast</string>
<string name="sk_crash_log_copied">Chaidh lethbhreac dhen loga tuislidh a dhèanamh</string>
<string name="sk_open_post_preview">Ro-sheall am post</string>
<string name="sk_post_preview">Ro-sheall</string>
<string name="sk_poll_multiple_choice">Iomadh roghainn</string>
<string name="sk_poll_show_results">Seall na toraidhean</string>
<string name="sk_poll_hide_results">Falaich na toraidhean</string>
</resources>

View file

@ -114,4 +114,5 @@
<string name="mo_error_display_text">Algo fallou ao cargar esta publicación. Se o problema persiste, informa dos detalles do problema na nosa páxina de Incidencias.</string>
<string name="mo_settings_remove_tracking_params">Ligazóns privadas</string>
<string name="mo_settings_remove_tracking_params_summary">Retirar os parámetros de rastrexo das ligazóns</string>
<string name="mo_personal_note_saved">Gardouse a nota</string>
</resources>

View file

@ -94,4 +94,26 @@
<string name="mo_setting_haptic_feedback_summary">Bergetar ketika berinteraksi dengan kiriman</string>
<string name="mo_confirm_to_mute_hashtag">Apakah Anda yakin ingin membisukan tagar ini\?</string>
<string name="mo_notification_filter_reset">Atur ulang ke bawaan</string>
<string name="mo_settings_remove_tracking_params">Tautan Pribadi</string>
<string name="mo_error_display_text">Ada yang salah saat memuat kiriman ini. Jika masalah terus berlanjut, silakan laporkan di laman Isu serta dengan detail kesalahan.</string>
<string name="mo_settings_remove_tracking_params_summary">Hilangkan informasi pelacak dari tautan</string>
<string name="mo_instance_view_info">Tampilkan Info Server</string>
<string name="mo_mute_notifications">Sembunyikan notifikasi dari pengguna ini?</string>
<string name="mo_settings_unifiedpush_warning">UnifiedPush tidak diaktifkan</string>
<string name="mo_settings_unifiedpush_warning_no_distributors">Tidak ada distributor UnifiedPush yang terpasang. Anda tidak akan menerima notifikasi.</string>
<string name="mo_settings_unifiedpush_warning_disabled">UnifiedPush tidak diaktifkan. Anda tidak akan menerima notifikasi.</string>
<string name="mo_settings_unifiedpush_enable">Aktifkan</string>
<string name="import_settings_confirm">Konfirmasi mengimpor pengaturan?</string>
<string name="import_settings_confirm_body">Semua pengaturan dan lini masa saat ini akan ditimpa! Ini tidak dapat diurungkan.</string>
<string name="import_settings_failed">Gagal mengimpor pengaturan</string>
<string name="export_settings_share">Pengaturan Pengeksporan</string>
<string name="export_settings_fail">Gagal mengekspor pengaturan</string>
<string name="export_settings_summary">Ekspor semua pengaturan dan lini masa dari semua akun yang masuk</string>
<string name="import_settings_title">Impor pengaturan</string>
<string name="export_settings_title">Ekspor pengaturan</string>
<string name="mo_personal_note_saved">Catatan disimpan</string>
<string name="import_settings_summary">Impor pengaturan dan lini masa yang sebelumnya diekspor</string>
<string name="mo_error_display_title">Gagal menampilkan kiriman</string>
<string name="mo_error_display_copy_error_details">Salin detail</string>
<string name="mo_trending_link_read">Baca</string>
</resources>

View file

@ -113,4 +113,5 @@
<string name="mo_mute_hashtag">Silenzia hashtag</string>
<string name="mo_unmute_hashtag">Riattiva hashtag</string>
<string name="mo_instance_view_info">Visualizza informazioni Server</string>
<string name="mo_personal_note_saved">Nota salvata</string>
</resources>

View file

@ -71,4 +71,47 @@
<string name="mo_notification_action_replied">%s さんの投稿への返信に成功しました</string>
<string name="mo_load_remote_followers">リモートプロフィールのフォローとフォロワーを読み込む</string>
<string name="mo_color_palette_black_and_white">白黒</string>
<string name="mo_settings_remove_tracking_params_summary">リンクからトラッキング情報を削除</string>
<string name="mo_trending_link_read">既読</string>
<string name="mo_muted_conversation_successfully">会話を正常にミュートしました</string>
<string name="mo_unmuted_conversation_successfully">会話のミュートを解除しました</string>
<string name="mo_muting">ミュート中…</string>
<string name="mo_unmuting">ミュートを解除中…</string>
<string name="mo_mute_conversation">会話をミュート</string>
<string name="mo_confirm_to_unmute_conversation">この会話をミュート解除してもよろしいですか?</string>
<string name="mo_mute_hashtag">ハッシュタグをミュート</string>
<string name="mo_blocked_accounts">ブロックしたアカウント</string>
<string name="mo_show_media_preview">タイムラインにメディアプレビューを表示</string>
<string name="mo_filter_notifications">通知をフィルタリング</string>
<string name="mo_recent_emoji_cleared">最近の絵文字がクリアされました</string>
<string name="mo_notification_filter_reset">デフォルトにリセット</string>
<string name="mo_double_tap_to_search">ダブルタップして検索を開く</string>
<string name="mo_confirm_to_mute_hashtag">このハッシュタグをミュートしてもよろしいですか?</string>
<string name="mo_unmute_conversation">会話のミュートを解除</string>
<string name="mo_muted_accounts">ミュートしたアカウント</string>
<string name="mo_personal_note_saved">ノートが保存されました</string>
<string name="mo_instance_view_info">サーバー情報を表示</string>
<string name="mo_settings_show_posts_without_alt_summary">投稿はすべてのタイムラインで非表示になりますが、スレッドや通知では表示されます</string>
<string name="mo_error_display_text">この投稿の読み込み中に問題が発生しました。問題が解決しない場合は、エラーの詳細を添えて私たちのIssuesページに報告してください。</string>
<string name="mo_confirm_to_mute_conversation">この会話をミュートしてもよろしいですか?</string>
<string name="mo_settings_show_posts_without_alt">代替テキストがないメディア投稿を表示</string>
<string name="mo_mute_notifications">このユーザーからの通知を非表示にしますか?</string>
<string name="mo_settings_unifiedpush_warning">UnifiedPushが有効になっていません</string>
<string name="mo_settings_unifiedpush_warning_no_distributors">UnifiedPushディストリビューターがインストールされていないため、通知を受け取ることができません。</string>
<string name="mo_settings_unifiedpush_warning_disabled">UnifiedPushが有効になっていないため、通知を受け取ることができません。</string>
<string name="mo_settings_unifiedpush_enable">有効</string>
<string name="import_settings_confirm">設定をインポートしてもよろしいですか?</string>
<string name="import_settings_confirm_body">現在のすべての設定とタイムラインが上書きされます!この操作は元に戻せません。</string>
<string name="import_settings_failed">設定のインポートに失敗しました</string>
<string name="export_settings_share">設定をエクスポート</string>
<string name="export_settings_fail">設定のエクスポートに失敗しました</string>
<string name="export_settings_title">設定をエクスポート</string>
<string name="export_settings_summary">すべてのログイン中のアカウントの設定とタイムラインをエクスポート</string>
<string name="import_settings_title">設定をインポート</string>
<string name="import_settings_summary">以前にエクスポートした設定とタイムラインをインポート</string>
<string name="mo_error_display_title">投稿の表示に失敗しました</string>
<string name="mo_error_display_copy_error_details">詳細をコピー</string>
<string name="mo_unmute_hashtag">ハッシュタグのミュートを解除</string>
<string name="mo_confirm_to_unmute_hashtag">このハッシュタグをミュート解除してもよろしいですか?</string>
<string name="mo_settings_remove_tracking_params">プライベートリンク</string>
</resources>

View file

@ -401,4 +401,31 @@
<string name="sk_icon_thunderstorm">雷雨</string>
<string name="sk_open_in_app_failed">アプリで開くことができませんでした</string>
<string name="sk_private_note_confirm_delete">%s に関するパーソナルメモを削除しますか?</string>
<string name="sk_settings_reply_visibility_following">フォローしている人への返信</string>
<string name="sk_trending_links_info_banner">これらのニュース記事はフェディバース全体で話題になっています。</string>
<string name="sk_alt_text_missing">少なくとも1つの添付ファイルに説明が含まれていません。</string>
<string name="sk_posted">%s が投稿しました</string>
<string name="sk_settings_local_only_explanation">この機能が動作するためには、あなたのホームインスタンスがローカル専用投稿をサポートしている必要があります。ほとんどの修正されたMastodonのバージョンはこれをサポートしていますが、Mastodonはサポートしていません。</string>
<string name="sk_reacted">%s がリアクションしました</string>
<string name="sk_settings_prefix_reply_cw_with_re">返信する際は、CWを「re:」で始めてください</string>
<string name="sk_content_type_unspecified">指定されていません</string>
<string name="sk_external_share_or_open_title">アカウントで共有または開く</string>
<string name="sk_settings_prefix_replies_always">誰にでも</string>
<string name="sk_settings_prefix_replies_never">無効にする</string>
<string name="sk_settings_forward_report_default">「報告を転送」スイッチのデフォルト</string>
<plurals name="sk_users_reacted_with">
<item quantity="other">%1$,d人のユーザーが%2$sで反応しました</item>
</plurals>
<string name="sk_search_suicide_message">もし自殺を考えているなら、これはあなたに対するメッセージです。辛い時は、お住いの地域の自殺防止ホットラインに連絡することを考えてみてください。</string>
<string name="sk_open_post_preview">投稿のプレビュー</string>
<string name="sk_poll_multiple_choice">複数の選択肢</string>
<string name="sk_poll_show_results">結果を表示</string>
<string name="sk_poll_hide_results">結果を隠す</string>
<string name="sk_settings_content_types_explanation">投稿を作成する際に、Markdownのようなコンテンツタイプを設定できるようにします。ただし、すべてのインスタンスがこれをサポートしているわけではないことに注意してください。</string>
<string name="sk_reply_line_above_avatar">アバターの上の「返信先」行</string>
<string name="sk_settings_prefix_replies_to_others">他の人への返信のみ</string>
<string name="sk_reacted_with">%1$s が %2$s でリアクションしました</string>
<string name="sk_settings_default_content_type_explanation">これにより、新しい投稿を作成する際にコンテンツタイプを事前に選択でき、「投稿設定」で設定された値を上書きすることができます。</string>
<string name="sk_edit_timeline_tags_explanation">これらの操作はサーバーによって処理されることに注意してください。これらを組み合わせることはサポートされていない可能性があります。</string>
<string name="sk_post_preview">プレビュー</string>
</resources>

View file

@ -407,4 +407,11 @@
<string name="sk_edit_alt_text">대체 텍스트 편집</string>
<string name="sk_settings_unifiedpush">UnifiedPush 사용</string>
<string name="sk_pronouns_label">인칭 대명사</string>
<string name="sk_icon_water"></string>
<string name="sk_icon_sun">태양</string>
<string name="sk_icon_sunset">일몰</string>
<string name="sk_icon_cloud">구름</string>
<string name="sk_icon_thunderstorm">번개구름</string>
<string name="sk_icon_rain"></string>
<string name="sk_icon_snowflake">눈꽃</string>
</resources>

View file

@ -113,4 +113,5 @@
<string name="import_settings_confirm_body">Visi esami nustatymai ir laiko skalės bus perrašyti! Šio veiksmo atšaukti negalima.</string>
<string name="import_settings_summary">Importuok anksčiau eksportuotus nustatymus ir laiko skales.</string>
<string name="mo_error_display_text">Įkeliant šį įrašą kažkas nutiko ne taip. Jei problema išlieka, pranešk apie tai mūsų problemų puslapyje ir nurodyk klaidos informaciją.</string>
<string name="mo_personal_note_saved">Išsaugota pastaba</string>
</resources>

View file

@ -3,12 +3,12 @@
<string name="sk_pinned_posts">Prisegta</string>
<string name="sk_confirm_pin_post_title">Prisegti įrašą prie profilio</string>
<string name="sk_confirm_unpin_post_title">Atsegti įrašą iš profilio</string>
<string name="sk_confirm_pin_post">Ar nori prisegti šį įrašą prie savo profilio?</string>
<string name="sk_confirm_delete_and_redraft">Ar tikrai nori ištrinti ir iš naujo parengti šį įrašą?</string>
<string name="sk_confirm_pin_post">Ar norite prisegti šį įrašą prie savo profilio?</string>
<string name="sk_confirm_delete_and_redraft">Ar tikrai norite ištrinti ir iš naujo parengti šį įrašą?</string>
<string name="sk_pin_post">Prisegti prie profilio</string>
<string name="sk_pinning">Prisegimas įrašas…</string>
<string name="sk_unpin_post">Atsegti iš profilio</string>
<string name="sk_confirm_unpin_post">Ar tikrai nori atsegti šį įrašą?</string>
<string name="sk_confirm_unpin_post">Ar tikrai norite atsegti šį įrašą?</string>
<string name="sk_unpinning">Atsegimas įrašas…</string>
<string name="sk_image_description">Vaizdo aprašymas</string>
<string name="sk_settings_show_replies">Rodyti atsakymus</string>
@ -22,9 +22,9 @@
<string name="sk_mark_media_as_sensitive">Žymėti mediją kaip jautrią</string>
<string name="sk_user_post_notifications_on">Įjungta įrašų pranešimai naudotojui %s</string>
<string name="sk_federated_timeline">Federacija</string>
<string name="sk_federated_timeline_info_banner">Tai naujausi įrašai, kuriuos paskelbė žmonės tavo federacijoje.</string>
<string name="sk_bubble_timeline_info_banner">Tai naujausi įrašai iš tinklo, kuriuos kuruoja tavo serverio administratoriai.</string>
<string name="sk_trending_links_info_banner">Tai naujienų istorijos, kurios kalbamoms visoje Fediversijoje.</string>
<string name="sk_federated_timeline_info_banner">Tai naujausi įrašai, kuriuos paskelbė asmenys jūsų federacijoje.</string>
<string name="sk_bubble_timeline_info_banner">Tai naujausi įrašai iš tinklo, kuriuos kuruoja jūsų serverio administratoriai.</string>
<string name="sk_trending_links_info_banner">Tai naujienų istorijos, kurios kalbamoms visoje fediversijoje.</string>
<string name="sk_update_available">„Megalodon“ %s paruoštas atsisiųsti.</string>
<string name="sk_check_for_update">Tikrinti, ar yra naujinimas</string>
<string name="sk_list_timelines">Sąrašai</string>
@ -69,7 +69,7 @@
<string name="sk_settings_translate_only_opened">Versti tik atvirus įrašus</string>
<string name="sk_settings_translation_availability_note_available">%s palaiko vertimą!</string>
<string name="sk_settings_translation_availability_note_unavailable">%s atrodo, kad nepalaiko vertimo.</string>
<string name="sk_loading_fediverse_resource_title">Ieškoma Fediversijoje</string>
<string name="sk_loading_fediverse_resource_title">Ieškoma fediversijoje</string>
<string name="sk_loading_resource_on_instance_title">Ieškoma serveryje %s</string>
<string name="sk_undo_reblog">Atšaukti pasidalinimą</string>
<string name="sk_quote_post">Skelbti apie tai</string>
@ -125,7 +125,7 @@
<string name="sk_resource_not_found">Išteklių nepavyko rasti.</string>
<string name="sk_bookmarked_as">Pridėta kaip %s</string>
<string name="sk_save_draft_message">Ar nori išsaugoti šio juodraščio pakeitimus, ar paskelbti jį dabar?</string>
<string name="sk_settings_continues_playback_summary">Leisk toliau leisti jau leidžiamą mediją, uždengiant naująjį įrašo peržiūrą.</string>
<string name="sk_settings_continues_playback_summary">Leiskite toliau paleisti jau leidžiamą mediją, uždengiant naująjį įrašo peržiūrą.</string>
<string name="sk_settings_show_boosts">Rodyti pasidalinimus</string>
<string name="sk_reject_follow_request">Atmesti sekimo prašymą</string>
<string name="sk_color_palette_red">Raudona</string>
@ -153,7 +153,7 @@
<string name="sk_compose_draft">Įrašas bus išsaugotas kaip juodraštis.</string>
<string name="sk_private_note_update_failed">Nepavyko išsaugoti pastabos.</string>
<string name="sk_schedule">Planuoti</string>
<string name="sk_trending_posts_info_banner">Tai įrašai, kurie šiuo metu sulaukia vis daugiau dėmesio Fediversijoje.</string>
<string name="sk_trending_posts_info_banner">Tai įrašai, kurie šiuo metu sulaukia vis daugiau dėmesio fediversijoje.</string>
<string name="sk_schedule_or_draft">Planuoti arba išsaugoti kaip juodraštį</string>
<string name="sk_notify_update">Redaguoja pasidalintą įrašą</string>
<string name="sk_external_share_title">Bendrinti su paskyra</string>
@ -335,7 +335,7 @@
<string name="sk_settings_instance">Serveris</string>
<string name="sk_disable_pill_shaped_active_indicator">Išjungti piliulės formos aktyvaus skirtuko indikatorių</string>
<string name="sk_settings_true_black">Juodos spalvos režimas</string>
<string name="sk_search_fediverse">Ieškoti Fediversą</string>
<string name="sk_search_fediverse">Ieškoti fediversą</string>
<string name="sk_settings_display_pronouns_in_timelines">Rodyti įvardžius laiko skalėje</string>
<string name="sk_settings_display_pronouns_in_threads">Rodyti įvardžius gijose</string>
<string name="sk_settings_display_pronouns_in_user_listings">Rodyti įvardžius naudotojų sąrašuose</string>
@ -442,5 +442,5 @@
<string name="sk_settings_like_icon">Naudoti širdelę kaip mėgstamą piktogramą</string>
<string name="sk_settings_prefix_replies_always">Atsakant į bet kurį</string>
<string name="sk_settings_show_labels_in_navigation_bar">Rodyti skirtukų etiketes naršymo juostoje</string>
<string name="sk_settings_emoji_reactions_explanation">Rodo jaustukų reakcijas įrašams ir leidžia pridėti savo. Įvairūs Fediverso serveriai tai palaiko, bet įprastas „Mastodon“ ne.</string>
<string name="sk_settings_emoji_reactions_explanation">Rodo jaustukų reakcijas įrašams ir leidžia pridėti savo. Įvairūs fediverso serveriai tai palaiko, bet įprastas „Mastodon“ ne.</string>
</resources>

View file

@ -107,4 +107,13 @@
<string name="import_settings_failed">Import ustawień się nie powiódł</string>
<string name="export_settings_fail">Nie udało się wyeksportować ustawień</string>
<string name="mo_error_display_title">Nie udało się wyświetlić wpisu</string>
<string name="mo_settings_remove_tracking_params_summary">Usuń z linków parametry służące do śledzenia użytkoników</string>
<string name="mo_settings_remove_tracking_params">Linki bez parametrów śledzących</string>
<string name="mo_settings_unifiedpush_warning_no_distributors">Nie zainstalowano UnifiedPush Distributors. Nie możliwe będzie otrzymywanie powiadomień.</string>
<string name="mo_settings_unifiedpush_warning_disabled">UnifiedPush nie jest włączone. Niemożliwe będzie otrzymywanie powiadomień.</string>
<string name="import_settings_confirm_body">Wszystkie obecne ustawienia i osie czasu zostaną nadpisane! Nie można tego cofnąć.</string>
<string name="import_settings_summary">Importuj wcześniej wyeksportowane ustawienia i osie czasu</string>
<string name="mo_personal_note_saved">Zapisano notatkę</string>
<string name="export_settings_summary">Eksportuj wszystkie ustawienia i osie czasu z zalogowanych kont</string>
<string name="mo_error_display_text">Wystąpił błąd podczas ładowania tego wpisu. Jeżeli problem się powtarza prosimy zgłosić go na naszej stronie Zgłoszeń wraz z infomacjami o błędzie.</string>
</resources>

View file

@ -448,4 +448,5 @@
<string name="sk_add_timeline_tag_error_empty">Hashtag nie może być pusty</string>
<string name="sk_list_exclusive_switch_explanation">Członkowie listy na wyłączność nie będą wyświetlani na głównej osi czasu — jeśli Twoja instancja ją obsługuje.</string>
<string name="sk_icon_beaker">Szkło laboratoryjne</string>
<string name="sk_posted">Nowy wpis %s</string>
</resources>

View file

@ -115,4 +115,5 @@
<string name="mo_trending_link_read">Citiți</string>
<string name="mo_settings_remove_tracking_params_summary">Eliminați informațiile de urmărire din linkuri</string>
<string name="mo_settings_remove_tracking_params">Linkuri private</string>
<string name="mo_personal_note_saved">Notă salvată</string>
</resources>

View file

@ -1,3 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="sk_app_name">Megalodon</string>
<string name="sk_pinned_posts">Sabitlenmiş</string>
</resources>

View file

@ -6,7 +6,7 @@
<string name="mo_color_palette_nord">Nord</string>
<string name="mo_disable_dividers">Вимкнути роздільники публікацій</string>
<string name="mo_relocate_publish_button">Перемістити кнопку «Опублікувати»</string>
<string name="mo_hide_compose_button_while_scrolling_setting">Сховати кнопку «Нова публікація» під час прокручування</string>
<string name="mo_hide_compose_button_while_scrolling_setting">Сховати кнопку «Новий допис» під час прокручування</string>
<string name="mo_personal_note">Додати нотатку до цього профілю</string>
<string name="mo_personal_note_confirm">Підтвердити зміни</string>
<string name="mo_personal_note_update_failed">Не вдалося зберегти нотатку</string>
@ -34,7 +34,7 @@
<string name="mo_download_latest_nightly_release">Встановити останній нічний реліз</string>
<string name="mo_notification_action_replied">Успішно надіслано відповідь на публікацію від %s</string>
<string name="mo_change_default_reply_visibility_to_unlisted">За замовчуванням відповідати як «Прихований»</string>
<string name="mo_composer_behavior">Поведінка екрану створення публікації</string>
<string name="mo_composer_behavior">Поведінка екрана створення публікації</string>
<string name="mo_miscellaneous_settings">Інші Налаштування</string>
<string name="mo_duration_minutes_5">5 хвилин</string>
<string name="mo_disable_double_tap_to_swipe_between_tabs">Вимкнути подвійне тицяння для перемикання між вкладками</string>
@ -116,4 +116,5 @@
<string name="mo_mute_hashtag">Заблокувати хештег</string>
<string name="mo_unmute_hashtag">Розблокувати хештег</string>
<string name="mo_confirm_to_unmute_hashtag">Ви впевнені що хочете розблокувати цей хештег?</string>
<string name="mo_personal_note_saved">Нотатку збережено</string>
</resources>

View file

@ -57,7 +57,7 @@
<string name="sk_settings_show_federated_timeline">Показувати федеративну стрічку</string>
<string name="sk_example_domain">example.social</string>
<string name="sk_welcome_title">Вітаємо!</string>
<string name="sk_welcome_text">Акулка вітає вас! Щоб розпочати, введіть нижче доменне імя вашого сервера.</string>
<string name="sk_welcome_text">Акулка вітає вас! Щоб розпочати, введіть нижче доменне ім\'я вашого сервера.</string>
<string name="sk_settings_profile">Налаштувати профіль</string>
<string name="sk_settings_posting">Налаштувати постинг</string>
<string name="sk_settings_filters">Налаштувати фільтри</string>
@ -366,7 +366,7 @@
<item quantity="many">%1$,d користувачів зреагували %2$s</item>
<item quantity="other">%1$,d користувачів зреагували %2$s</item>
</plurals>
<string name="sk_button_react">Реагуйте за допомогою емоджі</string>
<string name="sk_button_react">Реагувати за допомогою емоджі</string>
<string name="sk_again_for_system_keyboard">Торкніться ще раз, щоб відкрити системну клавіатуру</string>
<string name="sk_settings_emoji_reactions">Увімкнути реакції з емоджі</string>
<string name="sk_settings_emoji_reactions_explanation">Показує реакції емоджі на дописи та дає змогу додавати свої. Різні сервери Федісвіту підтримують цю функцію, але Mastodon не підтримує.</string>

View file

@ -97,4 +97,24 @@
<string name="mo_notification_filter_reset">重置为默认值</string>
<string name="mo_instance_view_info">查看服务器信息</string>
<string name="mo_mute_notifications">隐藏来自此用户的通知?</string>
<string name="mo_settings_remove_tracking_params_summary">删除链接中的跟踪信息</string>
<string name="import_settings_confirm">确认导入设置?</string>
<string name="mo_settings_unifiedpush_warning">未启用 UnifiedPush</string>
<string name="mo_settings_unifiedpush_warning_no_distributors">未安装 UnifiedPush 分发程序。您将不会收到任何通知。</string>
<string name="mo_settings_unifiedpush_warning_disabled">未启用 UnifiedPush。您将不会收到任何通知。</string>
<string name="mo_settings_unifiedpush_enable">启用</string>
<string name="import_settings_confirm_body">所有当前设置和时间线将被覆盖!此操作无法撤销。</string>
<string name="import_settings_failed">导入设置失败</string>
<string name="export_settings_share">导出设置</string>
<string name="export_settings_fail">导出设置失败</string>
<string name="export_settings_title">导出设置</string>
<string name="export_settings_summary">导出所有已登录账户的设置和时间线</string>
<string name="import_settings_title">导入设置</string>
<string name="import_settings_summary">导入先前导出的设置和时间线</string>
<string name="mo_error_display_title">显示帖文失败</string>
<string name="mo_error_display_text">加载此帖文时出了问题。如果问题仍然存在,请在我们的工单页面上报告,并提供错误详情。</string>
<string name="mo_settings_remove_tracking_params">链接隐私保护</string>
<string name="mo_error_display_copy_error_details">复制详情</string>
<string name="mo_trending_link_read">阅读</string>
<string name="mo_personal_note_saved">备注已保存</string>
</resources>

View file

@ -289,8 +289,8 @@
<string name="sk_settings_content_types">启用嘟文格式</string>
<string name="sk_settings_content_types_explanation">允许在创建文章时设置类似Markdown的内容类型。注意不是所有的实例都支持这个。</string>
<string name="sk_settings_default_content_type">默认的内容类型</string>
<string name="sk_timeline_bubble">Bubble</string>
<string name="sk_icon_feed">Feed</string>
<string name="sk_timeline_bubble">气泡</string>
<string name="sk_icon_feed">食物</string>
<string name="sk_settings_default_content_type_explanation">这可以让你在创建新帖子时预选内容类型,覆盖 \"发帖偏好 \"中设置的值。</string>
<string name="sk_instance_info_unavailable">实例信息暂时不可用</string>
<string name="sk_open_in_app">在应用程序中打开</string>
@ -427,4 +427,5 @@
<string name="sk_poll_multiple_choice">多选</string>
<string name="sk_poll_show_results">显示结果</string>
<string name="sk_suicide_helplines_url">https://findahelpline.com</string>
<string name="sk_posted">%s 发布了</string>
</resources>

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="mo_color_palette_black_and_white">黑白</string>
</resources>

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