Compare commits

...

150 Commits

Author SHA1 Message Date
sk
646f83ff0a boop verison 2023-09-08 22:19:41 +02:00
sk
fdf0414698 fix missing banner icons and wrong strings
closes sk22#805
2023-09-08 22:05:06 +02:00
sk
cc699a3f5e fix spacing stuff in report fragment 2023-09-08 21:58:08 +02:00
LucasGGamerM
12eaa8d5f1 fix: fix window insets on ScheduledStatusListFragment
cc: @sk22
2023-09-08 21:49:29 +02:00
sk22
70680e39c6 Translated using Weblate (German)
Currently translated at 100.0% (384 of 384 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/de/
2023-09-08 19:46:45 +00:00
sk
8bd8f90d58 remove unused strings 2023-09-08 21:44:31 +02:00
edxkl
54b53a266e Translated using Weblate (Portuguese (Brazil))
Currently translated at 93.2% (362 of 388 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/pt_BR/
2023-09-08 19:40:59 +00:00
sk22
66921e3b5a Translated using Weblate (German)
Currently translated at 97.1% (377 of 388 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/de/
2023-09-08 19:40:59 +00:00
sk22
9d7af3964b Translated using Weblate (English)
Currently translated at 100.0% (388 of 388 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/en/
2023-09-08 19:40:59 +00:00
ihor_ck
ec73687e9b Translated using Weblate (Ukrainian)
Currently translated at 100.0% (382 of 382 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/uk/
2023-09-08 19:17:03 +00:00
Choukajohn
c8af800b88 Translated using Weblate (French)
Currently translated at 100.0% (382 of 382 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/fr/
2023-09-08 19:17:02 +00:00
gallegonovato
e74ac5da56 Translated using Weblate (Spanish)
Currently translated at 99.4% (380 of 382 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/es/
2023-09-08 19:17:02 +00:00
sk
efa003a9a5 implement bidirectional missing posts gap 2023-09-08 21:16:42 +02:00
butterflyoffire
de5165434d Translated using Weblate (Arabic)
Currently translated at 16.6% (3 of 18 strings)

Translation: Megalodon/metadata
Translate-URL: https://translate.codeberg.org/projects/megalodon/metadata/ar/
2023-09-08 15:43:13 +00:00
sk
be648cc5ab Merge remote-tracking branch 'upstream/l10n_master' 2023-09-08 17:42:47 +02:00
sk
90f1f464dc reset strings.xml to upstream 2023-09-08 17:41:30 +02:00
sk
734aa52816 Merge remote-tracking branch 'weblate/main' 2023-09-08 17:37:31 +02:00
sk
068d42175e Merge remote-tracking branch 'upstream/master' 2023-09-08 17:37:00 +02:00
sk
2314871246 temporary fix for pre-release users 2023-09-08 17:36:17 +02:00
butterflyoffire
e4f13c900b Translated using Weblate (Arabic)
Currently translated at 67.5% (250 of 370 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/ar/
2023-09-07 19:23:10 +00:00
ppnplus
4ddfa483d4 Translated using Weblate (Thai)
Currently translated at 23.5% (87 of 370 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/th/
2023-09-07 19:23:10 +00:00
butterflyoffire
20f41ce7c9 Translated using Weblate (Kabyle)
Currently translated at 0.5% (2 of 370 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/kab/
2023-09-07 19:23:10 +00:00
Arkxv
c8df9e085e Translated using Weblate (Japanese)
Currently translated at 78.3% (290 of 370 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/ja/
2023-09-07 19:23:10 +00:00
GunChleoc
0238aa4375 Translated using Weblate (Gaelic)
Currently translated at 84.3% (312 of 370 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/gd/
2023-09-07 19:23:09 +00:00
butterflyoffire
79d7873790 Translated using Weblate (French)
Currently translated at 100.0% (370 of 370 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/fr/
2023-09-07 19:23:09 +00:00
kallekn
996842489d Translated using Weblate (Finnish)
Currently translated at 100.0% (370 of 370 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/fi/
2023-09-07 19:23:09 +00:00
Andrewblasco
23c2c2b5e7 Translated using Weblate (Spanish)
Currently translated at 100.0% (370 of 370 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/es/
2023-09-07 19:23:08 +00:00
sk
9dd694ce2e Merge branch 'merge/load-more-direction' 2023-09-07 18:32:21 +02:00
FineFindus
f51f2a1197 fix: use random account id in notification endpoint (#806)
Closes https://github.com/sk22/megalodon/issues/803. This was due to registering with the actual accounId, whilst saving a random one. Once receiving a notification, the id could not be found.
2023-09-07 18:28:32 +02:00
LucasGGamerM
3020cab243 fix: fixes crashes when currentQuery is null and suicide prevention dialog is enabled (#807)
cc: @FineFindus
2023-09-07 10:03:22 +02:00
Eugen Rochko
be73c9e81c New translations strings.xml (Basque) 2023-09-07 02:28:42 +02:00
Eugen Rochko
1c2183bf1a New translations strings.xml (Slovenian) 2023-09-06 22:29:03 +02:00
Gregory K
1789d90dc3 Merge pull request #685 from LucasGGamerM/mastodon-android
fix(editing-alt-text): fix small oversight on editing existing attachments without alt text
2023-09-06 01:42:41 +03:00
LucasGGamerM
57306ff7fe fix(editing-alt-text): fix small oversight on editing existing attachments without alt text
This makes the implementation hopefully bug free
2023-09-05 19:37:12 -03:00
sk
2aba90f353 add media indicator for spoiler
closes sk22#598
2023-09-05 00:18:47 +02:00
sk
5065c7e7e2 add dummy to add spacing
closes sk22#782
2023-09-04 23:42:00 +02:00
sk
a10e661b21 fix wrong info banner color
closes sk22#790
2023-09-04 23:37:34 +02:00
sk
4975bde76f fix tab layout horizontal paddings 2023-09-04 23:33:35 +02:00
FineFindus
ebbd56e3bc feat(search): show suicide help dialog (#767)
* feat(search): show suicide help dialog

* change wording, add helpline url, change behavior

---------

Co-authored-by: sk <sk22@mailbox.org>
2023-09-04 23:07:24 +02:00
Jacoco
454ec6b4c0 Fix errors when some entries were missing when retrieving account information (#757)
* Handle null avatar

* Handle empty account
2023-09-04 22:24:17 +02:00
FineFindus
10a8b195b1 fix: move tabbar padding to tabbar items (#792)
* feat: increase padding without labels

* fix: move tabbar padding to individual items
2023-09-04 22:19:47 +02:00
sk
6f273df060 use single-line linear layout 2023-09-04 19:54:07 +02:00
sk
7cfade62d3 fix click listener target 2023-09-04 19:53:33 +02:00
starstuff
0a338ad607 Translated using Weblate (Swedish)
Currently translated at 41.6% (154 of 370 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/sv/
2023-09-04 08:05:19 +00:00
Arkxv
0cb3e1863e Translated using Weblate (Japanese)
Currently translated at 5.4% (20 of 370 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/ja/
2023-09-04 08:05:19 +00:00
kallekn
209081f1f0 Translated using Weblate (Finnish)
Currently translated at 0.8% (3 of 370 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/fi/
2023-09-04 08:05:19 +00:00
Eugen Rochko
f0eb6573f4 New translations strings.xml (Portuguese, Brazilian) 2023-09-04 08:10:24 +02:00
Eugen Rochko
e7f5dd3357 New translations strings.xml (Bengali) 2023-09-04 07:10:06 +02:00
Eugen Rochko
8101bb9ea1 New translations strings.xml (Portuguese, Brazilian) 2023-09-04 07:10:05 +02:00
butterflyoffire
54d48253d5 Translated using Weblate (Arabic)
Currently translated at 12.4% (46 of 370 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/ar/
2023-09-04 00:53:06 +00:00
ca
3373b2bb04 Translated using Weblate (Catalan)
Currently translated at 100.0% (18 of 18 strings)

Translation: Megalodon/metadata
Translate-URL: https://translate.codeberg.org/projects/megalodon/metadata/ca/
2023-09-04 00:53:06 +00:00
ca
a7e23aa228 Translated using Weblate (Catalan)
Currently translated at 100.0% (370 of 370 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/ca/
2023-09-04 00:53:06 +00:00
FineFindus
8cd55fc365 feat: display icon for bots (#793)
* feat(profile): display bot icon for bots

* feat(status): display bot icon

* use 16sp size and 4sp spacing

* don't add lock/bot icon as image spans

---------

Co-authored-by: sk <sk22@mailbox.org>
2023-09-03 21:34:22 +02:00
LucasGGamerM
f14df2bb0f fix: allows for editing timeline badges again. fixes sk22#800 (#804) 2023-09-03 20:49:29 +02:00
Eugen Rochko
228fdc8ffe New translations strings.xml (Swedish) 2023-09-03 11:26:37 +02:00
Angelo Suzuki
2d24e50ff2 Add a setting for "Load missing posts behavior"
This will make sure that items that are filtered out don't show up on the interface.
Fixes sk22#311
2023-09-01 21:51:14 +02:00
Jacoco
53369eb2d4 Fix unreliable Preferences from Account Source (#798)
* Create empty Preferences object on error

* Update prefs from account when preferences fails
2023-09-01 21:28:02 +02:00
Eugen Rochko
e9df125cde New translations strings.xml (Swedish) 2023-09-01 16:10:32 +02:00
sk
807010893a support static url for emoji reacts and keyboard 2023-09-01 14:38:55 +02:00
sk
ea01b14ffb more options for showing emoji reactions
closes sk22#796
re: sk22#788
2023-09-01 14:23:38 +02:00
arnav
3fd9dc1dcd Translated using Weblate (Hindi)
Currently translated at 4.3% (16 of 370 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/hi/
2023-08-31 23:18:52 +00:00
sk
02a4a77885 Merge remote-tracking branch 'weblate/main' 2023-09-01 01:18:30 +02:00
sk
651090a504 Merge remote-tracking branch 'upstream/master' 2023-09-01 01:17:18 +02:00
sk
203254c9f4 fix crash in onEmojiReactionsChanged 2023-09-01 01:16:52 +02:00
Gregory K
16ef577a7a Merge pull request #678 from LucasGGamerM/mastodon-android
fix: fix alt texts not being able to be edited
2023-08-31 20:31:39 +03:00
LucasGGamerM
734b3bced6 fix: fix alt texts not being able to be edited
fixes #70 cc: @sk22
2023-08-31 14:18:32 -03:00
sk
e26c641dc7 fix drafts being all on the same-ish day 2023-08-31 18:07:43 +02:00
sk
9295cf4e9c fix emoji reaction spacing not updating
closes sk22#784
2023-08-31 17:24:29 +02:00
sk
dd9237e9ca enable emojiReactionsInTimelines by default 2023-08-31 17:20:44 +02:00
sk
ea81c1fad6 Merge remote-tracking branch 'upstream/master' 2023-08-31 17:09:18 +02:00
sk
d334703c65 adhere to showEmojiReactionsInLists setting
closes sk22#788
2023-08-31 17:04:22 +02:00
Gregory K
5f6f3c94c9 Merge pull request #677 from tinsukE/gap-local-filter
When loading gap posts, apply filters before building display items.
2023-08-31 15:06:07 +03:00
Angelo Suzuki
09ba42a974 When loading gap posts, apply filters before building display items.
This will make sure that items that are filtered out don't show up on the interface.
Fixes #675
2023-08-31 14:01:58 +02:00
ihor_ck
b1e43d6f97 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (370 of 370 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/uk/
2023-08-30 18:04:05 +00:00
ppnplus
ea92a61d13 Translated using Weblate (Thai)
Currently translated at 20.5% (76 of 370 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/th/
2023-08-30 18:04:05 +00:00
Linerly
7fda69a6aa Translated using Weblate (Indonesian)
Currently translated at 100.0% (370 of 370 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/id/
2023-08-30 18:04:05 +00:00
gallegonovato
cf8b9ac649 Translated using Weblate (Spanish)
Currently translated at 100.0% (370 of 370 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/es/
2023-08-30 18:04:05 +00:00
ppnplus
3c122b005d Translated using Weblate (Thai)
Currently translated at 3.7% (14 of 370 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/th/
2023-08-29 22:37:15 +00:00
edxkl
f9dc6105f4 Translated using Weblate (Portuguese (Brazil))
Currently translated at 97.5% (361 of 370 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/pt_BR/
2023-08-29 22:37:15 +00:00
Oliebol
d7fe3c80e6 Translated using Weblate (Dutch)
Currently translated at 82.9% (307 of 370 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/nl/
2023-08-29 22:37:15 +00:00
Choukajohn
e996deea0b Translated using Weblate (French)
Currently translated at 100.0% (370 of 370 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/fr/
2023-08-29 22:37:14 +00:00
S1m
580ae15af6 Fix unifiedpush (#785)
* [UnifiedPush] Register the new endpoint

* [UnifiedPush] Get account linked to instance
2023-08-29 12:22:12 +02:00
Eugen Rochko
d76e823489 New translations strings.xml (Italian) 2023-08-29 11:52:38 +02:00
sk
e66078e52e fix poll options outline provider
closes sk22#702
2023-08-29 00:53:02 +02:00
FineFindus
f84356f5d0 fix: display 'Lists with' with username (#780) 2023-08-29 00:19:34 +02:00
sk
1fa5a8436b highlight verified links again!
closes sk22#713
2023-08-29 00:18:12 +02:00
sk
2a471ffa96 fix broken "edit avatar" overlay.. again!!
closes sk22#727
closes sk22#738
2023-08-28 23:48:18 +02:00
sk
1ee5e1ab3a fix cut-off settings item titles
closes sk22#723
2023-08-28 23:42:34 +02:00
sk
4d90cad034 Merge remote-tracking branch 'weblate/main' 2023-08-28 23:35:18 +02:00
sk
45615b1fc5 Merge remote-tracking branch 'upstream/l10n_master' 2023-08-28 23:35:04 +02:00
sk
9fd0e7fea4 return if fcm device token is empty
closes sk22#779
2023-08-28 23:33:28 +02:00
sk
696016bd8f use hasSpoiler method 2023-08-28 23:29:18 +02:00
sk
cc46e09853 fix issue with visibility button
closes sk22#740
2023-08-28 23:24:56 +02:00
sk
83e84836b5 fix slightly wrong margins
closes sk22#778
2023-08-28 22:47:43 +02:00
sk
14bb544344 replace donation link 2023-08-28 22:35:17 +02:00
sk
ceec18ff5e fix divider not being full-width 2023-08-28 22:33:19 +02:00
sk
d36ad43700 fix reporting crashing the app 2023-08-28 22:26:53 +02:00
sk
fb39f74ba5 fix bottom padding for above emoji reactions 2023-08-28 20:22:16 +02:00
sk
9bfc73d6ee fix wrong bottom padding
hopefully, lol
2023-08-28 20:04:52 +02:00
EndermanCo
efb72eace9 Translated using Weblate (Persian)
Currently translated at 50.0% (9 of 18 strings)

Translation: Megalodon/metadata
Translate-URL: https://translate.codeberg.org/projects/megalodon/metadata/fa/
2023-08-28 14:53:05 +00:00
edxkl
84b15f4a49 Translated using Weblate (Portuguese (Brazil))
Currently translated at 97.5% (360 of 369 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/pt_BR/
2023-08-28 14:53:05 +00:00
ca
2c793fd83b Translated using Weblate (Catalan)
Currently translated at 100.0% (369 of 369 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/ca/
2023-08-28 14:53:05 +00:00
Eugen Rochko
900b204bb0 New translations strings.xml (Portuguese, Brazilian) 2023-08-27 16:51:00 +02:00
Eugen Rochko
17d679901a New translations strings.xml (Japanese) 2023-08-27 15:42:52 +02:00
Eugen Rochko
d8036779f8 New translations strings.xml (Japanese) 2023-08-27 14:46:15 +02:00
0que
3a35674ea2 Translated using Weblate (Russian)
Currently translated at 77.7% (14 of 18 strings)

Translation: Megalodon/metadata
Translate-URL: https://translate.codeberg.org/projects/megalodon/metadata/ru/
2023-08-27 05:53:05 +00:00
0que
3235cf1c4f Translated using Weblate (Russian)
Currently translated at 89.7% (331 of 369 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/ru/
2023-08-27 05:53:04 +00:00
Eugen Rochko
3f6bda28b3 New translations strings.xml (Vietnamese) 2023-08-26 17:43:48 +02:00
Eugen Rochko
c0b4f4dd79 New translations strings.xml (Vietnamese) 2023-08-26 16:06:27 +02:00
starstuff
2a913e26e7 Translated using Weblate (Swedish)
Currently translated at 41.4% (153 of 369 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/sv/
2023-08-25 14:53:06 +00:00
edxkl
f60375cd5f Translated using Weblate (Portuguese (Brazil))
Currently translated at 97.0% (358 of 369 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/pt_BR/
2023-08-25 14:53:06 +00:00
poesty
5920270899 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (369 of 369 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/zh_Hans/
2023-08-25 14:53:06 +00:00
Eugen Rochko
f36aee44c6 New translations strings.xml (Scottish Gaelic) 2023-08-25 09:54:23 +02:00
Eugen Rochko
cd24526a9d New translations strings.xml (Swedish) 2023-08-24 17:48:37 +02:00
Eugen Rochko
a345ac1390 New translations strings.xml (Icelandic) 2023-08-24 17:48:36 +02:00
Eugen Rochko
3d987b8e1d New translations strings.xml (Thai) 2023-08-23 21:39:07 +02:00
Eugen Rochko
57043912e0 New translations strings.xml (Chinese Traditional) 2023-08-23 19:16:40 +02:00
Eugen Rochko
00aef5ea6b New translations full_description.txt (Arabic) 2023-08-23 13:02:31 +02:00
Eugen Rochko
369b69668c New translations strings.xml (Arabic) 2023-08-23 13:02:29 +02:00
Eugen Rochko
65245f4560 New translations strings.xml (Arabic) 2023-08-23 09:39:50 +02:00
Eugen Rochko
4d4fdc97d4 New translations strings.xml (French) 2023-08-23 09:39:49 +02:00
Eugen Rochko
c96577891c New translations strings.xml (Scottish Gaelic) 2023-08-23 07:00:18 +02:00
Eugen Rochko
f48b2fc9cb New translations strings.xml (Thai) 2023-08-23 07:00:13 +02:00
Eugen Rochko
2fca2580ed New translations strings.xml (Bengali) 2023-08-23 07:00:12 +02:00
Eugen Rochko
7adc1da361 New translations strings.xml (Persian) 2023-08-23 07:00:11 +02:00
Eugen Rochko
6dc24dde43 New translations strings.xml (Indonesian) 2023-08-23 07:00:10 +02:00
Eugen Rochko
4929e0e6ec New translations strings.xml (Portuguese, Brazilian) 2023-08-23 07:00:09 +02:00
Eugen Rochko
16a8b8ed71 New translations strings.xml (Icelandic) 2023-08-23 07:00:08 +02:00
Eugen Rochko
ad1412817e New translations strings.xml (Galician) 2023-08-23 07:00:07 +02:00
Eugen Rochko
d9e6bb3bea New translations strings.xml (Vietnamese) 2023-08-23 07:00:06 +02:00
Eugen Rochko
8970404638 New translations strings.xml (Chinese Traditional) 2023-08-23 07:00:05 +02:00
Eugen Rochko
2a2241d7f9 New translations strings.xml (Chinese Simplified) 2023-08-23 07:00:04 +02:00
Eugen Rochko
db1a47e8eb New translations strings.xml (Ukrainian) 2023-08-23 07:00:03 +02:00
Eugen Rochko
3e57061cef New translations strings.xml (Turkish) 2023-08-23 07:00:02 +02:00
Eugen Rochko
cd200f8450 New translations strings.xml (Slovenian) 2023-08-23 07:00:00 +02:00
Eugen Rochko
782013079f New translations strings.xml (Russian) 2023-08-23 06:59:59 +02:00
Eugen Rochko
e5db8acd66 New translations strings.xml (Polish) 2023-08-23 06:59:57 +02:00
Eugen Rochko
1a6a8019c8 New translations strings.xml (Norwegian) 2023-08-23 06:59:57 +02:00
Eugen Rochko
e935eef29f New translations strings.xml (Dutch) 2023-08-23 06:59:56 +02:00
Eugen Rochko
381defda51 New translations strings.xml (Japanese) 2023-08-23 06:59:54 +02:00
Eugen Rochko
02ae80c204 New translations strings.xml (Italian) 2023-08-23 06:59:53 +02:00
Eugen Rochko
82214b30e8 New translations strings.xml (Armenian) 2023-08-23 06:59:52 +02:00
Eugen Rochko
33a1f48602 New translations strings.xml (Greek) 2023-08-23 06:59:48 +02:00
Eugen Rochko
aee845e5cc New translations strings.xml (German) 2023-08-23 06:59:47 +02:00
Eugen Rochko
cd780f6006 New translations strings.xml (Danish) 2023-08-23 06:59:46 +02:00
Eugen Rochko
d4741fefa0 New translations strings.xml (Czech) 2023-08-23 06:59:46 +02:00
Eugen Rochko
7e1e8a2616 New translations strings.xml (Belarusian) 2023-08-23 06:59:44 +02:00
Eugen Rochko
d73c05cdfc New translations strings.xml (Arabic) 2023-08-23 06:59:43 +02:00
Eugen Rochko
78323023cb New translations strings.xml (Spanish) 2023-08-23 06:59:42 +02:00
Eugen Rochko
2cf084c98f New translations strings.xml (French) 2023-08-23 06:59:41 +02:00
137 changed files with 2908 additions and 638 deletions

1
.github/FUNDING.yml vendored
View File

@@ -3,7 +3,6 @@
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # mastodon
open_collective: # Replace with a single Open Collective username e.g., user1
ko_fi: xsk22
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username e.g., user1

View File

@@ -15,8 +15,8 @@ android {
applicationId "org.joinmastodon.android.sk"
minSdk 23
targetSdk 33
versionCode 98
versionName "2.0.3+fork.98"
versionCode 99
versionName "2.0.3+fork.99"
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']
}

View File

@@ -25,6 +25,8 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import androidx.annotation.StringRes;
public class GlobalUserPreferences{
private static final String TAG="GlobalUserPreferences";
@@ -60,6 +62,7 @@ public class GlobalUserPreferences{
public static boolean showNavigationLabels;
public static boolean displayPronounsInTimelines, displayPronounsInThreads, displayPronounsInUserListings;
public static boolean overlayMedia;
public static boolean showSuicideHelp;
private static SharedPreferences getPrefs(){
return MastodonApp.context.getSharedPreferences("global", Context.MODE_PRIVATE);
@@ -119,6 +122,7 @@ public class GlobalUserPreferences{
displayPronounsInThreads=prefs.getBoolean("displayPronounsInThreads", true);
displayPronounsInUserListings=prefs.getBoolean("displayPronounsInUserListings", true);
overlayMedia=prefs.getBoolean("overlayMedia", false);
showSuicideHelp=prefs.getBoolean("showSuicideHelp", true);
if (prefs.contains("prefixRepliesWithRe")) {
prefixReplies = prefs.getBoolean("prefixRepliesWithRe", false)
@@ -177,6 +181,7 @@ public class GlobalUserPreferences{
.putBoolean("displayPronounsInThreads", displayPronounsInThreads)
.putBoolean("displayPronounsInUserListings", displayPronounsInUserListings)
.putBoolean("overlayMedia", overlayMedia)
.putBoolean("showSuicideHelp", showSuicideHelp)
.apply();
}

View File

@@ -325,7 +325,7 @@ public class PushNotificationReceiver extends BroadcastReceiver{
req.visibility = preferences.postingDefaultVisibility;
req.inReplyToId = notification.status.id;
if (!notification.status.spoilerText.isEmpty() &&
if (notification.status.hasSpoiler() &&
(GlobalUserPreferences.prefixReplies == ALWAYS
|| (GlobalUserPreferences.prefixReplies == TO_OTHERS && !ownID.equals(notification.status.account.id)))
&& !notification.status.spoilerText.startsWith("re: ")) {

View File

@@ -27,9 +27,9 @@ public class UnifiedPushNotificationReceiver extends MessagingReceiver{
public void onNewEndpoint(@NotNull Context context, @NotNull String endpoint, @NotNull String instance) {
// Called when a new endpoint be used for sending push messages
Log.d(TAG, "onNewEndpoint: New Endpoint " + endpoint + " for "+ instance);
AccountSession account = AccountSessionManager.getInstance().getLastActiveAccount();
AccountSession account = AccountSessionManager.getInstance().tryGetAccount(instance);
if (account != null)
account.getPushSubscriptionManager().registerAccountForPush(null);
account.getPushSubscriptionManager().registerAccountForPush(null, endpoint);
}
@Override
@@ -37,7 +37,7 @@ public class UnifiedPushNotificationReceiver extends MessagingReceiver{
// called when the registration is not possible, eg. no network
Log.d(TAG, "onRegistrationFailed: " + instance);
//re-register for gcm
AccountSession account = AccountSessionManager.getInstance().getLastActiveAccount();
AccountSession account = AccountSessionManager.getInstance().tryGetAccount(instance);
if (account != null)
account.getPushSubscriptionManager().registerAccountForPush(null);
}
@@ -47,7 +47,7 @@ public class UnifiedPushNotificationReceiver extends MessagingReceiver{
// called when this application is unregistered from receiving push messages
Log.d(TAG, "onUnregistered: " + instance);
//re-register for gcm
AccountSession account = AccountSessionManager.getInstance().getLastActiveAccount();
AccountSession account = AccountSessionManager.getInstance().tryGetAccount(instance);
if (account != null)
account.getPushSubscriptionManager().registerAccountForPush(null);
}
@@ -55,7 +55,10 @@ public class UnifiedPushNotificationReceiver extends MessagingReceiver{
@Override
public void onMessage(@NotNull Context context, @NotNull byte[] message, @NotNull String instance) {
// Called when a new message is received. The message contains the full POST body of the push message
AccountSession account = AccountSessionManager.getInstance().getAccount(instance);
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,

View File

@@ -97,7 +97,7 @@ public class PushSubscriptionManager{
deviceToken=getPrefs().getString("deviceToken", null);
int tokenVersion=getPrefs().getInt("version", 0);
if(!TextUtils.isEmpty(deviceToken) && tokenVersion==BuildConfig.VERSION_CODE){
registerAllAccountsForPush(false);
registerAllAccountsForPush(true); // TODO: revert this before release
return;
}
Log.i(TAG, "tryRegisterFCM: no token found or app was updated. Trying to get push token...");
@@ -125,17 +125,16 @@ public class PushSubscriptionManager{
// this function is used for registering push notifications using FCM
// to avoid NonFreeNet in F-Droid, this registration is disabled in it
// see https://github.com/LucasGGamerM/moshidon/issues/206 for more context
if(BuildConfig.BUILD_TYPE.equals("fdroidRelease"))
if(BuildConfig.BUILD_TYPE.equals("fdroidRelease") || TextUtils.isEmpty(deviceToken)){
Log.d(TAG, "Skipping registering for FCM push notifications");
return;
}
if(TextUtils.isEmpty(deviceToken))
throw new IllegalStateException("No device push token available");
String endpoint = "https://app.joinmastodon.org/relay-to/fcm/"+deviceToken+"/"+accountID;
String endpoint = "https://app.joinmastodon.org/relay-to/fcm/"+deviceToken+"/";
registerAccountForPush(subscription, endpoint);
}
public void registerAccountForPush(PushSubscription subscription, String endpoint){
MastodonAPIController.runInBackground(()->{
Log.d(TAG, "registerAccountForPush: started for "+accountID);
String encodedPublicKey, encodedAuthKey, pushAccountID;
@@ -164,7 +163,13 @@ public class PushSubscriptionManager{
Log.e(TAG, "registerAccountForPush: error generating encryption key", e);
return;
}
new RegisterForPushNotifications(endpoint,
//work-around for adding the randomAccountId
String newEndpoint = endpoint;
if (endpoint.startsWith("https://app.joinmastodon.org/relay-to/fcm/"))
newEndpoint += pushAccountID;
new RegisterForPushNotifications(newEndpoint,
encodedPublicKey,
encodedAuthKey,
subscription==null ? PushSubscription.Alerts.ofAll() : subscription.alerts,

View File

@@ -11,13 +11,11 @@ import java.util.ArrayList;
import java.util.List;
public class CreateStatus extends MastodonAPIRequest<Status>{
public static final Instant DRAFTS_AFTER_INSTANT = Instant.ofEpochMilli(253370764799999L) /* end of 9998 */;
private static final float draftFactor = 31536000000f /* one year */ / 253370764799999f /* end of 9998 */;
public static long EPOCH_OF_THE_YEAR_FIVE_THOUSAND=95617584000000L;
public static final Instant DRAFTS_AFTER_INSTANT=Instant.ofEpochMilli(EPOCH_OF_THE_YEAR_FIVE_THOUSAND - 1) /* end of 4999 */;
public static Instant getDraftInstant() {
// returns an instant between 9999-01-01 00:00:00 and 9999-12-31 23:59:59
// yes, this is a weird implementation for something that hardly matters
return DRAFTS_AFTER_INSTANT.plusMillis(1 + (long) (System.currentTimeMillis() * draftFactor));
return DRAFTS_AFTER_INSTANT.plusMillis(System.currentTimeMillis());
}
public CreateStatus(CreateStatus.Request req, String uuid){
@@ -36,6 +34,7 @@ public class CreateStatus extends MastodonAPIRequest<Status>{
public static class Request{
public String status;
public List<MediaAttribute> mediaAttributes;
public List<String> mediaIds;
public Poll poll;
public String inReplyToId;
@@ -55,5 +54,17 @@ public class CreateStatus extends MastodonAPIRequest<Status>{
public boolean multiple;
public boolean hideTotals;
}
public static class MediaAttribute{
public String id;
public String description;
public String focus;
public MediaAttribute(String id, String description, String focus){
this.id=id;
this.description=description;
this.focus=focus;
}
}
}
}

View File

@@ -13,7 +13,6 @@ import org.joinmastodon.android.model.TimelineDefinition;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
public class AccountLocalPreferences{
private final SharedPreferences prefs;
@@ -39,7 +38,7 @@ public class AccountLocalPreferences{
public boolean keepOnlyLatestNotification;
public boolean emojiReactionsEnabled;
public boolean showEmojiReactionsInLists;
public ShowEmojiReactions showEmojiReactions;
private final static Type recentLanguagesType = new TypeToken<ArrayList<String>>() {}.getType();
private final static Type timelinesType = new TypeToken<ArrayList<TimelineDefinition>>() {}.getType();
@@ -66,7 +65,7 @@ public class AccountLocalPreferences{
timelineReplyVisibility=prefs.getString("timelineReplyVisibility", null);
keepOnlyLatestNotification=prefs.getBoolean("keepOnlyLatestNotification", false);
emojiReactionsEnabled=prefs.getBoolean("emojiReactionsEnabled", session.getInstance().isPresent() && session.getInstance().get().isAkkoma());
showEmojiReactionsInLists=prefs.getBoolean("showEmojiReactionsInLists", false);
showEmojiReactions=ShowEmojiReactions.valueOf(prefs.getString("showEmojiReactions", ShowEmojiReactions.HIDE_EMPTY.name()));
}
public long getNotificationsPauseEndTime(){
@@ -99,7 +98,13 @@ public class AccountLocalPreferences{
.putString("timelineReplyVisibility", timelineReplyVisibility)
.putBoolean("keepOnlyLatestNotification", keepOnlyLatestNotification)
.putBoolean("emojiReactionsEnabled", emojiReactionsEnabled)
.putBoolean("showEmojiReactionsInLists", showEmojiReactionsInLists)
.putString("showEmojiReactions", showEmojiReactions.name())
.apply();
}
public enum ShowEmojiReactions{
HIDE_EMPTY,
ONLY_OPENED,
ALWAYS
}
}

View File

@@ -146,6 +146,9 @@ public class AccountSession{
@Override
public void onError(ErrorResponse error){
Log.w(TAG, "Failed to load preferences for account "+getID()+": "+error);
if (preferences==null)
preferences=new Preferences();
preferencesFromAccountSource(self);
}
})
.exec(getID());
@@ -310,4 +313,10 @@ public class AccountSession{
.authority(getInstance().map(i -> i.normalizedUri).orElse(domain))
.build();
}
public String getDefaultAvatarUrl() {
return getInstance()
.map(instance->"https://"+domain+(instance.isAkkoma() ? "/images/avi.png" : "/avatars/original/missing.png"))
.orElse("");
}
}

View File

@@ -0,0 +1,19 @@
package org.joinmastodon.android.events;
import androidx.recyclerview.widget.RecyclerView;
import org.joinmastodon.android.model.EmojiReaction;
import java.util.List;
public class EmojiReactionsUpdatedEvent{
public final String id;
public final List<EmojiReaction> reactions;
public final boolean updateTextPadding;
public RecyclerView.ViewHolder viewHolder;
public EmojiReactionsUpdatedEvent(String id, List<EmojiReaction> reactions, boolean updateTextPadding, RecyclerView.ViewHolder viewHolder){
this.id=id;
this.reactions=reactions;
this.updateTextPadding=updateTextPadding;
this.viewHolder=viewHolder;
}
}

View File

@@ -1,27 +1,14 @@
package org.joinmastodon.android.events;
import androidx.recyclerview.widget.RecyclerView;
import org.joinmastodon.android.api.CacheController;
import org.joinmastodon.android.model.EmojiReaction;
import org.joinmastodon.android.model.Status;
import java.util.ArrayList;
import java.util.List;
public class StatusCountersUpdatedEvent{
public String id;
public long favorites, reblogs, replies;
public boolean favorited, reblogged, bookmarked, pinned;
public List<EmojiReaction> reactions;
public Status status;
public RecyclerView.ViewHolder viewHolder;
public StatusCountersUpdatedEvent(Status s){
this(s, null);
}
public StatusCountersUpdatedEvent(Status s, RecyclerView.ViewHolder vh){
id=s.id;
status=s;
favorites=s.favouritesCount;
@@ -31,7 +18,5 @@ public class StatusCountersUpdatedEvent{
reblogged=s.reblogged;
bookmarked=s.bookmarked;
pinned=s.pinned;
reactions=new ArrayList<>(s.reactions);
viewHolder=vh;
}
}

View File

@@ -617,7 +617,7 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
}
}
public void onGapClick(GapStatusDisplayItem.Holder item){}
public void onGapClick(GapStatusDisplayItem.Holder item, boolean downwards){}
public void onWarningClick(WarningFilteredStatusDisplayItem.Holder warning){
int startPos = warning.getAbsoluteAdapterPosition();

View File

@@ -419,7 +419,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
hasSpoiler=true;
spoilerWrap.setVisibility(View.VISIBLE);
spoilerBtn.setSelected(true);
}else if(editingStatus!=null && !TextUtils.isEmpty(editingStatus.spoilerText)){
}else if(editingStatus!=null && editingStatus.hasSpoiler()){
hasSpoiler=true;
spoilerWrap.setVisibility(View.VISIBLE);
spoilerEdit.setText(getArguments().getString("sourceSpoiler", editingStatus.spoilerText));
@@ -678,7 +678,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
view.findViewById(R.id.time).setVisibility(time==null ? View.GONE : View.VISIBLE);
if(time!=null) ((TextView) view.findViewById(R.id.time)).setText(time);
if (status.spoilerText != null && !status.spoilerText.isBlank()) {
if (status.hasSpoiler()) {
TextView replyToSpoiler = view.findViewById(R.id.reply_to_spoiler);
replyToSpoiler.setVisibility(View.VISIBLE);
replyToSpoiler.setText(status.spoilerText);
@@ -1066,6 +1066,9 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
req.scheduledAt=scheduledAt;
if(!mediaViewController.isEmpty()){
req.mediaIds=mediaViewController.getAttachmentIDs();
if(editingStatus != null){
req.mediaAttributes=mediaViewController.getAttachmentAttributes();
}
}
// ask whether to publish now when editing an existing draft
if (!force && editingStatus != null && scheduledAt != null && scheduledAt.isAfter(DRAFTS_AFTER_INSTANT)) {

View File

@@ -344,7 +344,7 @@ public class EditTimelinesFragment extends MastodonRecyclerFragment<TimelineDefi
mainHashtag = name;
name = null;
}
if (TextUtils.isEmpty(mainHashtag)) {
if (TextUtils.isEmpty(mainHashtag) && (item != null && item.getType() == TimelineDefinition.TimelineType.HASHTAG)) {
Toast.makeText(ctx, R.string.sk_add_timeline_tag_error_empty, Toast.LENGTH_SHORT).show();
onSave.accept(null);
return;

View File

@@ -45,8 +45,8 @@ public class FeaturedHashtagsListFragment extends BaseStatusListFragment<Hashtag
}
@Override
public void onItemClick(String id){
UiUtils.openHashtagTimeline(getActivity(), accountID, id, data.stream().filter(h -> Objects.equals(h.name, id)).findAny().map(h -> h.following).orElse(null));
public void onItemClick(String hashtag){
UiUtils.openHashtagTimeline(getActivity(), accountID, hashtag, data.stream().filter(h -> Objects.equals(h.name, hashtag)).findAny().map(h -> h.following).orElse(null));
}
@Override

View File

@@ -17,8 +17,10 @@ import android.widget.TextView;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.accounts.GetAccountRelationships;
import org.joinmastodon.android.api.requests.accounts.GetFollowRequests;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.HeaderPaginationList;
import org.joinmastodon.android.model.Instance;
import org.joinmastodon.android.model.Relationship;
import org.joinmastodon.android.ui.OutlineProviders;
import org.joinmastodon.android.ui.text.HtmlParser;
@@ -357,8 +359,9 @@ public class FollowRequestsListFragment extends MastodonRecyclerFragment<FollowR
public AccountWrapper(Account account){
this.account=account;
if(!TextUtils.isEmpty(account.avatar))
avaRequest=new UrlImageLoaderRequest(account.avatar, V.dp(50), V.dp(50));
avaRequest=new UrlImageLoaderRequest(
TextUtils.isEmpty(account.avatar) ? AccountSessionManager.get(getAccountID()).getDefaultAvatarUrl() : account.avatar,
V.dp(50), V.dp(50));
if(!TextUtils.isEmpty(account.header))
coverRequest=new UrlImageLoaderRequest(account.header, 1000, 1000);
parsedBio=HtmlParser.parse(account.note, account.emojis, Collections.emptyList(), Collections.emptyList(), accountID);

View File

@@ -13,25 +13,24 @@ import org.joinmastodon.android.api.requests.markers.SaveMarkers;
import org.joinmastodon.android.api.requests.timelines.GetHomeTimeline;
import org.joinmastodon.android.api.session.AccountLocalPreferences;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.events.StatusCreatedEvent;
import org.joinmastodon.android.model.CacheablePaginatedResponse;
import org.joinmastodon.android.model.FilterContext;
import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.model.TimelineMarkers;
import org.joinmastodon.android.ui.displayitems.GapStatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
import org.joinmastodon.android.utils.StatusFilterPredicate;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import me.grishka.appkit.api.Callback;
import me.grishka.appkit.api.ErrorResponse;
import me.grishka.appkit.api.SimpleCallback;
import me.grishka.appkit.utils.V;
public class HomeTimelineFragment extends StatusListFragment {
private HomeTabFragment parent;
@@ -176,15 +175,23 @@ public class HomeTimelineFragment extends StatusListFragment {
}
@Override
public void onGapClick(GapStatusDisplayItem.Holder item){
public void onGapClick(GapStatusDisplayItem.Holder item, boolean downwards){
if(dataLoading)
return;
item.getItem().loading=true;
V.setVisibilityAnimated(item.progress, View.VISIBLE);
V.setVisibilityAnimated(item.text, View.GONE);
GapStatusDisplayItem gap=item.getItem();
gap.loading=true;
dataLoading=true;
currentRequest=new GetHomeTimeline(item.getItemID(), null, 20, null, getLocalPrefs().timelineReplyVisibility)
String maxID = null;
String minID = null;
if (downwards) {
maxID = item.getItemID();
} else {
int gapPos=displayItems.indexOf(gap);
StatusDisplayItem nextItem=displayItems.get(gapPos + 1);
minID=nextItem.parentID;
}
currentRequest=new GetHomeTimeline(maxID, minID, 20, null, getLocalPrefs().timelineReplyVisibility)
.setCallback(new Callback<>(){
@Override
public void onSuccess(List<Status> result){
@@ -204,52 +211,96 @@ public class HomeTimelineFragment extends StatusListFragment {
AccountSessionManager.getInstance().getAccount(accountID).getCacheController().putHomeTimeline(Collections.singletonList(gapStatus), false);
}
}else{
Set<String> idsBelowGap=new HashSet<>();
boolean belowGap=false;
int gapPostIndex=0;
for(Status s:data){
if(belowGap){
idsBelowGap.add(s.id);
}else if(s.id.equals(gap.parentID)){
belowGap=true;
s.hasGapAfter=false;
AccountSessionManager.getInstance().getAccount(accountID).getCacheController().putHomeTimeline(Collections.singletonList(s), false);
}else{
gapPostIndex++;
if(downwards) {
Set<String> idsBelowGap=new HashSet<>();
boolean belowGap=false;
int gapPostIndex=0;
for(Status s:data){
if(belowGap){
idsBelowGap.add(s.id);
}else if(s.id.equals(gap.parentID)){
belowGap=true;
s.hasGapAfter=false;
AccountSessionManager.getInstance().getAccount(accountID).getCacheController().putHomeTimeline(Collections.singletonList(s), false);
}else{
gapPostIndex++;
}
}
}
int endIndex=0;
for(Status s:result){
endIndex++;
if(idsBelowGap.contains(s.id))
break;
}
if(endIndex==result.size()){
result.get(result.size()-1).hasGapAfter=true;
}else{
result=result.subList(0, endIndex);
}
List<StatusDisplayItem> targetList=displayItems.subList(gapPos, gapPos+1);
targetList.clear();
List<Status> insertedPosts=data.subList(gapPostIndex+1, gapPostIndex+1);
StatusFilterPredicate filterPredicate=new StatusFilterPredicate(accountID, getFilterContext());
for(Status s:result){
if(idsBelowGap.contains(s.id))
break;
if(typeFilterPredicate(s) && filterPredicate.test(s)){
int endIndex=0;
for(Status s:result){
endIndex++;
if(idsBelowGap.contains(s.id))
break;
}
if(endIndex==result.size()){
result.get(result.size()-1).hasGapAfter=true;
}else{
result=result.subList(0, endIndex);
}
AccountSessionManager.get(accountID).filterStatuses(result, FilterContext.HOME);
List<StatusDisplayItem> targetList=displayItems.subList(gapPos, gapPos+1);
targetList.clear();
List<Status> insertedPosts=data.subList(gapPostIndex+1, gapPostIndex+1);
for(Status s:result){
if(idsBelowGap.contains(s.id))
break;
targetList.addAll(buildDisplayItems(s));
insertedPosts.add(s);
}
if(targetList.isEmpty()){
// oops. We didn't add new posts, but at least we know there are none.
adapter.notifyItemRemoved(getMainAdapterOffset()+gapPos);
}else{
adapter.notifyItemChanged(getMainAdapterOffset()+gapPos);
adapter.notifyItemRangeInserted(getMainAdapterOffset()+gapPos+1, targetList.size()-1);
}
AccountSessionManager.getInstance().getAccount(accountID).getCacheController().putHomeTimeline(insertedPosts, false);
} else {
String aboveGapID = gap.parentID;
int gapPostIndex = 0;
for (;gapPostIndex<data.size();gapPostIndex++){
if (Objects.equals(aboveGapID, data.get(gapPostIndex).id)) {
break;
}
}
// find if there's an overlap between the new data and the current data
int indexOfGapInResponse = 0;
for (;indexOfGapInResponse<result.size();indexOfGapInResponse++){
if (Objects.equals(aboveGapID, result.get(indexOfGapInResponse).id)) {
break;
}
}
// there is an overlap between new and current data
List<StatusDisplayItem> targetList=displayItems.subList(gapPos, gapPos+1);
if(indexOfGapInResponse<result.size()){
result=result.subList(indexOfGapInResponse+1,result.size());
Optional<Status> gapStatus=data.stream()
.filter(s->Objects.equals(s.id, gap.parentID))
.findFirst();
if (gapStatus.isPresent()) {
gapStatus.get().hasGapAfter=false;
AccountSessionManager.getInstance().getAccount(accountID).getCacheController().putHomeTimeline(Collections.singletonList(gapStatus.get()), false);
}
targetList.clear();
} else {
gap.loading=false;
}
List<Status> insertedPosts=data.subList(gapPostIndex+1, gapPostIndex+1);
for(Status s:result){
targetList.addAll(buildDisplayItems(s));
insertedPosts.add(s);
}
AccountSessionManager.get(accountID).filterStatuses(insertedPosts, FilterContext.HOME);
if(targetList.isEmpty()){
// oops. We didn't add new posts, but at least we know there are none.
adapter.notifyItemRemoved(getMainAdapterOffset()+gapPos);
}else{
adapter.notifyItemChanged(getMainAdapterOffset()+gapPos);
adapter.notifyItemRangeInserted(getMainAdapterOffset()+gapPos+1, targetList.size()-1);
}
list.scrollToPosition(getMainAdapterOffset()+gapPos+targetList.size());
AccountSessionManager.getInstance().getAccount(accountID).getCacheController().putHomeTimeline(insertedPosts, false);
}
AccountSessionManager.get(accountID).filterStatuses(insertedPosts, getFilterContext());
if(targetList.isEmpty()){
// oops. We didn't add new posts, but at least we know there are none.
adapter.notifyItemRemoved(getMainAdapterOffset()+gapPos);
}else{
adapter.notifyItemChanged(getMainAdapterOffset()+gapPos);
adapter.notifyItemRangeInserted(getMainAdapterOffset()+gapPos+1, targetList.size()-1);
}
AccountSessionManager.getInstance().getAccount(accountID).getCacheController().putHomeTimeline(insertedPosts, false);
}
}

View File

@@ -15,6 +15,7 @@ import org.joinmastodon.android.E;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.events.EmojiReactionsUpdatedEvent;
import org.joinmastodon.android.events.PollUpdatedEvent;
import org.joinmastodon.android.events.RemoveAccountPostsEvent;
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
@@ -27,6 +28,7 @@ import org.joinmastodon.android.ui.displayitems.ExtendedFooterStatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.FooterStatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.NotificationHeaderStatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.TextStatusDisplayItem;
import org.joinmastodon.android.ui.utils.DiscoverInfoBannerHelper;
import org.joinmastodon.android.ui.utils.InsetStatusItemDecoration;
import org.joinmastodon.android.ui.utils.UiUtils;
@@ -43,7 +45,6 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import me.grishka.appkit.api.SimpleCallback;
import me.grishka.appkit.utils.MergeRecyclerAdapter;
import me.grishka.appkit.views.FragmentRootLinearLayout;
public class NotificationsListFragment extends BaseStatusListFragment<Notification> {
private boolean onlyMentions;
@@ -95,15 +96,13 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
if (n.type == Notification.Type.FOLLOW_REQUEST) {
ArrayList<StatusDisplayItem> items = new ArrayList<>();
items.add(titleItem);
items.add(new AccountCardStatusDisplayItem(n.id, this, n.account, n));
items.add(new AccountCardStatusDisplayItem(n.id, this, accountID, n.account, n));
return items;
}
if(n.status!=null){
int flags=titleItem==null ? 0 : (StatusDisplayItem.FLAG_NO_FOOTER | StatusDisplayItem.FLAG_INSET | StatusDisplayItem.FLAG_NO_EMOJI_REACTIONS); // | StatusDisplayItem.FLAG_NO_HEADER);
if (GlobalUserPreferences.spectatorMode)
flags |= StatusDisplayItem.FLAG_NO_FOOTER;
if (!getLocalPrefs().showEmojiReactionsInLists)
flags |= StatusDisplayItem.FLAG_NO_EMOJI_REACTIONS;
ArrayList<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, n.status, accountID, n, knownAccounts, null, flags);
if(titleItem!=null)
items.add(0, titleItem);
@@ -248,8 +247,7 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
@Subscribe
public void onStatusCountersUpdated(StatusCountersUpdatedEvent ev){
for(Notification n:data){
if (n.status == null) continue;
if(n.status.getContentStatus().id.equals(ev.id)){
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++){
@@ -258,15 +256,36 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
footer.rebind();
}else if(holder instanceof ExtendedFooterStatusDisplayItem.Holder footer && footer.getItem().status==n.status.getContentStatus()){
footer.rebind();
}else if(holder instanceof EmojiReactionsStatusDisplayItem.Holder reactions && ev.viewHolder!=holder){
reactions.rebind();
}
}
}
}
for(Notification n:preloadedData){
if (n.status == null) continue;
if(n.status.getContentStatus().id.equals(ev.id)){
if(n.status!=null && n.status.getContentStatus().id.equals(ev.id)){
n.status.getContentStatus().update(ev);
AccountSessionManager.get(accountID).getCacheController().updateNotification(n);
}
}
}
@Subscribe
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())){
text.rebind();
}
}
}
}
for(Notification n : preloadedData){
if(n.status!=null && n.status.getContentStatus().id.equals(ev.id)){
n.status.getContentStatus().update(ev);
AccountSessionManager.get(accountID).getCacheController().updateNotification(n);
}

View File

@@ -4,10 +4,12 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Fragment;
import android.app.assist.AssistContent;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Color;
@@ -131,6 +133,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
private CoverImageView cover;
private View avatarBorder;
private TextView name, username, bio, followersCount, followersLabel, followingCount, followingLabel;
private ImageView lockIcon, botIcon;
private ProgressBarButton actionButton, notifyButton;
private ViewPager2 pager;
private NestedRecyclerScrollView scrollView;
@@ -230,6 +233,8 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
avatarBorder=content.findViewById(R.id.avatar_border);
name=content.findViewById(R.id.name);
username=content.findViewById(R.id.username);
lockIcon=content.findViewById(R.id.lock_icon);
botIcon=content.findViewById(R.id.bot_icon);
bio=content.findViewById(R.id.bio);
followersCount=content.findViewById(R.id.followers_count);
followersLabel=content.findViewById(R.id.followers_label);
@@ -347,7 +352,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
followersBtn.setOnClickListener(this::onFollowersOrFollowingClick);
followingBtn.setOnClickListener(this::onFollowersOrFollowingClick);
username.setOnClickListener(v->{
content.findViewById(R.id.username_wrap).setOnClickListener(v->{
try {
new GetInstance()
.setCallback(new Callback<>(){
@@ -368,11 +373,11 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
.execRemote(Uri.parse(account.url).getHost());
} catch (NullPointerException ignored) {
// maybe the url was malformed?
Toast.makeText(getContext(), R.string.error, Toast.LENGTH_SHORT);
Toast.makeText(getContext(), R.string.error, Toast.LENGTH_SHORT).show();
}
});
username.setOnLongClickListener(v->{
content.findViewById(R.id.username_wrap).setOnLongClickListener(v->{
String usernameString=account.acct;
if(!usernameString.contains("@")){
usernameString+="@"+domain;
@@ -592,10 +597,14 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
}
}
@SuppressLint("SetTextI18n")
private void bindHeaderView(){
setTitle(account.displayName);
setSubtitle(getResources().getQuantityString(R.plurals.x_posts, (int)(account.statusesCount%1000), account.statusesCount));
ViewImageLoader.load(avatar, null, new UrlImageLoaderRequest(GlobalUserPreferences.playGifs ? account.avatar : account.avatarStatic, V.dp(100), V.dp(100)));
ViewImageLoader.load(avatar, null, new UrlImageLoaderRequest(
TextUtils.isEmpty(account.avatar) ? getSession().getDefaultAvatarUrl() :
GlobalUserPreferences.playGifs ? account.avatar : account.avatarStatic,
V.dp(100), V.dp(100)));
ViewImageLoader.load(cover, null, new UrlImageLoaderRequest(GlobalUserPreferences.playGifs ? account.header : account.headerStatic, 1000, 1000));
SpannableStringBuilder ssb=new SpannableStringBuilder(account.displayName);
if(AccountSessionManager.get(accountID).getLocalPreferences().customEmojiInNames)
@@ -624,19 +633,15 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
String acct = ((isSelf || account.isRemote)
? account.getFullyQualifiedName()
: account.acct);
if(account.locked){
ssb=new SpannableStringBuilder("@");
ssb.append(acct);
ssb.append(" ");
Drawable lock=username.getResources().getDrawable(R.drawable.ic_lock, getActivity().getTheme()).mutate();
lock.setBounds(0, 0, lock.getIntrinsicWidth(), lock.getIntrinsicHeight());
lock.setTint(username.getCurrentTextColor());
ssb.append(getString(R.string.manually_approves_followers), new ImageSpan(lock, ImageSpan.ALIGN_BASELINE), 0);
username.setText(ssb);
}else{
// noinspection SetTextI18n
username.setText('@'+acct);
}
username.setText('@'+acct);
lockIcon.setVisibility(account.locked ? View.VISIBLE : View.GONE);
lockIcon.setImageTintList(ColorStateList.valueOf(username.getCurrentTextColor()));
botIcon.setVisibility(account.bot ? View.VISIBLE : View.GONE);
botIcon.setImageTintList(ColorStateList.valueOf(username.getCurrentTextColor()));
CharSequence parsedBio=HtmlParser.parse(account.note, account.emojis, Collections.emptyList(), Collections.emptyList(), accountID);
if(TextUtils.isEmpty(parsedBio)){
bio.setVisibility(View.GONE);
@@ -1059,7 +1064,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
actionButton.setText(R.string.save_changes);
pager.setVisibility(View.GONE);
tabbar.setVisibility(View.GONE);
Drawable overlay=getResources().getDrawable(R.drawable.edit_avatar_overlay).mutate();
Drawable overlay=getResources().getDrawable(R.drawable.edit_avatar_overlay, getActivity().getTheme()).mutate();
avatar.setForeground(overlay);
updateMetadataHeight();
@@ -1227,7 +1232,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
if(ava==null)
return;
int radius=V.dp(25);
currentPhotoViewer=new PhotoViewer(getActivity(), createFakeAttachments(account.avatar, ava), 0,
currentPhotoViewer=new PhotoViewer(getActivity(), createFakeAttachments(TextUtils.isEmpty(account.avatar) ? getSession().getDefaultAvatarUrl() : account.avatar, ava), 0,
new SingleImagePhotoViewerListener(avatar, avatarBorder, new int[]{radius, radius, radius, radius}, this, ()->currentPhotoViewer=null, ()->ava, null, null));
}
}
@@ -1428,16 +1433,14 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
}
}
private class AboutViewHolder extends BaseViewHolder implements ImageLoaderViewHolder {
private class AboutViewHolder extends BaseViewHolder implements ImageLoaderViewHolder{
private final TextView title;
private final LinkedTextView value;
// private final ImageView verifiedIcon;
public AboutViewHolder(){
super(R.layout.item_profile_about);
title=findViewById(R.id.title);
value=findViewById(R.id.value);
// verifiedIcon=findViewById(R.id.verified_icon);
}
@Override
@@ -1445,7 +1448,18 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
super.onBind(item);
title.setText(item.parsedName);
value.setText(item.parsedValue);
// verifiedIcon.setVisibility(item.verifiedAt!=null ? View.VISIBLE : View.GONE);
if(item.verifiedAt!=null){
int textColor=UiUtils.isDarkTheme() ? 0xFF89bb9c : 0xFF5b8e63;
value.setTextColor(textColor);
value.setLinkTextColor(textColor);
Drawable check=getResources().getDrawable(R.drawable.ic_fluent_checkmark_starburst_20_regular, getActivity().getTheme()).mutate();
check.setTint(textColor);
value.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, check, null);
}else{
value.setTextColor(UiUtils.getThemeColor(getActivity(), android.R.attr.textColorPrimary));
value.setLinkTextColor(UiUtils.getThemeColor(getActivity(), android.R.attr.colorAccent));
value.setCompoundDrawables(null, null, null, null);
}
}
@Override

View File

@@ -2,8 +2,11 @@ package org.joinmastodon.android.fragments;
import android.app.Activity;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
import android.widget.ImageButton;
import com.squareup.otto.Subscribe;
@@ -26,6 +29,7 @@ import java.util.List;
import me.grishka.appkit.Nav;
import me.grishka.appkit.api.SimpleCallback;
import me.grishka.appkit.utils.V;
public class ScheduledStatusListFragment extends BaseStatusListFragment<ScheduledStatus> {
private String nextMaxID;
@@ -80,7 +84,10 @@ public class ScheduledStatusListFragment extends BaseStatusListFragment<Schedule
@Override
protected List<StatusDisplayItem> buildDisplayItems(ScheduledStatus s) {
return StatusDisplayItem.buildItems(this, s.toStatus(), accountID, s, knownAccounts, false, false, false, true, null);
return StatusDisplayItem.buildItems(this, s.toStatus(), accountID, s, knownAccounts, null,
StatusDisplayItem.FLAG_NO_EMOJI_REACTIONS |
StatusDisplayItem.FLAG_NO_FOOTER |
StatusDisplayItem.FLAG_NO_TRANSLATE);
}
@Override
@@ -183,6 +190,21 @@ public class ScheduledStatusListFragment extends BaseStatusListFragment<Schedule
return null;
}
@Override
public void onApplyWindowInsets(WindowInsets insets){
if(contentView!=null){
if(Build.VERSION.SDK_INT>=29 && insets.getTappableElementInsets().bottom==0){
int insetBottom=insets.getSystemWindowInsetBottom();
((ViewGroup.MarginLayoutParams) list.getLayoutParams()).bottomMargin=insetBottom;
((ViewGroup.MarginLayoutParams) fab.getLayoutParams()).bottomMargin=V.dp(16)+insetBottom;
insets=insets.inset(0, 0, 0, insetBottom);
}else{
((ViewGroup.MarginLayoutParams) fab.getLayoutParams()).bottomMargin=V.dp(16);
}
}
super.onApplyWindowInsets(insets);
}
@Override
public Uri getWebUri(Uri.Builder base) {
// TODO: adapt when frontends finally implement a scheduled posts list

View File

@@ -9,6 +9,7 @@ import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.statuses.GetStatusEditHistory;
import org.joinmastodon.android.model.FilterContext;
import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.ui.displayitems.DummyStatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.ReblogOrReplyLineStatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
import org.joinmastodon.android.ui.utils.InsetStatusItemDecoration;
@@ -143,7 +144,8 @@ public class StatusEditHistoryFragment extends StatusListFragment{
}
}
String sep = getString(R.string.sk_separator);
items.add(0, new ReblogOrReplyLineStatusDisplayItem(s.id, this, action+" "+sep+" "+date, Collections.emptyList(), 0, null, null));
items.add(0, new ReblogOrReplyLineStatusDisplayItem(s.id, this, action+" "+sep+" "+date, Collections.emptyList(), 0, null, null, s));
items.add(1, new DummyStatusDisplayItem(s.id, this));
}
return items;
}

View File

@@ -1,5 +1,7 @@
package org.joinmastodon.android.fragments;
import static org.joinmastodon.android.api.session.AccountLocalPreferences.ShowEmojiReactions.ONLY_OPENED;
import android.content.res.Configuration;
import android.os.Bundle;
@@ -7,7 +9,9 @@ import com.squareup.otto.Subscribe;
import org.joinmastodon.android.E;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.api.session.AccountLocalPreferences;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.events.EmojiReactionsUpdatedEvent;
import org.joinmastodon.android.events.PollUpdatedEvent;
import org.joinmastodon.android.events.RemoveAccountPostsEvent;
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
@@ -20,6 +24,7 @@ import org.joinmastodon.android.ui.displayitems.EmojiReactionsStatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.ExtendedFooterStatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.FooterStatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.TextStatusDisplayItem;
import org.parceler.Parcels;
import java.util.ArrayList;
@@ -36,9 +41,10 @@ public abstract class StatusListFragment extends BaseStatusListFragment<Status>
protected List<StatusDisplayItem> buildDisplayItems(Status s){
boolean isMainThreadStatus = this instanceof ThreadFragment t && s.id.equals(t.mainStatus.id);
int flags = 0;
AccountLocalPreferences lp=getLocalPrefs();
if (GlobalUserPreferences.spectatorMode)
flags |= StatusDisplayItem.FLAG_NO_FOOTER;
if (!getLocalPrefs().showEmojiReactionsInLists)
if (!lp.emojiReactionsEnabled || lp.showEmojiReactions==ONLY_OPENED)
flags |= StatusDisplayItem.FLAG_NO_EMOJI_REACTIONS;
return StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, getFilterContext(), isMainThreadStatus ? 0 : flags);
}
@@ -223,8 +229,30 @@ public abstract class StatusListFragment extends BaseStatusListFragment<Status>
footer.rebind();
}else if(holder instanceof ExtendedFooterStatusDisplayItem.Holder footer && footer.getItem().status==s.getContentStatus()){
footer.rebind();
}else if(holder instanceof EmojiReactionsStatusDisplayItem.Holder reactions && reactions.getItem().status==s.getContentStatus() && ev.viewHolder!=holder){
}
}
}
}
for(Status s:preloadedData){
if(s.getContentStatus().id.equals(ev.id)){
s.getContentStatus().update(ev);
AccountSessionManager.get(accountID).getCacheController().updateStatus(s);
}
}
}
@Subscribe
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())){
text.rebind();
}
}
}

View File

@@ -16,6 +16,7 @@ import android.widget.TextView;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.accounts.GetAccountRelationships;
import org.joinmastodon.android.api.requests.accounts.GetFollowSuggestions;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.fragments.IsOnTop;
import org.joinmastodon.android.fragments.MastodonRecyclerFragment;
import org.joinmastodon.android.fragments.ProfileFragment;
@@ -319,8 +320,9 @@ public class DiscoverAccountsFragment extends MastodonRecyclerFragment<DiscoverA
public AccountWrapper(Account account){
this.account=account;
if(!TextUtils.isEmpty(account.avatar))
avaRequest=new UrlImageLoaderRequest(account.avatar, V.dp(50), V.dp(50));
avaRequest=new UrlImageLoaderRequest(
TextUtils.isEmpty(account.avatar) ? AccountSessionManager.getInstance().getAccount(accountID).getDefaultAvatarUrl() : account.avatar,
V.dp(50), V.dp(50));
if(!TextUtils.isEmpty(account.header))
coverRequest=new UrlImageLoaderRequest(account.header, 1000, 1000);
parsedBio=HtmlParser.parse(account.note, account.emojis, Collections.emptyList(), Collections.emptyList(), accountID);

View File

@@ -70,7 +70,7 @@ public class SearchFragment extends BaseStatusListFragment<SearchResult>{
return switch(s.type){
case ACCOUNT -> Collections.singletonList(new AccountStatusDisplayItem(s.id, this, s.account));
case HASHTAG -> Collections.singletonList(new HashtagStatusDisplayItem(s.id, this, s.hashtag));
case STATUS -> StatusDisplayItem.buildItems(this, s.status, accountID, s, knownAccounts, FilterContext.PUBLIC, !getLocalPrefs().showEmojiReactionsInLists ? StatusDisplayItem.FLAG_NO_EMOJI_REACTIONS : 0);
case STATUS -> StatusDisplayItem.buildItems(this, s.status, accountID, s, knownAccounts, FilterContext.PUBLIC, 0);
};
}

View File

@@ -10,7 +10,6 @@ import android.graphics.Outline;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
@@ -26,7 +25,7 @@ import android.widget.TextView;
import android.widget.Toast;
import android.widget.Toolbar;
import org.joinmastodon.android.MainActivity;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.search.GetSearchResults;
import org.joinmastodon.android.api.session.AccountSessionManager;
@@ -38,19 +37,16 @@ import org.joinmastodon.android.model.SearchResults;
import org.joinmastodon.android.model.viewmodel.ListItem;
import org.joinmastodon.android.model.viewmodel.SearchResultViewModel;
import org.joinmastodon.android.ui.DividerItemDecoration;
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
import org.joinmastodon.android.ui.SearchViewHelper;
import org.joinmastodon.android.ui.adapters.GenericListItemsAdapter;
import org.joinmastodon.android.ui.utils.HideableSingleViewRecyclerAdapter;
import org.joinmastodon.android.ui.utils.UiUtils;
import org.joinmastodon.android.ui.viewholders.AccountViewHolder;
import org.joinmastodon.android.ui.viewholders.SimpleListItemViewHolder;
import org.parceler.Parcels;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -381,16 +377,54 @@ public class SearchQueryFragment extends MastodonRecyclerFragment<SearchResultVi
}
private void openHashtag(SearchResult res){
UiUtils.openHashtagTimeline(getActivity(), accountID, res.hashtag.name, res.hashtag.following);
AccountSessionManager.getInstance().getAccount(accountID).getCacheController().putRecentSearch(res);
wrapSuicideDialog(()->{
UiUtils.openHashtagTimeline(getActivity(), accountID, res.hashtag.name, res.hashtag.following);
AccountSessionManager.getInstance().getAccount(accountID).getCacheController().putRecentSearch(res);
});
}
private boolean isInRecentMode(){
return TextUtils.isEmpty(currentQuery);
}
private void wrapSuicideDialog(Runnable r){
if(!GlobalUserPreferences.showSuicideHelp || currentQuery==null){
r.run();
return;
}
String[] terms=getContext().getString(R.string.sk_suicide_search_terms).toLowerCase().split(",");
String query=currentQuery.trim().toLowerCase();
boolean termMatches=false;
for(String term : terms){
if(query.contains(term)){
termMatches=true;
break;
}
}
if(!termMatches){
r.run();
return;
}
String url=getContext().getString(R.string.sk_suicide_helplines_url);
new M3AlertDialogBuilder(getActivity())
.setTitle(R.string.sk_search_suicide_title)
.setMessage(R.string.sk_search_suicide_message)
.setNegativeButton(R.string.sk_do_not_show_again, (dialog, which)->{
GlobalUserPreferences.showSuicideHelp = false;
GlobalUserPreferences.save();
r.run();
})
.setNeutralButton(R.string.sk_search_suicide_hotlines, (dialog, which)->UiUtils.launchWebBrowser(getContext(), url))
.setPositiveButton(R.string.ok, (dialog, which)->r.run())
.setOnDismissListener((dialog)->{})
.show();
}
private void onSearchViewEnter(){
deliverResult(currentQuery, null);
wrapSuicideDialog(()->deliverResult(currentQuery, null));
}
private void onOpenURLClick(){
@@ -398,10 +432,12 @@ public class SearchQueryFragment extends MastodonRecyclerFragment<SearchResultVi
}
private void onGoToHashtagClick(){
String q=searchViewHelper.getQuery();
if(q.startsWith("#"))
q=q.substring(1);
UiUtils.openHashtagTimeline(getActivity(), accountID, q, null);
wrapSuicideDialog(()->{
String q=searchViewHelper.getQuery();
if(q.startsWith("#"))
q=q.substring(1);
UiUtils.openHashtagTimeline(getActivity(), accountID, q, null);
});
}
private void onGoToAccountClick(){
@@ -422,11 +458,11 @@ public class SearchQueryFragment extends MastodonRecyclerFragment<SearchResultVi
}
private void onGoToStatusSearchClick(){
deliverResult(searchViewHelper.getQuery(), SearchResult.Type.STATUS);
wrapSuicideDialog(()->deliverResult(searchViewHelper.getQuery(), SearchResult.Type.STATUS));
}
private void onGoToAccountSearchClick(){
deliverResult(searchViewHelper.getQuery(), SearchResult.Type.ACCOUNT);
wrapSuicideDialog(()->deliverResult(searchViewHelper.getQuery(), SearchResult.Type.ACCOUNT));
}
private void onClearRecentClick(){

View File

@@ -83,7 +83,7 @@ public class ReportReasonChoiceFragment extends StatusListFragment{
reportStatus=Parcels.unwrap(getArguments().getParcelable("status"));
if(reportStatus!=null){
Status hiddenStatus=reportStatus.clone();
hiddenStatus.spoilerText=getString(R.string.post_hidden);
if(hiddenStatus.spoilerText==null) hiddenStatus.spoilerText=getString(R.string.post_hidden);
onDataLoaded(Collections.singletonList(hiddenStatus));
setTitle(R.string.report_title_post);
}else{
@@ -168,17 +168,6 @@ public class ReportReasonChoiceFragment extends StatusListFragment{
((UsableRecyclerView)list).setIncludeMarginsInItemHitbox(false);
if(reportStatus!=null){
list.addItemDecoration(new RecyclerView.ItemDecoration(){
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state){
RecyclerView.ViewHolder holder=parent.getChildViewHolder(view);
if(holder instanceof LinkCardStatusDisplayItem.Holder || holder instanceof MediaGridStatusDisplayItem.Holder){
outRect.left=V.dp(16);
outRect.right=V.dp(16);
}
}
});
list.addItemDecoration(new RecyclerView.ItemDecoration(){
private Paint paint=new Paint(Paint.ANTI_ALIAS_FLAG);
{
@@ -222,10 +211,6 @@ public class ReportReasonChoiceFragment extends StatusListFragment{
if(holder instanceof StatusDisplayItem.Holder<?>){
outRect.left=outRect.right=V.dp(16);
}
int index=holder.getAbsoluteAdapterPosition()-mergeAdapter.getPositionForAdapter(adapter);
if(index==displayItems.size()){
outRect.top=V.dp(32);
}
}
});
}
@@ -251,18 +236,6 @@ public class ReportReasonChoiceFragment extends StatusListFragment{
return null;
}
@Override
protected void onModifyItemViewHolder(BindableViewHolder<StatusDisplayItem> holder){
if((Object)holder instanceof MediaGridStatusDisplayItem.Holder h){
View layout=h.getLayout();
layout.setOutlineProvider(OutlineProviders.roundedRect(8));
layout.setClipToOutline(true);
View overlay=h.getSensitiveOverlay();
overlay.setOutlineProvider(OutlineProviders.roundedRect(8));
overlay.setClipToOutline(true);
}
}
@Override
public void putRelationship(String id, Relationship rel){
super.putRelationship(id, rel);

View File

@@ -16,6 +16,7 @@ import org.joinmastodon.android.model.viewmodel.ListItem;
import org.joinmastodon.android.ui.utils.UiUtils;
import java.util.List;
import java.util.Objects;
import androidx.recyclerview.widget.RecyclerView;
import me.grishka.appkit.imageloader.ImageCache;
@@ -32,7 +33,7 @@ public class SettingsAboutAppFragment extends BaseSettingsFragment<Void>{
setTitle(getString(R.string.about_app, getString(R.string.sk_app_name)));
AccountSession s=AccountSessionManager.get(accountID);
onDataLoaded(List.of(
new ListItem<>(R.string.sk_settings_donate, 0, R.drawable.ic_fluent_heart_24_regular, ()->UiUtils.launchWebBrowser(getActivity(), getString(R.string.donate_url))),
new ListItem<>(R.string.sk_settings_donate, 0, R.drawable.ic_fluent_heart_24_regular, ()->UiUtils.openHashtagTimeline(getActivity(), accountID, getString(R.string.donate_hashtag), null)),
new ListItem<>(R.string.sk_settings_contribute, 0, R.drawable.ic_fluent_open_24_regular, ()->UiUtils.launchWebBrowser(getActivity(), getString(R.string.repo_url))),
new ListItem<>(R.string.settings_tos, 0, R.drawable.ic_fluent_open_24_regular, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+s.domain+"/terms")),
new ListItem<>(R.string.settings_privacy_policy, 0, R.drawable.ic_fluent_open_24_regular, ()->UiUtils.launchWebBrowser(getActivity(), getString(R.string.privacy_policy_url)), 0, true),

View File

@@ -20,6 +20,7 @@ import org.joinmastodon.android.utils.MastodonLanguage;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class SettingsBehaviorFragment extends BaseSettingsFragment<Void> implements HasAccountID{
private ListItem<Void> languageItem;

View File

@@ -2,10 +2,14 @@ package org.joinmastodon.android.fragments.settings;
import android.os.Bundle;
import androidx.annotation.StringRes;
import org.joinmastodon.android.E;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.session.AccountLocalPreferences;
import org.joinmastodon.android.api.session.AccountSession;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.events.StatusDisplaySettingsChangedEvent;
import org.joinmastodon.android.fragments.HasAccountID;
import org.joinmastodon.android.model.ContentType;
import org.joinmastodon.android.model.viewmodel.CheckableListItem;
@@ -15,12 +19,13 @@ import org.joinmastodon.android.ui.utils.UiUtils;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import me.grishka.appkit.Nav;
public class SettingsInstanceFragment extends BaseSettingsFragment<Void> implements HasAccountID{
private CheckableListItem<Void> contentTypesItem, emojiReactionsItem, emojiReactionsInListsItem, localOnlyItem, glitchModeItem;
private ListItem<Void> defaultContentTypeItem;
private CheckableListItem<Void> contentTypesItem, emojiReactionsItem, localOnlyItem, glitchModeItem;
private ListItem<Void> defaultContentTypeItem, showEmojiReactionsItem;
private AccountLocalPreferences lp;
@Override
@@ -35,16 +40,16 @@ public class SettingsInstanceFragment extends BaseSettingsFragment<Void> impleme
new ListItem<>(R.string.sk_settings_posting, 0, R.drawable.ic_fluent_open_24_regular, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+s.domain+"/settings/preferences/other")),
new ListItem<>(R.string.sk_settings_auth, 0, R.drawable.ic_fluent_open_24_regular, ()->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, this::onContentTypeClick),
defaultContentTypeItem=new ListItem<>(R.string.sk_settings_default_content_type, lp.defaultContentType.getName(), R.drawable.ic_fluent_text_bold_24_regular, this::onDefaultContentTypeClick),
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, this::onEmojiReactionsClick),
emojiReactionsInListsItem=new CheckableListItem<>(R.string.sk_settings_emoji_reactions_in_lists, R.string.sk_settings_emoji_reactions_in_lists_explanation, CheckableListItem.Style.SWITCH, lp.showEmojiReactionsInLists, R.drawable.ic_fluent_emoji_24_regular, ()->toggleCheckableItem(emojiReactionsInListsItem)),
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, this::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, ()->toggleCheckableItem(glitchModeItem))
));
contentTypesItem.checkedChangeListener=checked->onContentTypeClick();
defaultContentTypeItem.isEnabled=contentTypesItem.checked;
emojiReactionsItem.checkedChangeListener=checked->onEmojiReactionsClick();
emojiReactionsInListsItem.isEnabled=emojiReactionsItem.checked;
showEmojiReactionsItem.isEnabled=emojiReactionsItem.checked;
localOnlyItem.checkedChangeListener=checked->onLocalOnlyClick();
glitchModeItem.isEnabled=localOnlyItem.checked;
}
@@ -57,10 +62,10 @@ public class SettingsInstanceFragment extends BaseSettingsFragment<Void> impleme
super.onHidden();
lp.contentTypesEnabled=contentTypesItem.checked;
lp.emojiReactionsEnabled=emojiReactionsItem.checked;
lp.showEmojiReactionsInLists=emojiReactionsInListsItem.checked;
lp.localOnlySupported=localOnlyItem.checked;
lp.glitchInstance=glitchModeItem.checked;
lp.save();
E.post(new StatusDisplaySettingsChangedEvent(accountID));
}
private void onServerClick(){
@@ -107,11 +112,34 @@ public class SettingsInstanceFragment extends BaseSettingsFragment<Void> impleme
.show();
}
private void onShowEmojiReactionsClick(){
int selected=lp.showEmojiReactions.ordinal();
int[] newSelected={selected};
new M3AlertDialogBuilder(getActivity())
.setTitle(R.string.sk_settings_show_emoji_reactions)
.setSingleChoiceItems((String[]) IntStream.of(R.string.sk_settings_show_emoji_reactions_hide_empty, R.string.sk_settings_show_emoji_reactions_only_opened, R.string.sk_settings_show_emoji_reactions_always).mapToObj(this::getString).toArray(String[]::new),
selected, (dlg, item)->newSelected[0]=item)
.setPositiveButton(R.string.ok, (dlg, item)->{
lp.showEmojiReactions=AccountLocalPreferences.ShowEmojiReactions.values()[newSelected[0]];
showEmojiReactionsItem.subtitleRes=getShowEmojiReactionsString();
rebindItem(showEmojiReactionsItem);
})
.setNegativeButton(R.string.cancel, null)
.show();
}
private @StringRes int getShowEmojiReactionsString(){
return switch(lp.showEmojiReactions){
case HIDE_EMPTY -> R.string.sk_settings_show_emoji_reactions_hide_empty;
case ONLY_OPENED -> R.string.sk_settings_show_emoji_reactions_only_opened;
case ALWAYS -> R.string.sk_settings_show_emoji_reactions_always;
};
}
private void onEmojiReactionsClick(){
toggleCheckableItem(emojiReactionsItem);
emojiReactionsInListsItem.checked=false;
emojiReactionsInListsItem.isEnabled=emojiReactionsItem.checked;
rebindItem(emojiReactionsInListsItem);
showEmojiReactionsItem.isEnabled=emojiReactionsItem.checked;
rebindItem(showEmojiReactionsItem);
}
private void onLocalOnlyClick(){

View File

@@ -7,12 +7,17 @@ import androidx.annotation.Nullable;
import org.joinmastodon.android.api.ObjectValidationException;
import org.joinmastodon.android.api.RequiredField;
import org.joinmastodon.android.api.requests.instance.GetInstance;
import org.parceler.Parcel;
import java.time.Instant;
import java.time.LocalDate;
import java.util.Collections;
import java.util.List;
import me.grishka.appkit.api.Callback;
import me.grishka.appkit.api.ErrorResponse;
/**
* Represents a user of Mastodon and their associated profile.
*/
@@ -23,22 +28,22 @@ public class Account extends BaseModel implements Searchable{
/**
* The account id
*/
@RequiredField
// @RequiredField
public String id;
/**
* The username of the account, not including domain.
*/
@RequiredField
// @RequiredField
public String username;
/**
* The Webfinger account URI. Equal to username for local users, or username@domain for remote users.
*/
@RequiredField
// @RequiredField
public String acct;
/**
* The location of the user's profile page.
*/
@RequiredField
// @RequiredField
public String url;
// Display attributes
@@ -51,12 +56,12 @@ public class Account extends BaseModel implements Searchable{
/**
* The profile's bio / description.
*/
@RequiredField
// @RequiredField
public String note;
/**
* An image icon that is shown next to statuses and in the profile.
*/
@RequiredField
// @RequiredField
public String avatar;
/**
* A static version of the avatar. Equal to avatar if its value is a static image; different if avatar is an animated GIF.
@@ -157,16 +162,26 @@ public class Account extends BaseModel implements Searchable{
if(fields!=null){
for(AccountField f:fields)
f.postprocess();
} else {
fields = Collections.emptyList();
}
if(emojis!=null){
for(Emoji e:emojis)
e.postprocess();
} else {
emojis = Collections.emptyList();
}
if(moved!=null)
moved.postprocess();
if(TextUtils.isEmpty(displayName))
displayName=username;
if(fqn == null) fqn = getFullyQualifiedName();
if(id == null) id = "";
if(username == null) username = "";
if(TextUtils.isEmpty(displayName))
displayName = !TextUtils.isEmpty(username) ? username : "";
if(acct == null) acct = "";
if(url == null) url = "";
if(note == null) note = "";
if(avatar == null) avatar = "";
}
public boolean isLocal(){
@@ -191,6 +206,8 @@ public class Account extends BaseModel implements Searchable{
}
public String getFullyQualifiedName() {
if (TextUtils.isEmpty(acct))
return "";
return fqn != null ? fqn : acct.split("@")[0] + "@" + getDomainFromURL();
}

View File

@@ -41,6 +41,12 @@ public class Emoji extends BaseModel{
this.staticUrl = staticUrl;
}
public String getUrl(boolean playGifs){
String idealUrl=playGifs ? url : staticUrl;
if(idealUrl==null) return url==null ? staticUrl : url;
return idealUrl;
}
@Override
public String toString(){
return "Emoji{"+

View File

@@ -1,5 +1,6 @@
package org.joinmastodon.android.model;
import org.joinmastodon.android.GlobalUserPreferences;
import org.parceler.Parcel;
import java.util.ArrayList;
@@ -22,6 +23,12 @@ public class EmojiReaction {
public transient ImageLoaderRequest request;
public String getUrl(boolean playGifs){
String idealUrl=playGifs ? url : staticUrl;
if(idealUrl==null) return url==null ? staticUrl : url;
return idealUrl;
}
public static EmojiReaction of(Emoji info, Account me){
EmojiReaction reaction=new EmojiReaction();
reaction.me=true;

View File

@@ -13,10 +13,10 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.api.ObjectValidationException;
import org.joinmastodon.android.api.RequiredField;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.events.EmojiReactionsUpdatedEvent;
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
import org.joinmastodon.android.ui.text.HtmlParser;
import org.parceler.Parcel;
@@ -114,8 +114,8 @@ public class Status extends BaseModel implements DisplayItemsParent, Searchable{
for(FilterResult fr:filtered)
fr.postprocess();
if(!TextUtils.isEmpty(spoilerText)) sensitive=true;
spoilerRevealed=TextUtils.isEmpty(spoilerText);
spoilerRevealed=!hasSpoiler();
if(!spoilerRevealed) sensitive=true;
sensitiveRevealed=!sensitive;
if(visibility.equals(StatusPrivacy.LOCAL)) localOnly=true;
if(emojiReactions!=null) reactions=emojiReactions;
@@ -175,6 +175,9 @@ public class Status extends BaseModel implements DisplayItemsParent, Searchable{
reblogged=ev.reblogged;
bookmarked=ev.bookmarked;
pinned=ev.pinned;
}
public void update(EmojiReactionsUpdatedEvent ev){
reactions=ev.reactions;
}
@@ -188,6 +191,10 @@ public class Status extends BaseModel implements DisplayItemsParent, Searchable{
return strippedText;
}
public boolean hasSpoiler(){
return !TextUtils.isEmpty(spoilerText);
}
@NonNull
@Override
public Status clone(){

View File

@@ -1,8 +1,10 @@
package org.joinmastodon.android.model.viewmodel;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.api.session.AccountSession;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.AccountField;
@@ -24,9 +26,13 @@ public class AccountViewModel{
public AccountViewModel(Account account, String accountID){
this.account=account;
avaRequest=new UrlImageLoaderRequest(GlobalUserPreferences.playGifs ? account.avatar : account.avatarStatic, V.dp(50), V.dp(50));
AccountSession session = AccountSessionManager.get(accountID);
avaRequest=new UrlImageLoaderRequest(
TextUtils.isEmpty(account.avatar) ? session.getDefaultAvatarUrl() :
GlobalUserPreferences.playGifs ? account.avatar : account.avatarStatic,
V.dp(50), V.dp(50));
emojiHelper=new CustomEmojiHelper();
if(AccountSessionManager.get(accountID).getLocalPreferences().customEmojiInNames)
if(session.getLocalPreferences().customEmojiInNames)
parsedName=HtmlParser.parseCustomEmoji(account.displayName, account.emojis);
else
parsedName=account.displayName;

File diff suppressed because one or more lines are too long

View File

@@ -37,6 +37,16 @@ public class OutlineProviders{
}
};
private final static int BUTTON_BG_HEIGHT=V.dp(40);
public static final ViewOutlineProvider M3_BUTTON=new ViewOutlineProvider(){
@Override
public void getOutline(View view, Outline outline){
int viewHeight=view.getHeight();
int top=Math.floorDiv(viewHeight - BUTTON_BG_HEIGHT, 2);
outline.setRoundRect(0, top, view.getWidth(), top + BUTTON_BG_HEIGHT, V.dp(20));
}
};
public static ViewOutlineProvider roundedRect(int dp){
ViewOutlineProvider provider=roundedRects.get(dp);
if(provider!=null)

View File

@@ -15,6 +15,7 @@ import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.fragments.BaseStatusListFragment;
import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.Notification;
@@ -41,12 +42,13 @@ public class AccountCardStatusDisplayItem extends StatusDisplayItem{
public CustomEmojiHelper emojiHelper=new CustomEmojiHelper();
public CharSequence parsedName, parsedBio;
public AccountCardStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, Account account, Notification notification){
public AccountCardStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, String accountID, Account account, Notification notification){
super(parentID, parentFragment);
this.account=account;
this.notification=notification;
if(!TextUtils.isEmpty(account.avatar))
avaRequest=new UrlImageLoaderRequest(account.avatar, V.dp(50), V.dp(50));
avaRequest=new UrlImageLoaderRequest(
TextUtils.isEmpty(account.avatar) ? AccountSessionManager.get(accountID).getDefaultAvatarUrl() : account.avatar,
V.dp(50), V.dp(50));
if(!TextUtils.isEmpty(account.header))
coverRequest=new UrlImageLoaderRequest(account.header, 1000, 1000);
parsedBio=HtmlParser.parse(account.note, account.emojis, Collections.emptyList(), Collections.emptyList(), parentFragment.getAccountID());

View File

@@ -21,6 +21,7 @@ import androidx.recyclerview.widget.LinearSmoothScroller;
import androidx.recyclerview.widget.RecyclerView;
import org.joinmastodon.android.E;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.MastodonAPIRequest;
import org.joinmastodon.android.api.requests.announcements.AddAnnouncementReaction;
@@ -31,11 +32,10 @@ import org.joinmastodon.android.api.requests.statuses.PleromaAddStatusReaction;
import org.joinmastodon.android.api.requests.statuses.PleromaDeleteStatusReaction;
import org.joinmastodon.android.api.session.AccountSession;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
import org.joinmastodon.android.events.EmojiReactionsUpdatedEvent;
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.Announcement;
import org.joinmastodon.android.model.Emoji;
import org.joinmastodon.android.model.EmojiReaction;
import org.joinmastodon.android.model.Status;
@@ -44,8 +44,6 @@ import org.joinmastodon.android.ui.utils.TextDrawable;
import org.joinmastodon.android.ui.utils.UiUtils;
import org.joinmastodon.android.ui.views.ProgressBarButton;
import java.util.Optional;
import me.grishka.appkit.Nav;
import me.grishka.appkit.api.Callback;
import me.grishka.appkit.api.ErrorResponse;
@@ -62,25 +60,24 @@ import me.grishka.appkit.views.UsableRecyclerView;
public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
public final Status status;
private final Drawable placeholder;
private final boolean hideAdd, forAnnouncement;
private final boolean hideEmpty, forAnnouncement, playGifs;
private final String accountID;
private boolean hidden;
private static final float ALPHA_DISABLED=0.55f;
public EmojiReactionsStatusDisplayItem(String parentID, BaseStatusListFragment<?> parentFragment, Status status, String accountID, boolean hideAdd, boolean forAnnouncement) {
public EmojiReactionsStatusDisplayItem(String parentID, BaseStatusListFragment<?> parentFragment, Status status, String accountID, boolean hideEmpty, boolean forAnnouncement) {
super(parentID, parentFragment);
this.status=status;
this.hideAdd=hideAdd;
this.hideEmpty=hideEmpty;
this.forAnnouncement=forAnnouncement;
this.accountID=accountID;
placeholder=parentFragment.getContext().getDrawable(R.drawable.image_placeholder).mutate();
placeholder.setBounds(0, 0, V.sp(24), V.sp(24));
updateHidden();
playGifs=GlobalUserPreferences.playGifs;
}
@Override
public int getImageCount(){
return (int) status.reactions.stream().filter(r->r.url != null).count();
return (int) status.reactions.stream().filter(r->r.getUrl(playGifs)!=null).count();
}
@Override
@@ -94,11 +91,7 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
}
public boolean isHidden(){
return hidden;
}
private void updateHidden(){
hidden=status.reactions.isEmpty() && hideAdd;
return status.reactions.isEmpty() && hideEmpty;
}
// borrowed from ProfileFragment
@@ -178,8 +171,9 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
public void onBind(EmojiReactionsStatusDisplayItem item) {
if(emojiKeyboard != null) root.removeView(emojiKeyboard.getView());
AccountSession session=item.parentFragment.getSession();
item.status.reactions.forEach(r->
r.request=r.url != null ? new UrlImageLoaderRequest(r.url, V.sp(24), V.sp(24)) : null);
item.status.reactions.forEach(r->r.request=r.getUrl(item.playGifs)!=null
? new UrlImageLoaderRequest(r.getUrl(item.playGifs), V.sp(24), V.sp(24))
: null);
emojiKeyboard=new CustomEmojiPopupKeyboard(
(Activity) item.parentFragment.getContext(),
AccountSessionManager.getInstance().getCustomEmojis(session.domain),
@@ -187,12 +181,12 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
emojiKeyboard.setListener(this);
space.setVisibility(View.GONE);
root.addView(emojiKeyboard.getView());
item.updateHidden();
root.setVisibility(item.hidden ? View.GONE : View.VISIBLE);
line.setVisibility(item.hidden ? View.GONE : View.VISIBLE);
boolean hidden=item.isHidden();
root.setVisibility(hidden ? View.GONE : View.VISIBLE);
line.setVisibility(hidden ? View.GONE : View.VISIBLE);
line.setPadding(
list.getPaddingLeft(),
item.hidden ? 0 : V.dp(8),
hidden ? 0 : V.dp(8),
list.getPaddingRight(),
item.forAnnouncement ? V.dp(8) : 0
);
@@ -219,6 +213,7 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
}
private void addEmojiReaction(String emoji, Emoji info) {
int countBefore=item.status.reactions.size();
for(int i=0; i<item.status.reactions.size(); i++){
EmojiReaction r=item.status.reactions.get(i);
if(r.name.equals(emoji) && r.me){
@@ -261,7 +256,7 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
finalExisting.add(me);
adapter.notifyItemChanged(item.status.reactions.indexOf(finalExisting));
}
E.post(new StatusCountersUpdatedEvent(item.status, adapter.parentHolder));
E.post(new EmojiReactionsUpdatedEvent(item.status.id, item.status.reactions, countBefore==0, adapter.parentHolder));
}, resetBtn).exec(item.accountID);
}
@@ -291,7 +286,7 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
@Override
public void clearImage(int index){
if(item.status.reactions.get(index).url==null) return;
if(item.status.reactions.get(index).getUrl(item.playGifs)==null) return;
setImage(index, item.placeholder);
}
@@ -324,7 +319,7 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
@Override
public int getImageCountForItem(int position){
return item.status.reactions.get(position).url == null ? 0 : 1;
return item.status.reactions.get(position).getUrl(item.playGifs)==null ? 0 : 1;
}
@Override
@@ -364,7 +359,7 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
btn.setText(UiUtils.abbreviateNumber(reaction.count));
btn.setContentDescription(reaction.name);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) btn.setTooltipText(reaction.name);
if(reaction.url==null){
if(reaction.getUrl(parent.playGifs)==null){
Paint p=new Paint();
p.setTextSize(V.sp(18));
TextDrawable drawable=new TextDrawable(p, reaction.name);
@@ -392,7 +387,11 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
break;
}
E.post(new StatusCountersUpdatedEvent(parent.status, adapter.parentHolder));
if(parent.isHidden()){
adapter.parentHolder.root.setVisibility(View.GONE);
adapter.parentHolder.line.setVisibility(View.GONE);
}
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());
});
@@ -406,7 +405,7 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem {
args.putString("statusID", parent.status.id);
int atSymbolIndex = emojiReaction.name.indexOf("@");
args.putString("emoji", atSymbolIndex != -1 ? emojiReaction.name.substring(0, atSymbolIndex) : emojiReaction.name);
args.putString("url", emojiReaction.url);
args.putString("url", emojiReaction.getUrl(parent.playGifs));
args.putInt("count", emojiReaction.count);
Nav.go(parent.parentFragment.getActivity(), StatusEmojiReactionsListFragment.class, args);
return true;

View File

@@ -1,5 +1,8 @@
package org.joinmastodon.android.ui.displayitems;
import static org.joinmastodon.android.ui.utils.UiUtils.opacityIn;
import static org.joinmastodon.android.ui.utils.UiUtils.opacityOut;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
@@ -12,8 +15,6 @@ import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.TextView;
@@ -56,7 +57,6 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
public static class Holder extends StatusDisplayItem.Holder<FooterStatusDisplayItem>{
private final TextView replies, boosts, favorites;
private final View reply, boost, favorite, share, bookmark;
private static final Animation opacityOut, opacityIn;
private View touchingView = null;
private boolean longClickPerformed = false;
@@ -77,18 +77,6 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
}
};
private static final float ALPHA_PRESSED=0.55f;
static {
opacityOut = new AlphaAnimation(1, ALPHA_PRESSED);
opacityOut.setDuration(300);
opacityOut.setInterpolator(CubicBezierInterpolator.DEFAULT);
opacityOut.setFillAfter(true);
opacityIn = new AlphaAnimation(ALPHA_PRESSED, 1);
opacityIn.setDuration(400);
opacityIn.setInterpolator(CubicBezierInterpolator.DEFAULT);
}
public Holder(Activity activity, ViewGroup parent){
super(activity, R.layout.display_item_footer, parent);

View File

@@ -8,14 +8,21 @@ import android.widget.TextView;
import org.joinmastodon.android.R;
import org.joinmastodon.android.fragments.BaseStatusListFragment;
import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.ui.drawables.SawtoothTearDrawable;
import org.joinmastodon.android.ui.utils.UiUtils;
import java.time.Instant;
import me.grishka.appkit.utils.V;
// Mind the gap!
public class GapStatusDisplayItem extends StatusDisplayItem{
public boolean loading;
private Status status;
public GapStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment){
public GapStatusDisplayItem(String parentID, BaseStatusListFragment<?> parentFragment, Status status){
super(parentID, parentFragment);
this.status=status;
}
@Override
@@ -24,25 +31,53 @@ public class GapStatusDisplayItem extends StatusDisplayItem{
}
public static class Holder extends StatusDisplayItem.Holder<GapStatusDisplayItem>{
public final ProgressBar progress;
public final TextView text;
public final ProgressBar progressTop, progressBottom;
public final TextView textTop, gap, textBottom;
public final View top, bottom;
public Holder(Context context, ViewGroup parent){
super(context, R.layout.display_item_gap, parent);
progress=findViewById(R.id.progress);
text=findViewById(R.id.text);
itemView.setForeground(new SawtoothTearDrawable(context));
progressTop=findViewById(R.id.progress_top);
progressBottom=findViewById(R.id.progress_bottom);
textTop=findViewById(R.id.text_top);
textBottom=findViewById(R.id.text_bottom);
top=findViewById(R.id.top);
top.setOnClickListener(this::onViewClick);
bottom=findViewById(R.id.bottom);
bottom.setOnClickListener(this::onViewClick);
gap=findViewById(R.id.gap);
gap.setForeground(new SawtoothTearDrawable(context));
}
@Override
public void onBind(GapStatusDisplayItem item){
text.setVisibility(item.loading ? View.GONE : View.VISIBLE);
progress.setVisibility(item.loading ? View.VISIBLE : View.GONE);
if(!item.loading){
progressBottom.setVisibility(View.GONE);
progressTop.setVisibility(View.GONE);
}
top.setClickable(!item.loading);
bottom.setClickable(!item.loading);
StatusDisplayItem next=getNextVisibleDisplayItem().orElse(null);
Instant dateBelow=next instanceof HeaderStatusDisplayItem h ? h.status.createdAt
: next instanceof ReblogOrReplyLineStatusDisplayItem l ? l.status.createdAt
: null;
String text=dateBelow!=null && item.status.createdAt!=null && dateBelow.isBefore(item.status.createdAt)
? UiUtils.formatPeriodBetween(item.parentFragment.getContext(), dateBelow, item.status.createdAt)
: null;
gap.setText(text);
int p=text==null ? V.dp(6) : V.dp(20);
gap.setPadding(p, p, p, p);
}
private void onViewClick(View v){
if(item.loading) return;
boolean isTop=v==top;
(isTop ? textTop : textBottom).startAnimation(UiUtils.opacityOut);
V.setVisibilityAnimated((isTop ? progressTop : progressBottom), View.VISIBLE);
item.parentFragment.onGapClick(this, isTop);
}
@Override
public void onClick(){
item.parentFragment.onGapClick(this);
}
public void onClick(){}
}
}

View File

@@ -86,10 +86,14 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
public HeaderStatusDisplayItem(String parentID, Account user, Instant createdAt, BaseStatusListFragment parentFragment, String accountID, Status status, CharSequence extraText, Notification notification, ScheduledStatus scheduledStatus){
super(parentID, parentFragment);
user=scheduledStatus != null ? AccountSessionManager.getInstance().getAccount(accountID).self : user;
AccountSession session = AccountSessionManager.get(accountID);
user=scheduledStatus != null ? session.self : user;
this.user=user;
this.createdAt=createdAt;
avaRequest=new UrlImageLoaderRequest(GlobalUserPreferences.playGifs ? user.avatar : user.avatarStatic, V.dp(50), V.dp(50));
avaRequest=new UrlImageLoaderRequest(
TextUtils.isEmpty(user.avatar) ? session.getDefaultAvatarUrl() :
GlobalUserPreferences.playGifs ? user.avatar : user.avatarStatic,
V.dp(50), V.dp(50));
this.accountID=accountID;
parsedName=new SpannableStringBuilder(user.displayName);
this.status=status;
@@ -134,7 +138,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
public static class Holder extends StatusDisplayItem.Holder<HeaderStatusDisplayItem> implements ImageLoaderViewHolder{
private final TextView name, time, username, extraText, pronouns;
private final View collapseBtn, timeUsernameSeparator;
private final ImageView avatar, more, visibility, deleteNotification, unreadIndicator, markAsRead, collapseBtnIcon;
private final ImageView avatar, more, visibility, deleteNotification, unreadIndicator, markAsRead, collapseBtnIcon, botIcon;
private final PopupMenu optionsMenu;
private Relationship relationship;
private APIRequest<?> currentRelationshipRequest;
@@ -148,6 +152,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
name=findViewById(R.id.name);
time=findViewById(R.id.time);
username=findViewById(R.id.username);
botIcon=findViewById(R.id.bot_icon);
timeUsernameSeparator=findViewById(R.id.separator);
avatar=findViewById(R.id.avatar);
more=findViewById(R.id.more);
@@ -192,7 +197,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
}
}
boolean isPixelfed = item.parentFragment.isInstancePixelfed();
boolean textEmpty = TextUtils.isEmpty(item.status.content) && TextUtils.isEmpty(item.status.spoilerText);
boolean textEmpty = TextUtils.isEmpty(item.status.content) && !item.status.hasSpoiler();
if(!redraft && (isPixelfed || textEmpty)){
// pixelfed doesn't support /statuses/:id/source :/
if (isPixelfed) {
@@ -322,13 +327,21 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
this.time.setVisibility(time==null ? View.GONE : View.VISIBLE);
if(time!=null) this.time.setText(time);
botIcon.setVisibility(item.user.bot ? View.VISIBLE : View.GONE);
botIcon.setColorFilter(username.getCurrentTextColor());
deleteNotification.setVisibility(GlobalUserPreferences.enableDeleteNotifications && item.notification!=null && !item.inset ? View.VISIBLE : View.GONE);
if (item.hasVisibilityToggle){
boolean disabled = !item.status.sensitiveRevealed ||
(!TextUtils.isEmpty(item.status.spoilerText) &&
!item.status.spoilerRevealed);
visibility.setEnabled(!disabled);
V.setVisibilityAnimated(visibility, disabled ? View.INVISIBLE : View.VISIBLE);
boolean hidden = !item.status.sensitiveRevealed || (item.status.hasSpoiler() && !item.status.spoilerRevealed);
// doing this because V.setVisibilityAnimated ignores changes between INVISIBLE and GONE
int newVis=hidden ? View.INVISIBLE : View.VISIBLE;
if(newVis==View.INVISIBLE && visibility.getVisibility()==View.GONE)
visibility.setVisibility(newVis);
else
V.setVisibilityAnimated(visibility, newVis);
visibility.setEnabled(!hidden);
visibility.setContentDescription(item.parentFragment.getString(item.status.sensitiveRevealed ? R.string.spoiler_hide : R.string.spoiler_show));
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
visibility.setTooltipText(visibility.getContentDescription());
@@ -421,6 +434,8 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
}
private void onAvaClick(View v){
if (TextUtils.isEmpty(item.user.url))
return;
if (item.announcement != null) {
UiUtils.openURL(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), item.user.url);
return;

View File

@@ -20,6 +20,8 @@ import android.widget.TextView;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.session.AccountSession;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.fragments.BaseStatusListFragment;
import org.joinmastodon.android.fragments.ProfileFragment;
import org.joinmastodon.android.model.Emoji;
@@ -53,7 +55,11 @@ public class NotificationHeaderStatusDisplayItem extends StatusDisplayItem{
if(notification.type==Notification.Type.POLL){
text=parentFragment.getString(R.string.poll_ended);
}else{
avaRequest=new UrlImageLoaderRequest(GlobalUserPreferences.playGifs ? notification.account.avatar : notification.account.avatarStatic, V.dp(50), V.dp(50));
AccountSession session = AccountSessionManager.get(accountID);
avaRequest=new UrlImageLoaderRequest(
TextUtils.isEmpty(notification.account.avatar) ? session.getDefaultAvatarUrl() :
GlobalUserPreferences.playGifs ? notification.account.avatar : notification.account.avatarStatic,
V.dp(50), V.dp(50));
SpannableStringBuilder parsedName=new SpannableStringBuilder(notification.account.displayName);
HtmlParser.parseCustomEmoji(parsedName, notification.account.emojis);
String str = parentFragment.getString(switch(notification.type){

View File

@@ -79,7 +79,7 @@ public class PollOptionStatusDisplayItem extends StatusDisplayItem{
progressBg=activity.getResources().getDrawable(R.drawable.bg_poll_option_voted, activity.getTheme()).mutate();
progressBgInset=activity.getResources().getDrawable(R.drawable.bg_poll_option_voted_inset, activity.getTheme()).mutate();
itemView.setOnClickListener(this::onButtonClick);
button.setOutlineProvider(OutlineProviders.roundedRect(24));
button.setOutlineProvider(OutlineProviders.M3_BUTTON);
button.setClipToOutline(true);
}

View File

@@ -17,6 +17,7 @@ import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.R;
import org.joinmastodon.android.fragments.BaseStatusListFragment;
import org.joinmastodon.android.model.Emoji;
import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.model.StatusPrivacy;
import org.joinmastodon.android.ui.text.HtmlParser;
import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
@@ -43,18 +44,20 @@ public class ReblogOrReplyLineStatusDisplayItem extends StatusDisplayItem{
public boolean needBottomPadding;
ReblogOrReplyLineStatusDisplayItem extra;
CharSequence fullText;
Status status;
public ReblogOrReplyLineStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, CharSequence text, List<Emoji> emojis, @DrawableRes int icon, StatusPrivacy visibility, @Nullable View.OnClickListener handleClick) {
this(parentID, parentFragment, text, emojis, icon, visibility, handleClick, text);
public ReblogOrReplyLineStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, CharSequence text, List<Emoji> emojis, @DrawableRes int icon, StatusPrivacy visibility, @Nullable View.OnClickListener handleClick, Status status) {
this(parentID, parentFragment, text, emojis, icon, visibility, handleClick, text, status);
}
public ReblogOrReplyLineStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, CharSequence text, List<Emoji> emojis, @DrawableRes int icon, StatusPrivacy visibility, @Nullable View.OnClickListener handleClick, CharSequence fullText) {
public ReblogOrReplyLineStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, CharSequence text, List<Emoji> emojis, @DrawableRes int icon, StatusPrivacy visibility, @Nullable View.OnClickListener handleClick, CharSequence fullText, Status status) {
super(parentID, parentFragment);
SpannableStringBuilder ssb=new SpannableStringBuilder(text);
HtmlParser.parseCustomEmoji(ssb, emojis);
this.text=ssb;
emojiHelper.setText(ssb);
this.icon=icon;
this.status=status;
this.handleClick=handleClick;
TypedValue outValue = new TypedValue();
context.getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);

View File

@@ -6,9 +6,9 @@ import android.graphics.drawable.LayerDrawable;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.R;
import org.joinmastodon.android.fragments.BaseStatusListFragment;
import org.joinmastodon.android.model.Status;
@@ -29,11 +29,13 @@ public class SpoilerStatusDisplayItem extends StatusDisplayItem{
private final CharSequence parsedTitle;
private final CustomEmojiHelper emojiHelper;
private final Type type;
private final int attachmentCount;
public SpoilerStatusDisplayItem(String parentID, BaseStatusListFragment<?> parentFragment, String title, Status statusForContent, Type type){
super(parentID, parentFragment);
this.status=statusForContent;
this.type=type;
this.attachmentCount=statusForContent.mediaAttachments.size();
if(TextUtils.isEmpty(title)){
parsedTitle=HtmlParser.parseCustomEmoji(statusForContent.spoilerText, statusForContent.emojis);
emojiHelper=new CustomEmojiHelper();
@@ -62,12 +64,14 @@ public class SpoilerStatusDisplayItem extends StatusDisplayItem{
public static class Holder extends StatusDisplayItem.Holder<SpoilerStatusDisplayItem> implements ImageLoaderViewHolder{
private final TextView title, action;
private final View button;
private final ImageView mediaIcon;
public Holder(Context context, ViewGroup parent, Type type){
super(context, R.layout.display_item_spoiler, parent);
title=findViewById(R.id.spoiler_title);
action=findViewById(R.id.spoiler_action);
button=findViewById(R.id.spoiler_button);
mediaIcon=findViewById(R.id.media_icon);
button.setOutlineProvider(OutlineProviders.roundedRect(8));
button.setClipToOutline(true);
@@ -94,6 +98,10 @@ public class SpoilerStatusDisplayItem extends StatusDisplayItem{
itemView.getPaddingRight(),
item.inset ? itemView.getPaddingTop() : 0
);
mediaIcon.setVisibility(item.attachmentCount > 0 ? View.VISIBLE : View.GONE);
mediaIcon.setImageResource(item.attachmentCount > 1
? R.drawable.ic_fluent_image_multiple_24_regular
: R.drawable.ic_fluent_image_24_regular);
}
@Override

View File

@@ -1,5 +1,8 @@
package org.joinmastodon.android.ui.displayitems;
import static org.joinmastodon.android.api.session.AccountLocalPreferences.ShowEmojiReactions.ALWAYS;
import static org.joinmastodon.android.api.session.AccountLocalPreferences.ShowEmojiReactions.ONLY_OPENED;
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
@@ -12,6 +15,7 @@ import android.view.ViewGroup;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.session.AccountLocalPreferences;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.fragments.BaseStatusListFragment;
import org.joinmastodon.android.fragments.HashtagTimelineFragment;
@@ -120,19 +124,6 @@ public abstract class StatusDisplayItem{
};
}
public static ArrayList<StatusDisplayItem> buildItems(BaseStatusListFragment<?> fragment, Status status, String accountID, DisplayItemsParent parentObject, Map<String, Account> knownAccounts, boolean inset, boolean showReactions, boolean addFooter, boolean disableTranslate, FilterContext filterContext) {
int flags=0;
if(inset)
flags|=FLAG_INSET;
if(!addFooter)
flags|=FLAG_NO_FOOTER;
if (disableTranslate)
flags|=FLAG_NO_TRANSLATE;
if (!showReactions)
flags|=FLAG_NO_EMOJI_REACTIONS;
return buildItems(fragment, status, accountID, parentObject, knownAccounts, filterContext, flags);
}
public static ReblogOrReplyLineStatusDisplayItem buildReplyLine(BaseStatusListFragment<?> fragment, Status status, String accountID, DisplayItemsParent parent, Account account, boolean threadReply) {
String parentID = parent.getID();
String text = threadReply ? fragment.getString(R.string.sk_show_thread)
@@ -144,7 +135,7 @@ public abstract class StatusDisplayItem{
: fragment.getString(R.string.in_reply_to, account.displayName);
return new ReblogOrReplyLineStatusDisplayItem(
parentID, fragment, text, account == null ? List.of() : account.emojis,
R.drawable.ic_fluent_arrow_reply_20sp_filled, null, null, fullText
R.drawable.ic_fluent_arrow_reply_20sp_filled, null, null, fullText, status
);
}
@@ -176,7 +167,7 @@ public abstract class StatusDisplayItem{
items.add(new ReblogOrReplyLineStatusDisplayItem(parentID, fragment, text, status.account.emojis, R.drawable.ic_fluent_arrow_repeat_all_20sp_filled, isOwnPost ? status.visibility : null, i->{
args.putParcelable("profileAccount", Parcels.wrap(status.account));
Nav.go(fragment.getActivity(), ProfileFragment.class, args);
}, fullText));
}, fullText, status));
} else if (!(status.tags.isEmpty() ||
fragment instanceof HashtagTimelineFragment ||
fragment instanceof ListTimelineFragment
@@ -192,7 +183,7 @@ public abstract class StatusDisplayItem{
i -> {
args.putString("hashtag", hashtag.name);
Nav.go(fragment.getActivity(), HashtagTimelineFragment.class, args);
}
}, status
)));
}
@@ -226,7 +217,7 @@ public abstract class StatusDisplayItem{
}
ArrayList<StatusDisplayItem> contentItems;
if(!TextUtils.isEmpty(statusForContent.spoilerText)){
if(statusForContent.hasSpoiler()){
if (AccountSessionManager.get(accountID).getLocalPreferences().revealCWs) statusForContent.spoilerRevealed = true;
SpoilerStatusDisplayItem spoilerItem=new SpoilerStatusDisplayItem(parentID, fragment, null, statusForContent, Type.SPOILER);
items.add(spoilerItem);
@@ -290,10 +281,12 @@ public abstract class StatusDisplayItem{
if(contentItems!=items && statusForContent.spoilerRevealed){
items.addAll(contentItems);
}
if((flags & FLAG_NO_EMOJI_REACTIONS)==0
&& AccountSessionManager.get(accountID).getLocalPreferences().emojiReactionsEnabled){
AccountLocalPreferences lp=fragment.getLocalPrefs();
if((flags & FLAG_NO_EMOJI_REACTIONS)==0 && lp.emojiReactionsEnabled &&
(lp.showEmojiReactions!=ONLY_OPENED || fragment instanceof ThreadFragment)){
boolean isMainStatus=fragment instanceof ThreadFragment t && t.getMainStatus().id.equals(statusForContent.id);
items.add(new EmojiReactionsStatusDisplayItem(parentID, fragment, statusForContent, accountID, !isMainStatus, false));
boolean showAddButton=lp.showEmojiReactions==ALWAYS || isMainStatus;
items.add(new EmojiReactionsStatusDisplayItem(parentID, fragment, statusForContent, accountID, !showAddButton, false));
}
FooterStatusDisplayItem footer=null;
if((flags & FLAG_NO_FOOTER)==0){
@@ -301,12 +294,12 @@ public abstract class StatusDisplayItem{
footer.hideCounts=hideCounts;
items.add(footer);
if(status.hasGapAfter && !(fragment instanceof ThreadFragment))
items.add(new GapStatusDisplayItem(parentID, fragment));
items.add(new GapStatusDisplayItem(parentID, fragment, status));
}
int i=1;
boolean inset=(flags & FLAG_INSET)!=0;
// add inset dummy so last content item doesn't clip out of inset bounds
if(inset || footer==null){
if((inset || footer==null) && (flags & FLAG_CHECKABLE)==0){
items.add(new DummyStatusDisplayItem(parentID, fragment));
// in case we ever need the dummy to display a margin for the media grid again:
// (i forgot why we apparently don't need this anymore)
@@ -398,15 +391,7 @@ public abstract class StatusDisplayItem{
}
return Optional.empty();
}
// int nextNextPos=getAbsoluteAdapterPosition() + 2;
// if(next.map(n->n instanceof EmojiReactionsStatusDisplayItem e && e.isHidden()).orElse(false)){
// List<StatusDisplayItem> displayItems=item.parentFragment.getDisplayItems();
// return displayItems.size() > nextNextPos
// ? Optional.of(displayItems.get(nextNextPos))
// : Optional.empty();
// }else{
// return next;
// }
public Optional<StatusDisplayItem> getNextDisplayItem(){
return getDisplayItemOffset(1);
}

View File

@@ -195,11 +195,10 @@ public class TextStatusDisplayItem extends StatusDisplayItem{
readMore.setText(item.status.textExpanded ? R.string.sk_collapse : R.string.sk_expand);
StatusDisplayItem next=getNextVisibleDisplayItem().orElse(null);
int bottomPadding=next instanceof FooterStatusDisplayItem
? V.dp(6)
: (!item.inset && next instanceof DummyStatusDisplayItem) ||
next instanceof EmojiReactionsStatusDisplayItem e && !e.isHidden()
? 0
if(next!=null && !next.parentID.equals(item.parentID)) next=null;
int bottomPadding=next instanceof FooterStatusDisplayItem ? V.dp(6)
: item.inset ? V.dp(12)
: (next instanceof EmojiReactionsStatusDisplayItem || next==null) ? 0
: V.dp(12);
itemView.setPadding(itemView.getPaddingLeft(), itemView.getPaddingTop(), itemView.getPaddingRight(), bottomPadding);

View File

@@ -23,9 +23,9 @@ import me.grishka.appkit.utils.V;
public class SawtoothTearDrawable extends Drawable{
private final Paint topPaint, bottomPaint;
private static final int TOP_SAWTOOTH_HEIGHT=5;
private static final int BOTTOM_SAWTOOTH_HEIGHT=3;
private static final int STROKE_WIDTH=2;
private static final int TOP_SAWTOOTH_HEIGHT=4;
private static final int BOTTOM_SAWTOOTH_HEIGHT=4;
private static final int STROKE_WIDTH=1;
private static final int SAWTOOTH_PERIOD=14;
public SawtoothTearDrawable(Context context){

View File

@@ -1715,7 +1715,9 @@ public class TabLayout extends HorizontalScrollView implements CustomViewHelper{
child.getLayoutParams().height);
int childWidthMeasureSpec =
MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY);
MeasureSpec.makeMeasureSpec(
getMeasuredWidth() - getPaddingLeft() - getPaddingRight(),
MeasureSpec.EXACTLY);
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}
}

View File

@@ -10,6 +10,7 @@ import android.widget.TextView;
import org.joinmastodon.android.MastodonApp;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.model.TimelineDefinition;
import java.util.EnumSet;
@@ -44,7 +45,7 @@ public class DiscoverInfoBannerHelper{
banner=((Activity)list.getContext()).getLayoutInflater().inflate(R.layout.discover_info_banner, list, false);
TextView text=banner.findViewById(R.id.banner_text);
text.setText(switch(type){
case TRENDING_POSTS -> list.getResources().getString(R.string.trending_posts_info_banner);
case TRENDING_POSTS -> list.getResources().getString(R.string.sk_trending_posts_info_banner);
case TRENDING_LINKS -> list.getResources().getString(R.string.trending_links_info_banner);
case FEDERATED_TIMELINE -> list.getResources().getString(R.string.sk_federated_timeline_info_banner);
case POST_NOTIFICATIONS -> list.getResources().getString(R.string.sk_notify_posts_info_banner);
@@ -57,8 +58,10 @@ public class DiscoverInfoBannerHelper{
case TRENDING_POSTS -> R.drawable.ic_fluent_arrow_trending_24_regular;
case TRENDING_LINKS -> R.drawable.ic_fluent_news_24_regular;
case ACCOUNTS -> R.drawable.ic_fluent_people_add_24_regular;
// no icon because those are displayed as timelines - with icon in top left
case LOCAL_TIMELINE, FEDERATED_TIMELINE, BUBBLE_TIMELINE, POST_NOTIFICATIONS -> 0;
case LOCAL_TIMELINE -> TimelineDefinition.LOCAL_TIMELINE.getDefaultIcon().iconRes;
case FEDERATED_TIMELINE -> TimelineDefinition.FEDERATED_TIMELINE.getDefaultIcon().iconRes;
case BUBBLE_TIMELINE -> TimelineDefinition.BUBBLE_TIMELINE.getDefaultIcon().iconRes;
case POST_NOTIFICATIONS -> TimelineDefinition.POSTS_TIMELINE.getDefaultIcon().iconRes;
});
adapter.addAdapter(new SingleViewRecyclerAdapter(banner));
}

View File

@@ -54,6 +54,8 @@ import android.view.SubMenu;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.webkit.MimeTypeMap;
import android.widget.Button;
import android.widget.ImageView;
@@ -96,7 +98,6 @@ import org.joinmastodon.android.fragments.ComposeFragment;
import org.joinmastodon.android.fragments.HashtagTimelineFragment;
import org.joinmastodon.android.fragments.ProfileFragment;
import org.joinmastodon.android.fragments.ThreadFragment;
import org.joinmastodon.android.fragments.settings.SettingsServerAboutFragment;
import org.joinmastodon.android.fragments.settings.SettingsServerFragment;
import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.AccountField;
@@ -173,6 +174,19 @@ public class UiUtils {
private static final DateTimeFormatter TIME_FORMATTER=DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT);
public static int MAX_WIDTH, SCROLL_TO_TOP_DELTA;
public static final float ALPHA_PRESSED=0.55f;
public static final Animation opacityOut, opacityIn;
static {
opacityOut = new AlphaAnimation(1, ALPHA_PRESSED);
opacityOut.setDuration(300);
opacityOut.setInterpolator(CubicBezierInterpolator.DEFAULT);
opacityOut.setFillAfter(true);
opacityIn = new AlphaAnimation(ALPHA_PRESSED, 1);
opacityIn.setDuration(400);
opacityIn.setInterpolator(CubicBezierInterpolator.DEFAULT);
}
private UiUtils() {
}
@@ -192,28 +206,33 @@ public class UiUtils {
}
public static String formatRelativeTimestamp(Context context, Instant instant) {
long t = instant.toEpochMilli();
long now = System.currentTimeMillis();
return formatPeriodBetween(context, instant, null);
}
public static String formatPeriodBetween(Context context, Instant since, Instant until) {
boolean ago = until == null;
long t = since.toEpochMilli();
long now = ago ? System.currentTimeMillis() : until.toEpochMilli();
long diff = now - t;
if(diff<1000L){
return context.getString(R.string.time_now);
}else if(diff<60_000L){
return context.getString(R.string.time_seconds_ago_short, diff/1000L);
return context.getString(ago ? R.string.time_seconds_ago_short : R.string.sk_time_seconds, diff/1000L);
}else if(diff<3600_000L){
return context.getString(R.string.time_minutes_ago_short, diff/60_000L);
return context.getString(ago ? R.string.time_minutes_ago_short : R.string.sk_time_minutes, diff/60_000L);
}else if(diff<3600_000L*24L){
return context.getString(R.string.time_hours_ago_short, diff/3600_000L);
return context.getString(ago ? R.string.time_hours_ago_short : R.string.sk_time_hours, diff/3600_000L);
} else {
int days = (int) (diff / (3600_000L * 24L));
if (days > 30) {
ZonedDateTime dt = instant.atZone(ZoneId.systemDefault());
if (ago && days > 30) {
ZonedDateTime dt = since.atZone(ZoneId.systemDefault());
if (dt.getYear() == ZonedDateTime.now().getYear()) {
return DATE_FORMATTER_SHORT.format(dt);
} else {
return DATE_FORMATTER_SHORT_WITH_YEAR.format(dt);
}
}
return context.getString(R.string.time_days_ago_short, days);
return context.getString(ago ? R.string.time_days_ago_short : R.string.sk_time_days, days);
}
}

View File

@@ -27,10 +27,14 @@ import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.joinmastodon.android.MastodonApp;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.MastodonAPIController;
import org.joinmastodon.android.api.ProgressListener;
import org.joinmastodon.android.api.requests.statuses.CreateStatus;
import org.joinmastodon.android.api.requests.statuses.GetAttachmentByID;
import org.joinmastodon.android.api.requests.statuses.UpdateAttachment;
import org.joinmastodon.android.api.requests.statuses.UploadAttachment;
@@ -47,8 +51,11 @@ import org.parceler.Parcel;
import org.parceler.Parcels;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;
import java.util.Objects;
import java.util.function.Consumer;
@@ -551,6 +558,14 @@ public class ComposeMediaViewController{
return attachments.stream().map(a->a.serverAttachment.id).collect(Collectors.toList());
}
public List<CreateStatus.Request.MediaAttribute> getAttachmentAttributes(){
List<CreateStatus.Request.MediaAttribute> mediaAttributes = new ArrayList<>();
for (DraftMediaAttachment att:attachments){
mediaAttributes.add(new CreateStatus.Request.MediaAttribute(att.serverAttachment.id, att.description, null));
}
return mediaAttributes;
}
public boolean isEmpty(){
return attachments.isEmpty();
}
@@ -592,7 +607,7 @@ public class ComposeMediaViewController{
public void saveAltTextsBeforePublishing(Runnable onSuccess, Consumer<ErrorResponse> onError){
ArrayList<UpdateAttachment> updateAltTextRequests=new ArrayList<>();
for(DraftMediaAttachment att:attachments){
if(!att.descriptionSaved){
if(!att.descriptionSaved && (fragment.editingStatus==null || !fragment.editingStatus.mediaAttachments.contains(att.serverAttachment))){
UpdateAttachment req=new UpdateAttachment(att.serverAttachment.id, att.description);
req.setCallback(new Callback<>(){
@Override

View File

@@ -213,6 +213,7 @@ public class AccountViewHolder extends BindableViewHolder<AccountViewModel> impl
Account account=item.account;
menu.findItem(R.id.share).setTitle(fragment.getString(R.string.share_user, account.getDisplayUsername()));
menu.findItem(R.id.manage_user_lists).setTitle(fragment.getString(R.string.sk_lists_with_user, account.getShortUsername()));
menu.findItem(R.id.mute).setTitle(fragment.getString(relationship.muting ? R.string.unmute_user : R.string.mute_user, account.getDisplayUsername()));
menu.findItem(R.id.block).setTitle(fragment.getString(relationship.blocking ? R.string.unblock_user : R.string.block_user, account.getDisplayUsername()));
menu.findItem(R.id.report).setTitle(fragment.getString(R.string.report_user, account.getDisplayUsername()));

View File

@@ -40,11 +40,9 @@ public abstract class ListItemViewHolder<T extends ListItem<?>> extends Bindable
if(TextUtils.isEmpty(item.subtitle) && item.subtitleRes==0){
subtitle.setVisibility(View.GONE);
title.setMaxLines(2);
view.setMinimumHeight(V.dp(56));
}else{
subtitle.setVisibility(View.VISIBLE);
title.setMaxLines(1);
view.setMinimumHeight(V.dp(72));
if(TextUtils.isEmpty(item.subtitle))
subtitle.setText(item.subtitleRes);

View File

@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<color android:color="?colorM3SurfaceVariant"/>
<color android:color="?colorM3SecondaryContainer"/>
</item>
<item android:drawable="?android:selectableItemBackground"/>
</layer-list>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:left="-1dp" android:right="-1dp">
<shape android:shape="rectangle">
<solid android:color="?colorM3Surface" />
<stroke android:color="?colorM3OutlineVariant" android:width="1dp" />
</shape>
</item>
</layer-list>

View File

@@ -0,0 +1,3 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
<path android:pathData="M13.72 5.78c0.293 0.293 0.767 0.293 1.06 0 0.293-0.293 0.293-0.767 0-1.06l-2.5-2.5c-0.293-0.293-0.767-0.293-1.06 0l-2.5 2.5c-0.293 0.293-0.293 0.767 0 1.06 0.293 0.293 0.767 0.293 1.06 0L11 4.56v4.19c0 0.414 0.336 0.75 0.75 0.75s0.75-0.336 0.75-0.75V4.56l1.22 1.22zM4 11.75C4 11.336 4.336 11 4.75 11h14.5c0.414 0 0.75 0.336 0.75 0.75s-0.336 0.75-0.75 0.75H4.75C4.336 12.5 4 12.164 4 11.75zm8.5 3c0-0.414-0.336-0.75-0.75-0.75S11 14.336 11 14.75v4.69l-1.22-1.22c-0.293-0.293-0.767-0.293-1.06 0-0.293 0.293-0.293 0.767 0 1.06l2.5 2.5c0.293 0.293 0.767 0.293 1.06 0l2.5-2.5c0.293-0.293 0.293-0.767 0-1.06-0.293-0.293-0.767-0.293-1.06 0l-1.22 1.22v-4.69z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@@ -0,0 +1,3 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="20dp" android:height="20dp" android:viewportWidth="20" android:viewportHeight="20">
<path android:pathData="M14.69 11.503c1 0 1.81 0.81 1.81 1.81v0.689h-0.005c-0.034 0.78-0.248 1.757-1.123 2.555C14.416 17.43 12.765 18 10 18c-2.766 0-4.416-0.57-5.372-1.443-0.875-0.798-1.089-1.776-1.123-2.555H3.5v-0.69c0-0.999 0.81-1.809 1.81-1.809h9.38zM6.5 3C5.672 3 5 3.672 5 4.5v4C5 9.328 5.672 10 6.5 10h7c0.828 0 1.5-0.672 1.5-1.5v-4C15 3.672 14.328 3 13.5 3h-3V2.5C10.5 2.191 10.276 2 10 2S9.5 2.23 9.5 2.5V3h-3zM7 6.5c0-0.552 0.448-1 1-1s1 0.448 1 1-0.448 1-1 1-1-0.448-1-1zm4 0c0-0.552 0.448-1 1-1s1 0.448 1 1-0.448 1-1 1-1-0.448-1-1z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@@ -0,0 +1,3 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="20dp" android:height="20dp" android:viewportWidth="20" android:viewportHeight="20">
<path android:pathData="M8.46 1.897l0.99 0.39c0.353 0.138 0.746 0.138 1.099 0l0.99-0.39c1.21-0.477 2.582 0.091 3.102 1.285l0.424 0.975c0.151 0.348 0.429 0.626 0.777 0.777l0.975 0.424c1.194 0.52 1.762 1.891 1.285 3.103l-0.39 0.99c-0.139 0.352-0.139 0.745 0 1.098l0.39 0.99c0.477 1.21-0.091 2.582-1.285 3.102l-0.975 0.424c-0.348 0.151-0.626 0.429-0.777 0.777l-0.424 0.975c-0.52 1.194-1.891 1.762-3.103 1.285l-0.99-0.39c-0.352-0.139-0.745-0.139-1.098 0l-0.99 0.39c-1.21 0.477-2.582-0.091-3.102-1.285l-0.424-0.975c-0.151-0.348-0.429-0.626-0.777-0.777l-0.975-0.424c-1.194-0.52-1.762-1.891-1.285-3.103l0.39-0.99c0.138-0.352 0.138-0.745 0-1.098l-0.39-0.99C1.42 7.25 1.988 5.878 3.182 5.358l0.975-0.424c0.348-0.151 0.626-0.429 0.777-0.777l0.424-0.975C5.878 1.988 7.25 1.42 8.461 1.897zm3.445 0.93l-0.99 0.39c-0.588 0.232-1.243 0.232-1.831 0l-0.99-0.39C7.384 2.549 6.58 2.881 6.275 3.582L5.851 4.556C5.599 5.136 5.136 5.6 4.556 5.851L3.581 6.275c-0.7 0.305-1.033 1.109-0.753 1.82l0.389 0.989c0.232 0.588 0.232 1.243 0 1.831l-0.39 0.99c-0.279 0.71 0.054 1.514 0.754 1.819l0.975 0.424c0.58 0.252 1.043 0.715 1.295 1.295l0.424 0.975c0.305 0.7 1.109 1.033 1.82 0.753l0.989-0.39c0.588-0.23 1.243-0.23 1.831 0l0.99 0.39c0.71 0.28 1.514-0.053 1.819-0.753l0.424-0.975c0.252-0.58 0.715-1.043 1.295-1.295l0.975-0.424c0.7-0.305 1.033-1.11 0.753-1.82l-0.39-0.989c-0.23-0.588-0.23-1.243 0-1.831l0.39-0.99c0.28-0.71-0.053-1.514-0.753-1.819l-0.975-0.424c-0.58-0.252-1.043-0.715-1.295-1.295l-0.424-0.975c-0.305-0.7-1.11-1.033-1.82-0.753zm-2.927 8.944l3.648-4.104c0.183-0.206 0.5-0.225 0.706-0.041 0.183 0.163 0.218 0.43 0.095 0.633l-0.054 0.073-4 4.5c-0.17 0.19-0.451 0.22-0.655 0.081l-0.072-0.06-2-2c-0.195-0.195-0.195-0.512 0-0.707 0.173-0.174 0.443-0.193 0.638-0.058l0.069 0.058 1.625 1.625 3.648-4.104-3.648 4.104z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@@ -0,0 +1,3 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="20dp" android:height="20dp" android:viewportWidth="20" android:viewportHeight="20">
<path android:pathData="M15.794 8.733c0.286 0.3 0.274 0.774-0.026 1.06l-5.25 5.001c-0.29 0.276-0.745 0.276-1.035 0l-5.25-5c-0.3-0.287-0.312-0.761-0.026-1.061 0.286-0.3 0.76-0.312 1.06-0.026l4.734 4.508 4.733-4.508c0.3-0.286 0.774-0.274 1.06 0.026zm0-4c0.286 0.3 0.274 0.774-0.026 1.06l-5.25 5.001c-0.29 0.276-0.745 0.276-1.035 0l-5.25-5c-0.3-0.287-0.312-0.761-0.026-1.061 0.286-0.3 0.76-0.312 1.06-0.026l4.734 4.509 4.733-4.51c0.3-0.285 0.774-0.273 1.06 0.027z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@@ -0,0 +1,3 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="20dp" android:height="20dp" android:viewportWidth="20" android:viewportHeight="20">
<path android:pathData="M4.207 15.267c-0.286-0.3-0.274-0.774 0.026-1.06l5.25-5.002c0.29-0.275 0.745-0.275 1.034 0l5.25 5.002c0.3 0.286 0.312 0.76 0.026 1.06-0.286 0.3-0.76 0.312-1.06 0.026L10 10.784l-4.733 4.51c-0.3 0.285-0.774 0.273-1.06-0.027zm0-4.998c-0.286-0.3-0.274-0.775 0.026-1.06l5.25-5.002c0.29-0.276 0.745-0.276 1.034 0l5.25 5.001c0.3 0.286 0.312 0.76 0.026 1.06-0.286 0.3-0.76 0.312-1.06 0.026L10 5.786l-4.733 4.508c-0.3 0.286-0.774 0.275-1.06-0.025z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@@ -0,0 +1,3 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
<path android:pathData="M13.748 8.996c0.69 0 1.248-0.559 1.248-1.248 0-0.69-0.559-1.248-1.248-1.248-0.69 0-1.248 0.559-1.248 1.248 0 0.69 0.559 1.248 1.248 1.248zM6.25 3C4.455 3 3 4.455 3 6.25v9c0 1.795 1.455 3.25 3.25 3.25h9c1.795 0 3.25-1.455 3.25-3.25v-9C18.5 4.455 17.045 3 15.25 3h-9zM4.5 6.25c0-0.966 0.784-1.75 1.75-1.75h9C16.216 4.5 17 5.284 17 6.25v9c0 0.231-0.045 0.452-0.126 0.654l-4.587-4.291c-0.865-0.81-2.21-0.81-3.075 0l-4.586 4.29C4.545 15.701 4.5 15.481 4.5 15.25v-9zm6.762 6.458l4.505 4.214C15.604 16.972 15.43 17 15.25 17h-9c-0.18 0-0.354-0.027-0.518-0.078l4.505-4.214c0.289-0.27 0.737-0.27 1.025 0zM8.75 21c-1.15 0-2.162-0.598-2.74-1.5h9.74c2.071 0 3.75-1.679 3.75-3.75V6.011C20.402 6.59 21 7.6 21 8.751v7C21 18.65 18.65 21 15.75 21h-7z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="16dp" android:height="16dp" android:viewportWidth="16" android:viewportHeight="16">
<group android:translateX="-2" android:translateY="-1">
<path android:pathData="M10 2c1.657 0 3 1.343 3 3v1h1c1.105 0 2 0.895 2 2v7c0 1.105-0.895 2-2 2H6c-1.105 0-2-0.895-2-2V8c0-1.105 0.895-2 2-2h1V5c0-1.657 1.343-3 3-3zm0 8.5c-0.552 0-1 0.448-1 1s0.448 1 1 1 1-0.448 1-1-0.448-1-1-1zM10 4C9.448 4 9 4.448 9 5v1h2V5c0-0.552-0.448-1-1-1z" android:fillColor="@color/fluent_default_icon_tint"/>
</group>
</vector>

View File

@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:fillColor="@android:color/white"
android:pathData="M5.5,19Q4.875,19 4.438,18.562Q4,18.125 4,17.5V9.5Q4,8.875 4.438,8.438Q4.875,8 5.5,8H6V6Q6,4.333 7.167,3.167Q8.333,2 10,2Q11.667,2 12.833,3.167Q14,4.333 14,6V8H14.5Q15.125,8 15.562,8.438Q16,8.875 16,9.5V17.5Q16,18.125 15.562,18.562Q15.125,19 14.5,19ZM7.5,8H12.5V6Q12.5,4.958 11.771,4.229Q11.042,3.5 10,3.5Q8.958,3.5 8.229,4.229Q7.5,4.958 7.5,6ZM10,15Q10.625,15 11.062,14.562Q11.5,14.125 11.5,13.5Q11.5,12.875 11.062,12.438Q10.625,12 10,12Q9.375,12 8.938,12.438Q8.5,12.875 8.5,13.5Q8.5,14.125 8.938,14.562Q9.375,15 10,15Z"/>
</vector>

View File

@@ -15,7 +15,7 @@
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginEnd="16dp"
android:tint="?colorM3OnPrimaryContainer"
android:tint="?colorM3Primary"
android:scaleType="center"
android:importantForAccessibility="no"
tools:src="@drawable/ic_fluent_arrow_trending_24_regular"/>

View File

@@ -43,6 +43,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="-4dp"
android:paddingStart="8dp"
android:paddingEnd="3dp"
android:clipToPadding="false"
android:requiresFadingEdge="horizontal"
android:fadingEdgeLength="24dp" />

View File

@@ -1,24 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="75dp"
android:background="@drawable/bg_timeline_gap">
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/bg_timeline_gap_border">
<TextView
android:id="@+id/text"
<FrameLayout
android:id="@+id/top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center_horizontal"
android:textAppearance="@style/m3_body_large"
android:textColor="?android:textColorSecondary"
android:text="@string/load_missing_posts"/>
android:layout_marginBottom="4dp"
android:background="?android:selectableItemBackground">
<ProgressBar
android:id="@+id/progress"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_gravity="center"
android:visibility="gone"/>
<ProgressBar
android:id="@+id/progress_top"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:visibility="gone"/>
</FrameLayout>
<TextView
android:id="@+id/text_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingHorizontal="16dp"
android:paddingTop="24dp"
android:paddingBottom="20dp"
android:drawablePadding="16dp"
android:drawableEnd="@drawable/ic_fluent_chevron_double_down_20_filled"
android:textAppearance="@style/m3_title_medium"
android:textColor="?android:textColorSecondary"
android:text="@string/sk_load_missing_posts_below"/>
</FrameLayout>
<TextView
android:id="@+id/gap"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:gravity="center"
android:textStyle="italic"
android:textColor="?colorM3Primary"
android:textAppearance="@style/m3_label_large"
android:background="@drawable/bg_timeline_gap"/>
<FrameLayout
android:id="@+id/bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:background="?android:selectableItemBackground">
<ProgressBar
android:id="@+id/progress_bottom"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:visibility="gone"/>
<TextView
android:id="@+id/text_bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingHorizontal="16dp"
android:paddingTop="20dp"
android:paddingBottom="24dp"
android:drawablePadding="16dp"
android:drawableEnd="@drawable/ic_fluent_chevron_double_up_20_filled"
android:textAppearance="@style/m3_title_medium"
android:textColor="?android:textColorSecondary"
android:text="@string/sk_load_missing_posts_above"/>
</FrameLayout>
</LinearLayout>

View File

@@ -173,6 +173,17 @@
android:textColor="?colorM3OnSurfaceVariant"
tools:text="\@Gargron@mastodon.social"/>
<ImageView
android:id="@+id/bot_icon"
android:layout_width="16sp"
android:layout_height="16sp"
android:layout_marginStart="4sp"
android:layout_gravity="center_vertical"
android:visibility="gone"
android:importantForAccessibility="no"
android:contentDescription="@string/sk_icon_bot"
android:src="@drawable/ic_fluent_bot_20_filled" />
<TextView
android:id="@+id/separator"
android:layout_width="wrap_content"

View File

@@ -8,83 +8,33 @@
android:paddingLeft="16dp"
android:clipToPadding="false">
<View
android:id="@+id/checkbox"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="-4dp"
android:layout_marginTop="-8dp"
android:layout_marginEnd="12dp"
android:duplicateParentState="true"/>
<FrameLayout
android:id="@+id/checkbox_wrap"
android:layout_width="wrap_content"
android:layout_height="46sp"
android:duplicateParentState="true">
<ImageView
android:id="@+id/more"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_marginTop="-2dp"
android:layout_marginEnd="-2dp"
android:background="?android:selectableItemBackgroundBorderless"
android:scaleType="center"
android:tint="?colorM3OnSurfaceVariant"
android:contentDescription="@string/more_options"
android:src="@drawable/ic_fluent_more_vertical_20_filled" />
<View
android:id="@+id/checkbox"
android:layout_gravity="center_vertical"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="-4dp"
android:layout_marginTop="0dp"
android:layout_marginEnd="12dp"
android:duplicateParentState="true"/>
<ImageView
android:id="@+id/avatar"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentTop="true"
android:layout_toEndOf="@id/checkbox"
android:layout_marginTop="2dp"
android:layout_marginEnd="8dp" />
</FrameLayout>
<org.joinmastodon.android.ui.views.HeaderSubtitleLinearLayout
android:id="@+id/name_wrap"
<FrameLayout
android:layout_width="match_parent"
android:layout_height="24dp"
android:layout_toEndOf="@id/avatar"
android:layout_toStartOf="@id/more"
android:layout_marginEnd="8dp">
android:layout_height="wrap_content"
android:layout_marginTop="-16dp"
android:layout_marginStart="-16dp"
android:layout_toEndOf="@id/checkbox_wrap">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="24dp"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="@style/m3_title_medium"
android:textColor="?colorM3OnSurface"
android:gravity="start|center_vertical"
tools:text="Eugen" />
<include layout="@layout/display_item_header" />
<TextView
android:id="@+id/extra_text"
android:layout_width="wrap_content"
android:layout_height="24dp"
android:layout_marginStart="8dp"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="@style/m3_title_medium"
android:fontFamily="sans-serif"
android:textAlignment="viewStart"
android:textColor="?colorM3OnSurface"
tools:text="boosted your cat picture" />
</org.joinmastodon.android.ui.views.HeaderSubtitleLinearLayout>
<TextView
android:id="@+id/time_and_username"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_below="@id/name_wrap"
android:layout_toEndOf="@id/avatar"
android:singleLine="true"
android:ellipsize="end"
android:textAppearance="@style/m3_title_small"
android:gravity="center_vertical"
android:textColor="?colorM3OnSurfaceVariant"
tools:text="9h ago · \@Gargron@mastodon.social"/>
</FrameLayout>
</org.joinmastodon.android.ui.views.CheckableRelativeLayout>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
@@ -8,7 +8,7 @@
android:paddingTop="16dp"
android:paddingRight="16dp">
<LinearLayout
<RelativeLayout
android:id="@+id/spoiler_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -19,11 +19,26 @@
android:paddingRight="12dp"
android:paddingBottom="8dp">
<ImageView
android:id="@+id/media_icon"
android:layout_width="28dp"
android:layout_height="28dp"
android:layout_marginHorizontal="8dp"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:scaleType="center"
android:contentDescription="@string/sk_post_contains_media"
android:src="@drawable/ic_fluent_image_24_regular"
android:tint="?colorM3OnSecondaryContainer" />
<TextView
android:id="@+id/spoiler_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_toStartOf="@id/media_icon"
android:textAppearance="@style/m3_body_large"
android:textColor="?colorM3OnSecondaryContainer"
tools:text="Spoilery stuff"/>
@@ -32,21 +47,14 @@
android:id="@+id/spoiler_action"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_below="@id/spoiler_title"
android:layout_toStartOf="@id/media_icon"
android:textAppearance="@style/m3_label_large"
android:singleLine="true"
android:gravity="center_vertical"
android:textColor="?colorM3Primary"
tools:text="Re-hide"/>
</LinearLayout>
</RelativeLayout>
<ImageView
android:id="@+id/media_icon"
android:layout_width="36dp"
android:layout_height="36dp"
android:background="?android:actionBarItemBackground"
android:scaleType="center"
android:src="@drawable/ic_fluent_image_24_regular"
android:tint="?android:textColorSecondary" />
</LinearLayout>
</FrameLayout>

View File

@@ -45,6 +45,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<org.joinmastodon.android.ui.tabs.TabLayout
android:id="@+id/tabbar"
android:layout_width="match_parent"
@@ -56,6 +57,8 @@
app:tabIndicatorFullWidth="false"
app:tabMinWidth="90dp"
app:tabMode="scrollable"
android:clipToPadding="false"
android:paddingHorizontal="4dp"
android:background="?colorM3Surface"/>
<View

View File

@@ -167,17 +167,51 @@
</org.joinmastodon.android.ui.views.AutoOrientationLinearLayout>
<TextView
android:id="@+id/username"
<LinearLayout
android:id="@+id/username_wrap"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:paddingTop="2dp"
android:paddingBottom="8dp"
android:layout_marginRight="16dp"
android:textAppearance="@style/m3_title_small"
android:textColor="?colorM3OnSurfaceVariant"
tools:text="\@Gargron" />
android:layout_marginStart="16dp"
android:layout_marginEnd="12dp"
android:layout_marginTop="2dp"
android:layout_marginBottom="8dp">
<TextView
android:id="@+id/username"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="4dp"
android:maxLines="1"
android:ellipsize="end"
android:textAppearance="@style/m3_title_small"
android:textColor="?colorM3OnSurfaceVariant"
tools:text="\@Gargron" />
<ImageView
android:id="@+id/lock_icon"
android:layout_width="18sp"
android:layout_height="18sp"
android:layout_marginEnd="4dp"
android:layout_gravity="center_vertical"
android:visibility="gone"
android:importantForAccessibility="no"
android:contentDescription="@string/manually_approves_followers"
android:src="@drawable/ic_fluent_lock_closed_20_filled" />
<ImageView
android:id="@+id/bot_icon"
android:layout_width="18sp"
android:layout_height="18sp"
android:layout_marginEnd="4dp"
android:layout_gravity="center_vertical"
android:visibility="gone"
android:importantForAccessibility="no"
android:contentDescription="@string/sk_icon_bot"
android:src="@drawable/ic_fluent_bot_20_filled" />
</LinearLayout>
<org.joinmastodon.android.ui.views.LinkedTextView
android:id="@+id/bio"
@@ -350,11 +384,12 @@
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="@drawable/bg_onboarding_panel"
android:clipToPadding="false"
android:paddingHorizontal="4dp"
app:tabGravity="start"
app:tabIndicator="@drawable/tab_indicator_m3"
app:tabIndicatorAnimationMode="elastic"
app:tabIndicatorColor="?colorM3Primary"
android:paddingHorizontal="4dp"
app:tabIndicatorFullWidth="false"
app:tabMinWidth="0dp"
app:tabMode="scrollable" />

View File

@@ -91,50 +91,6 @@
</RelativeLayout>
<LinearLayout
android:id="@+id/forward_report"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:paddingHorizontal="8dp"
android:paddingVertical="8dp"
android:gravity="center_vertical"
android:layoutDirection="locale"
android:background="?android:selectableItemBackground">
<ImageView
android:id="@+id/icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="32dp"
android:importantForAccessibility="no"
android:tint="?android:textColorPrimary"
android:src="@drawable/ic_fluent_arrow_forward_24_regular"/>
<TextView
android:id="@+id/forward_report_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingVertical="8dp"
android:textSize="16sp"
android:text="@string/sk_forward_report_to"
android:textColor="?android:textColorPrimary" />
<Switch
android:id="@+id/forward_report_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:duplicateParentState="true"
android:layout_marginStart="16dp"
android:layout_marginEnd="12dp"
android:focusable="false"
android:clickable="false"/>
</LinearLayout>
</LinearLayout>
</ScrollView>

View File

@@ -5,7 +5,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingEnd="16dp"
android:clipToPadding="false"
android:background="?colorM3Background"
tools:ignore="RtlSymmetry">
@@ -26,6 +25,7 @@
android:layout_height="48dp"
android:layout_alignParentEnd="true"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:scaleType="center"
android:tint="?colorM3OnSurface"
android:background="?android:actionBarItemBackground"

View File

@@ -13,8 +13,6 @@
android:id="@+id/tabbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="12dp"
android:paddingBottom="16dp"
android:paddingHorizontal="8dp">
<LinearLayout
@@ -23,6 +21,8 @@
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:paddingTop="12dp"
android:paddingBottom="16dp"
android:orientation="vertical">
<FrameLayout
@@ -61,6 +61,8 @@
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:paddingTop="12dp"
android:paddingBottom="16dp"
android:orientation="vertical">
<FrameLayout
@@ -99,6 +101,8 @@
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:paddingTop="12dp"
android:paddingBottom="16dp"
android:orientation="vertical">
<RelativeLayout
@@ -155,6 +159,8 @@
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:paddingTop="12dp"
android:paddingBottom="16dp"
android:orientation="vertical">
<FrameLayout

View File

@@ -182,7 +182,7 @@
<string name="report_reason_spam">إنه غير مرغوب فيه</string>
<string name="report_reason_spam_subtitle">روابط خبيثة أو تفاعل كاذب أو ردود متكررة</string>
<string name="report_reason_violation">ينتهك قواعد الخادم</string>
<string name="report_reason_violation_subtitle">تعلم أنه ينتهك قواعد محددة</string>
<string name="report_reason_violation_subtitle">أنت مُدرك لانتهاكه قواعد مُحَدَّدَة</string>
<string name="report_reason_other">إنَّهُ شَيءٌ آخَر</string>
<string name="report_reason_other_subtitle">لا تندرج هذه المشكلة ضمن فئات أخرى</string>
<string name="report_choose_rule">ما هي القواعد المنتهكة؟</string>
@@ -362,7 +362,7 @@
<item quantity="zero">منذ %d ثانية</item>
<item quantity="one">منذ ثانية</item>
<item quantity="two">منذ ثانيتان</item>
<item quantity="few">%d ثواني</item>
<item quantity="few">%d ثوانٍ</item>
<item quantity="many">منذ %d ثانية</item>
<item quantity="other">%d ثواني مضت</item>
</plurals>
@@ -463,7 +463,7 @@
<string name="welcome_to_mastodon">أهلًا بك على ماستدون</string>
<string name="welcome_paragraph1">ماستدون شبكة اجتماعية لامركزية، بمعنى أنه ليس هناك شركة واحدة تتحكم فيها. وهي تتألف من العديد من الخوادم التي تدار بشكل مستقل، وجميعها متصلة معا.</string>
<string name="what_are_servers">ما هي الخوادم؟</string>
<string name="welcome_paragraph2"><![CDATA[تتم استضافة كل حساب ماستدون على خادم - ولكل منها قيمه وقواعده ومسؤوليه الخاصين. بغض النظر عن الشخص الذي تختاره ، يمكنك متابعة الأشخاص والتفاعل معهم على أي خادم.]]></string>
<string name="welcome_paragraph2">تتم استضافة كل حساب ماستدون على خادم - ولكل خادم قيمه وقواعده ومسؤوليه الخاصين. مهما اخترت أي خادم، يمكنك متابعة الأشخاص والتفاعل معهم على أي خادم آخر.</string>
<string name="opening_link">رابط الافتتاح…</string>
<string name="link_not_supported">هذا الرابط غير مدعوم في التطبيق</string>
<string name="log_out_all_accounts">تسجيل الخروج من جميع الحسابات</string>
@@ -694,8 +694,8 @@
<string name="posts_matching_string">منشورات تحتوي على “%s”</string>
<string name="accounts_matching_string">أشخاص لديهم \"%s\"</string>
<!-- Shown in the post header. Please keep it short -->
<string name="time_seconds_ago_short">مُنذُ %dث</string>
<string name="time_minutes_ago_short">مُنذُ %dش</string>
<string name="time_hours_ago_short">مُنذُ %dس</string>
<string name="time_days_ago_short">مُنذُ %dي</string>
<string name="time_seconds_ago_short">مُنذُ %dثا</string>
<string name="time_minutes_ago_short">مُنذُ %dد</string>
<string name="time_hours_ago_short">مُنذُ %dسا</string>
<string name="time_days_ago_short">مُنذُ %d أيام</string>
</resources>

View File

@@ -31,4 +31,222 @@
<string name="sk_user_post_notifications_off">عطل إشعارات النشر لـ %s</string>
<string name="sk_check_for_update">تحقق من وجود تحديثات</string>
<string name="sk_no_update_available">لا يتوفر تحديث</string>
<string name="sk_duration_hours_1">ساعة واحدة</string>
<string name="sk_duration_hours_6">6 ساعات</string>
<string name="sk_duration_days_1">يوم واحد</string>
<string name="sk_duration_days_3">3 أيام</string>
<string name="sk_duration_days_7">7 أيام</string>
<string name="sk_federated_timeline">الفديرالية</string>
<string name="sk_timeline_local">المحلي</string>
<string name="sk_tab_notifications">الإشعارات</string>
<string name="sk_mute_label">المدة</string>
<string name="sk_settings_show_boosts">إظهار المعاد نشرها</string>
<string name="sk_duration_minutes_5">5 دقائق</string>
<string name="sk_timeline_home">الرئيسي</string>
<string name="sk_duration_minutes_30">30 دقيقة</string>
<string name="sk_tab_home">الرئيسي</string>
<string name="sk_edit_timeline_tag_main">المنشورات التي تحتوي على الوسم …</string>
<string name="sk_post_edited">عُدِّل</string>
<string name="sk_notification_type_update">المنشورات المُعدَّلة</string>
<string name="sk_settings_publish_button_text">نص زر النشر</string>
<string name="sk_delete_notification_confirm_action">حذف الإشعار</string>
<string name="sk_settings_translation_availability_note_available">إنَّ %s يدعم خدمة الترجمة!</string>
<string name="sk_reply_as">رُدّ بواسطة حساب آخَر</string>
<string name="sk_confirm_save_changes">أتريد حفظ التعديلات؟</string>
<string name="sk_list_replies_policy_none">لا أحد</string>
<string name="sk_unpinned_timeline">تم فك التثبيت مِن الرئيسي</string>
<string name="sk_settings_hide_interaction">إخفاء أزرار التفاعلات</string>
<string name="sk_list_exclusive_switch">جعلُ القائمة حصرية</string>
<string name="sk_favorite_as">أضفه إلى المفضلة بحساب آخَر</string>
<string name="sk_timeline_bubble">فقاعة</string>
<string name="sk_icon_bot">حساب آلي</string>
<string name="sk_icon_keyboard">لوحة المفاتيح الموسيقية</string>
<string name="sk_local_only">الخادم المحلي فقط</string>
<string name="sk_settings_disable_alt_text_reminder">تعطيل تذكيري لإضافة نص بديل</string>
<string name="sk_no_remote_info_hint">المعلومات البُعدية غير متوفرة</string>
<string name="sk_advanced_options_show">إظهار الميزات المتقدمة</string>
<string name="sk_content_type">نوع المحتوى</string>
<string name="sk_app_name">Megalodon</string>
<string name="sk_list">القائمة</string>
<string name="sk_edit_timelines">تعديل الخيوط الزمنية</string>
<string name="sk_icon_feed">موجز اخباري</string>
<string name="sk_gif_badge">GIF</string>
<string name="sk_inline_local_only">المحلي فقط</string>
<string name="sk_settings_reply_visibility">مدى ظهور الردود</string>
<string name="sk_settings_show_interaction_counts">إظهار عدد التفاعلات</string>
<string name="sk_settings_app_version">Megalodon نسخة %1$s (%2$d)</string>
<string name="sk_mark_media_as_sensitive">تعيين الوسائط كحساسة</string>
<string name="sk_update_available">ميگالودون %s متوفّر للتنزيل.</string>
<string name="sk_welcome_text">القِرش يحييك! للبداية ، رجاءً قم بإدخال اسم نطاق خادمك الخاص هنا.</string>
<string name="sk_color_palette_material3">النظام</string>
<string name="sk_color_palette_pink">وردي</string>
<string name="sk_color_palette_purple">أرجواني</string>
<string name="sk_color_palette_green">أخضر</string>
<string name="sk_color_palette_blue">أزرق</string>
<string name="sk_color_palette_brown">قهوي</string>
<string name="sk_color_palette_red">أحمر</string>
<string name="sk_color_palette_yellow">أصفر</string>
<string name="sk_poll_allow_multiple">السماح بخيارات متعددة</string>
<string name="sk_translate_post">ترجمة</string>
<string name="sk_translate_show_original">إظهار الأصلي</string>
<string name="sk_translated_using">تُرجِم بواسطة %s</string>
<string name="sk_post_language">اللغة: %s</string>
<string name="sk_available_languages">اللغات المتوفرة</string>
<string name="sk_clear_recent_languages">مسح آخر اللغات المستخدَمة</string>
<string name="sk_welcome_title">مرحبًا!</string>
<string name="sk_example_domain">example.social</string>
<string name="sk_settings_profile">إعداد الملف التعريفي</string>
<string name="sk_settings_posting">تفضيلات النشر</string>
<string name="sk_settings_filters">ضبط عوامل التصفية</string>
<string name="sk_settings_auth">إعدادات الأمان</string>
<string name="sk_settings_rules">القواعد</string>
<string name="sk_settings_about">عن التطبيق</string>
<string name="sk_settings_donate">التبرع</string>
<string name="sk_delete_notification">حذف الإشعار</string>
<string name="sk_clear_all_notifications">حذف كافة الإشعارات</string>
<string name="sk_clear_all_notifications_confirm_action">حذف الكل</string>
<string name="sk_settings_publish_button_text_title">تخصيص نص زر النشر</string>
<string name="sk_settings_translate_only_opened">ترجمة المنشورات المفتوحة فقط</string>
<string name="sk_loading_fediverse_resource_title">البحث عنه في الفديفرس</string>
<string name="sk_loading_resource_on_instance_title">البحث في %s</string>
<string name="sk_quote_post">أنشُر حول الموضوع</string>
<string name="sk_hashtags_you_follow">الوسوم التي تتبعها</string>
<string name="sk_copy_link_to_post">انسخ رابط المنشور</string>
<string name="sk_open_with_account">افتحه بواسطة حساب آخَر</string>
<string name="sk_unsent_posts">المنشورات غير المُرسَلَة</string>
<string name="sk_draft">المسودة</string>
<string name="sk_schedule">برمجة</string>
<string name="sk_confirm_delete_draft_title">احذف المسودّة</string>
<string name="sk_draft_saved">تم حفظ المسودّة</string>
<string name="sk_confirm_save_draft">أتريد حفظ المسودّة؟</string>
<string name="sk_settings_translation_availability_note_unavailable">لا يبدو أنّ %s يدعم الترجمة.</string>
<string name="sk_bookmark_as">أضفه إلى الفواصل المرجعية بحساب آخَر</string>
<string name="sk_forward_report_to">إعادة التوجيه إلى %s</string>
<string name="sk_compose_draft">سيُحفَظ المنشور كمسودّة.</string>
<string name="sk_mark_as_draft">تعيينه كمسودّة</string>
<string name="sk_schedule_post">برمَجة المنشور</string>
<string name="sk_edit_list_title">تعديل القائمة</string>
<string name="sk_your_lists">قوائمك</string>
<string name="sk_announcements">الإعلانات</string>
<string name="sk_mark_as_read">تعيينه كمقروء</string>
<string name="sk_settings_about_instance">عن مثيل الخادم</string>
<string name="sk_create">إنشاء</string>
<string name="sk_create_list_title">إنشاء قائمة</string>
<string name="sk_list_name_hint">اسم القائمة</string>
<string name="sk_list_replies_policy_list">أعضاء القائمة</string>
<string name="sk_list_replies_policy_followed">المستخدِمون المتابَعون</string>
<string name="sk_delete_list">احذف القائمة</string>
<string name="sk_timeline_federated">الفديرالية</string>
<string name="sk_settings_single_notification">إظهار إشعار واحد فقط</string>
<string name="sk_settings_unifiedpush">استخدم UnifiedPush</string>
<string name="sk_settings_unifiedpush_choose">اختر مُزوِّدًا</string>
<string name="sk_delete_list_confirm">أمُتأكد مِن أنك تُريد حذف قائمة \"%s\"؟</string>
<string name="sk_recent_searches_placeholder">أكتب شيئا ما لمواصلة البحث</string>
<string name="sk_changelog">سِجِلّ التغييرات</string>
<string name="sk_alt_text_missing_title">ينقصه نص بديل</string>
<string name="sk_publish_anyway">أنشُره على أي حال</string>
<string name="sk_timelines">الخيوط الزمنية</string>
<string name="sk_timeline_posts">المنشورات</string>
<string name="sk_timelines_add">إضافة</string>
<string name="sk_remove_follower">تنحية من بين متابعيك</string>
<string name="sk_pinned_timeline">مثبَّت على الرئيسي</string>
<string name="sk_edit_timeline_tag_any">… أو أي من هذه</string>
<string name="sk_edit_timeline_tag_hint">أدخِل الوسم …</string>
<string name="sk_edit_timeline_tags_hint">أدخِل الوسوم …</string>
<string name="sk_timeline">الخيط الزمني</string>
<string name="sk_hashtag">الوسم</string>
<string name="sk_pin_timeline">تثبيت الخيط الزمني</string>
<string name="sk_unpin_timeline">فكّ تثبيت الخيط الزمني</string>
<string name="sk_remove">حذف</string>
<string name="sk_timeline_icon">أيقونة</string>
<string name="sk_icon_heart">قلب</string>
<string name="sk_icon_star">نجمة</string>
<string name="sk_icon_city">مدينة</string>
<string name="sk_icon_cat">قط</string>
<string name="sk_icon_dog">كلب</string>
<string name="sk_icon_rabbit">أرنب</string>
<string name="sk_icon_turtle">سلحفاة</string>
<string name="sk_icon_bed">سرير</string>
<string name="sk_icon_recycle_bin">سلة مهملات</string>
<string name="sk_icon_doctor">طبيب</string>
<string name="sk_add_timeline">إضافة خيط زمني</string>
<string name="sk_icon_balloon">كرة</string>
<string name="sk_icon_image">صورة</string>
<string name="sk_icon_language">اللغة</string>
<string name="sk_icon_location">المكان</string>
<string name="sk_icon_microphone">المايكروفون</string>
<string name="sk_icon_microscope">مجهر</string>
<string name="sk_icon_coffee">قهوة</string>
<string name="sk_icon_laugh">ضحك</string>
<string name="sk_icon_news">أخبار</string>
<string name="sk_icon_stethoscope">سمّاعة</string>
<string name="sk_icon_weather">الطقس</string>
<string name="sk_icon_games">ألعاب</string>
<string name="sk_icon_diamond">ألماس</string>
<string name="sk_icon_umbrella">مطرية</string>
<string name="sk_hashtag_timeline_local_only_switch">أتريد إظهار المنشورات المحلية فقط؟</string>
<string name="sk_alt_button">ALT</string>
<string name="sk_attach_file">أرفِق ملفًا</string>
<string name="sk_searching">البحث…</string>
<string name="sk_no_alt_text">لا نص بديل متوفر</string>
<string name="sk_separator">·</string>
<string name="sk_instance_features">ميزات مثيل الخادم</string>
<string name="sk_reported">تم الإبلاغ عنه</string>
<string name="sk_settings_server_version">إصدار الخادم: %s</string>
<string name="sk_expand">توسيع</string>
<string name="sk_follow_as">متابعته بواسطة حساب آخَر</string>
<string name="sk_settings_default_content_type">النوع المبدئي للمحتوى</string>
<string name="sk_open_in_app">افتحه بواسطة التطبيق</string>
<string name="sk_exclusive_list">قائمة حصرية</string>
<string name="sk_advanced_options_hide">إخفاء الميزات المتقدمة</string>
<string name="sk_spoiler_show">إظهار المحتوى</string>
<string name="sk_pronouns_label">الضمائر</string>
<string name="sk_no_results">لا نتائج</string>
<string name="sk_save_draft">أتريد حفظ المسودّة؟</string>
<string name="sk_content_type_unspecified">غير محدد</string>
<string name="sk_external_share_title">شاركه عبر حساب</string>
<string name="sk_settings_auto_reveal_author">ردود مِن نفس الناشر</string>
<string name="sk_settings_instance">مثيل الخادم</string>
<string name="sk_settings_true_black">الوضع الأسود الداكن</string>
<string name="sk_settings_display_pronouns_in_timelines">إظهار الضمائر على الخيوط الزمنية</string>
<string name="sk_settings_display_pronouns_in_threads">إظهار الضمائر على خيوط المحادثات</string>
<string name="sk_tab_search">البحث</string>
<string name="sk_tab_profile">الملف التعريفي</string>
<string name="sk_settings_confirm_before_reblog">التأكيد قبل إعادة النشر</string>
<string name="sk_language_name">%1$s (%2$s)</string>
<string name="sk_undo_reblog">إلغاء إعادة النشر</string>
<string name="sk_reblog_with_visibility">أعد النشر بمدى الظهور التالي</string>
<string name="sk_reblog_as">أعد النشر بحساب آخَر</string>
<string name="sk_reblogged_as">تمت إعادة النشر كـ %s</string>
<string name="sk_show_thread">إظهار خيط المحادثة</string>
<string name="sk_new_reports">إبلاغات جديدة</string>
<string name="sk_collapse">اطوي</string>
<string name="sk_settings_always_reveal_content_warnings">الكشف عن تحذيرات المحتوى دائما</string>
<string name="sk_notification_type_status">المنشورات</string>
<string name="sk_update_ready">تم تنزيل ميگالودون %s وهو جاهز للتنصيب.</string>
<string name="sk_edit_timeline">تعديل الخيط الزمني</string>
<string name="sk_icon_pin">دبوس</string>
<string name="sk_icon_leaves">أوراق شجر</string>
<string name="sk_icon_sport">رياضة</string>
<string name="sk_icon_music">موسيقى</string>
<string name="sk_icon_people">ناس</string>
<string name="sk_icon_health">صحة</string>
<string name="sk_icon_important">مهم</string>
<string name="sk_icon_chat">دردشة</string>
<string name="sk_icon_human">إنسان</string>
<string name="sk_icon_globe">كرة أرضية</string>
<string name="sk_icon_light_bulb">مصباح</string>
<string name="sk_icon_train">قطار</string>
<string name="sk_icon_shield">درع</string>
<string name="sk_icon_book">كتاب</string>
<string name="sk_icon_bicycle">دراجة هوائية</string>
<string name="sk_icon_map">خريطة</string>
<string name="sk_icon_fire">نار</string>
<string name="sk_icon_bug">حشرة</string>
<string name="sk_icon_pizza">بيتزا</string>
<string name="sk_icon_gavel">مطرقة</string>
<string name="sk_icon_headphones">سمّاعات</string>
<string name="sk_notify_poll_results">نتيجة استطلاع الرأي</string>
<string name="sk_filtered">تمت تصفيته: %s</string>
<string name="sk_search_fediverse">البحث في الفديفرس</string>
</resources>

View File

@@ -404,7 +404,6 @@
<string name="welcome_to_mastodon">Вітаем у Mastodon</string>
<string name="welcome_paragraph1">Mastodon - гэта дэцэнтралізаваная сацыяльная сетка, што азначае, што ні адна кампанія не кантралюе яе. Яна складаецца з мноства незалежна працуючых сервераў, злучаных разам.</string>
<string name="what_are_servers">Што такое серверы?</string>
<string name="welcome_paragraph2"><![CDATA[Кожны акаўнт Mastodon размяшчаецца на серверы - кожны са сваімі каштоўнасцямі, правіламі і адміністратарамі. Незалежна ад таго, які сервер вы вылучыце, вы можаце сачыць і ўзаемадзейнічаць з людзьмі на любым серверы.]]></string>
<string name="retry">Паўтарыць</string>
<!-- %s is formatted file size ("467 KB image") -->
<string name="attachment_type_video">Відэа</string>

View File

@@ -2,6 +2,7 @@
<resources>
<string name="log_in">লগ ইন করুন</string>
<string name="next">এরপর</string>
<string name="loading_instance">সার্ভারের তথ্য পুনরূদ্ধার করা হচ্ছে…</string>
<string name="error">কোনো ত্রুটি ঘটেছে</string>
<string name="ok">ঠিক আছে</string>
<string name="preparing_auth">প্রমাণীকরণের জন্য প্রস্তুত হচ্ছে...</string>
@@ -65,6 +66,10 @@
<item quantity="one">%d দিন বাকি</item>
<item quantity="other">%d দিন বাকি</item>
</plurals>
<plurals name="x_votes">
<item quantity="one">%,d ভোট</item>
<item quantity="other">%,d ভোট</item>
</plurals>
<string name="poll_closed">বন্ধ</string>
<string name="confirm_mute_title">অ্যাকাউন্টটি মিউট করুন</string>
<string name="do_mute">মিউট করুন</string>
@@ -123,6 +128,8 @@
<string name="category_tech">তথ্য-প্রযুক্তি</string>
<string name="confirm_email_title">আপনার ইনবক্স দেখুন</string>
<!-- %s is the email address -->
<string name="open_email_app">ই-মেইল অ্যাপ খুলুন</string>
<string name="resent_email">নিশ্চিতকরনের ই-মেইল পাঠানো হয়েছে</string>
<string name="visibility_followers_only">ফলোয়ারদের জন্য</string>
<string name="notification_type_follow">নতুন ফলোয়াররা</string>
<string name="err_not_logged_in">Mastodon-এ প্রথমে লগ ইন করুন</string>
@@ -181,7 +188,6 @@
<string name="welcome_to_mastodon">Mastodon - এ আপনাকে স্বাগত জানাই</string>
<string name="welcome_paragraph1">Mastodon হল একটি বিকেন্দ্রীভূত সামাজিক নেটওয়ার্ক, যার মানে কোনো একক কোম্পানি এটিকে নিয়ন্ত্রণ করে না। এটি অনেকগুলি স্বাধীনভাবে চালিত সার্ভারের সমন্বয়ে গঠিত, যেখানে সব সার্ভারগুলি একসাথে সংযুক্ত৷</string>
<string name="what_are_servers">সার্ভার কি?</string>
<string name="welcome_paragraph2"><![CDATA[প্রতিটি Mastodon অ্যাকাউন্টকে একটি সার্ভারে হোস্ট করা হয় — প্রত্যেকটির নিজস্ব মান, নিয়ম এবং প্রশাসক (অ্যাডমিন) রয়েছে। আপনি যে কোনো সার্ভারই বেছে নিন না কেন তা বিবেচ্য নয়, আপনি যেকোনো সার্ভারের লোকেদের সাথে যোগাযোগ করতে এবং তাদের ফলো করতে পারেন।]]></string>
<!-- %s is formatted file size ("467 KB image") -->
<!-- %s is the server domain -->
<!-- Shown on the "stamp" on the screen that appears after you report a post/user. Please keep the translation short, preferably a single word -->

View File

@@ -34,7 +34,7 @@
<string name="sk_list_timelines">Llistes</string>
<string name="sk_follow_requests">Sol·licituds de seguiment</string>
<string name="sk_reject_follow_request">Rebutja la sol·licitud</string>
<string name="sk_lists_with_user">Edita les llistes amb %s</string>
<string name="sk_lists_with_user">Llistes amb %s</string>
<string name="sk_settings_always_reveal_content_warnings">Mostra sempre els avisos de contingut</string>
<string name="sk_settings_contribute">Contribueix a Megalodon</string>
<string name="sk_settings_show_federated_timeline">Mostra la línia de temps federada</string>
@@ -246,11 +246,134 @@
<string name="sk_searching">Cercant…</string>
<string name="sk_save_draft">Voleu desar l\'esborrany\?</string>
<string name="sk_settings_show_no_alt_indicator">Indicador dels textos alternatius inexistents</string>
<string name="sk_settings_prefix_reply_cw_with_re">Afegeix «re:» a les respostes als avisos de contingut</string>
<string name="sk_settings_prefix_reply_cw_with_re">Afig «re:» en respondre als avisos de contingut</string>
<string name="sk_filtered">Filtrat: %s</string>
<string name="sk_expand">Amplia</string>
<string name="sk_collapse">Tanca</string>
<string name="sk_settings_collapse_long_posts">Acurta les publicacions llargues</string>
<string name="sk_signed_up">registrat</string>
<string name="sk_spectator_mode">Mode d\'espectador</string>
<string name="sk_button_react">Reacciona amb un emoji</string>
<string name="sk_enter_emoji_hint">Escriviu per a reaccionar amb un emoji</string>
<string name="sk_duration_minutes_5">5 minuts</string>
<string name="sk_duration_minutes_30">30 minuts</string>
<string name="sk_duration_hours_1">1 hora</string>
<string name="sk_duration_hours_6">6 hores</string>
<string name="sk_duration_indefinite">Indefinida</string>
<string name="sk_mute_label">Durada</string>
<string name="sk_enter_emoji_toast">Heu d\'escriure un emoji</string>
<string name="sk_again_for_system_keyboard">Toqueu una altra vegada per a obrir el teclat del sistema</string>
<string name="sk_duration_days_1">1 dia</string>
<string name="sk_duration_days_3">3 dies</string>
<string name="sk_duration_days_7">7 dies</string>
<string name="sk_notification_mention">%s t\'ha mencionat</string>
<string name="sk_settings_auto_reveal_equal_spoilers">Mostra els mateixos avisos de contingut en respostes</string>
<string name="sk_settings_auto_reveal_nobody">Mai</string>
<string name="sk_settings_auto_reveal_author">Respostes del mateix autor</string>
<string name="sk_open_in_app_failed">No s\'ha pogut obrir</string>
<string name="sk_no_remote_info_hint">La informació remota no està disponible</string>
<string name="sk_error_loading_profile">No s\'ha pogut carregar el perfil via %s</string>
<string name="sk_settings_prefix_replies_to_others">Només en resposta a altres</string>
<string name="sk_settings_prefix_replies_always">Responent a qualsevol</string>
<string name="sk_settings_prefix_replies_never">Mai</string>
<string name="sk_content_type_unspecified">Sense especificar</string>
<string name="sk_content_type_plain">Text pla</string>
<string name="sk_content_type_html">HTML</string>
<string name="sk_content_type">Tipus de contingut</string>
<string name="sk_content_type_mfm">MFM</string>
<string name="sk_settings_default_content_type">Contingut per defecte</string>
<string name="sk_timeline_bubble">Bombolla</string>
<string name="sk_in_reply">Resposta</string>
<string name="sk_followed_as">Seguit a %s</string>
<string name="sk_follow_as">Segueix des d\'un altre compte</string>
<string name="sk_icon_feed">Línia del temps</string>
<string name="sk_edit_timeline_tag_main">Publicacions amb l\'etiqueta…</string>
<string name="sk_edit_timeline_tags_explanation">Tingueu en compte que el servidor gestiona aquestes operacions. És possible que no s\'admeta combinar-les.</string>
<string name="sk_new_reports">Denúncies noves</string>
<string name="sk_unfinished_attachments_message">Alguns fitxers adjunts no han acabat de pujar-se\'n.</string>
<string name="sk_settings_hide_fab">Amaga automàticament el botó de redacció</string>
<string name="sk_settings_confirm_before_reblog">Confirma abans d\'impulsar</string>
<string name="sk_settings_content_types">Activa la formatació de text</string>
<string name="sk_settings_content_types_explanation">Permet establir un format de contingut com Markdown en crear una publicació. Tingueu en compte que no totes les instàncies són compatibles.</string>
<string name="sk_settings_default_content_type_explanation">Això permet preseleccionar un tipus de contingut en crear publicacions noves, substituint el valor establert a «Preferències de publicació».</string>
<string name="sk_settings_emoji_reactions">Activa les reaccions d\'emojis</string>
<string name="sk_settings_emoji_reactions_explanation">Mostra les reaccions d\'emojis a les publicacions i us permet interactuar amb elles. Algunes versions modificades de Mastodon són compatibles, però Mastodon no.</string>
<string name="sk_settings_emoji_reactions_in_lists">Mostra les reaccions d\'emojis a les línies de temps</string>
<plurals name="sk_users_reacted_with">
<item quantity="one">Un usuari ha reaccionat amb %2$s</item>
<item quantity="other">%1$,d usuaris han reaccionat amb %2$s</item>
</plurals>
<string name="sk_settings_emoji_reactions_in_lists_explanation">Si les reaccions d\'emojis s\'han de mostrar a les línies de temps. Si l\'opció està desactivada, les reaccions d\'emojis només es mostraran quan es visualitze un fil.</string>
<string name="sk_settings_unifiedpush">Utilitza UnifiedPush</string>
<string name="sk_list_exclusive_switch">Fes la llista exclusiva</string>
<string name="sk_settings_unifiedpush_choose">Tria un distribuïdor</string>
<string name="sk_list_exclusive_switch_explanation">Els membres d\'una llista exclusiva no apareixeran a la línia de temps de l\'inici (si la vostra instància és compatible).</string>
<string name="sk_settings_unifiedpush_no_distributor_body">Heu d\'instal·lar un distribuïdor perquè funcionen les notificacions UnifiedPush. Per a més informació, visita https://unifiedpush.org/</string>
<string name="sk_settings_allow_remote_loading">Carrega la informació de les instàncies remotes</string>
<string name="sk_settings_forward_report_default">Activa per defecte «Reenvia la denúncia»</string>
<string name="sk_gif_badge">GIF</string>
<string name="sk_quoting_user">Citant %s</string>
<string name="sk_settings_reply_visibility">Visibilitat de la resposta</string>
<string name="sk_settings_reply_visibility_all">Totes les respostes</string>
<string name="sk_settings_reply_visibility_following">Respostes als meus seguits</string>
<string name="sk_settings_reply_visibility_self">Respostes a mi</string>
<string name="sk_notification_action_replied">S\'ha enviat la resposta a %s</string>
<string name="sk_settings_continues_playback">Superposició d\'àudio</string>
<string name="sk_settings_continues_playback_summary">Permet que els fitxers multimèdia que ja s\'estan reproduint continuen reproduint-se en la superposició el reproductor nou</string>
<string name="sk_settings_unifiedpush_no_distributor">No s\'ha trobat cap distribuïdor</string>
<string name="sk_icon_bed">Llit</string>
<string name="sk_icon_recycle_bin">Paperera de reciclatge</string>
<string name="sk_icon_verified">Verificat</string>
<string name="sk_icon_doctor">Metge</string>
<string name="sk_icon_diamond">Diamant</string>
<string name="sk_icon_umbrella">Paraigua</string>
<string name="sk_add_timeline">Afig línia de temps</string>
<string name="sk_edit_timeline_tag_any">…o alguna d\'aquestes</string>
<string name="sk_edit_timeline_tag_all">…i cada una d\'aquestes</string>
<string name="sk_edit_timeline_tag_none">…però cap d\'aquestes</string>
<string name="sk_edit_timeline_tag_hint">Introduïu l\'etiqueta…</string>
<string name="sk_edit_timeline_tags_hint">Introduïu etiquetes…</string>
<string name="sk_icon_beaker">Vas científic</string>
<string name="sk_hashtag_timeline_local_only_switch">Mostra només publicacions locals\?</string>
<string name="sk_add_timeline_tag_error_empty">L\'etiqueta no pot ser buida</string>
<string name="sk_reported">denunciat</string>
<string name="sk_unfinished_attachments">Voleu arreglar els adjunts\?</string>
<string name="sk_reply_line_above_avatar">Text «En resposta a» damunt de l\'avatar</string>
<string name="sk_compact_reblog_reply_line">Text compacte d\'impuls/resposta</string>
<string name="sk_content_type_markdown">Markdown</string>
<string name="sk_content_type_bbcode">BBCode</string>
<string name="sk_instance_info_unavailable">La informació de la instància no està disponible temporalment</string>
<string name="sk_open_in_app">Obri en l\'aplicació</string>
<string name="sk_external_share_title">Comparteix amb un compte</string>
<string name="sk_external_share_or_open_title">Comparteix o obri amb un compte</string>
<string name="sk_settings_show_labels_in_navigation_bar">Mostra els noms de les pestanyes a la barra de navegació</string>
<string name="sk_tab_profile">Perfil</string>
<string name="sk_tab_notifications">Notificacions</string>
<string name="sk_tab_search">Cerca</string>
<string name="sk_tab_home">Inici</string>
<string name="sk_settings_display_pronouns_in_user_listings">Mostra els pronoms als llistats d\'usuaris</string>
<string name="sk_settings_display_pronouns_in_threads">Mostra els pronoms als fils</string>
<string name="sk_settings_display_pronouns_in_timelines">Mostra els pronoms a les línies de temps</string>
<string name="sk_settings_instance">Instància</string>
<string name="sk_switch_timeline">Canvia de línia de temps</string>
<string name="sk_pronouns_label">Pronoms</string>
<string name="sk_spoiler_show">Mostra el contingut</string>
<string name="sk_exclusive_list">Llista exclusiva</string>
<string name="sk_settings_allow_remote_loading_explanation">Prova d\'obtenir llistes més precises de seguidors, m\'agrada i impulsos carregant la informació de la instància d\'origen.</string>
<string name="sk_settings_auto_reveal_anyone">Respostes de tothom</string>
<string name="sk_advanced_options_show">Mostra les opcions avançades</string>
<string name="sk_advanced_options_hide">Amaga les opcions avançades</string>
<string name="sk_disable_pill_shaped_active_indicator">Desactiva l\'indicador en forma de pastilla de pestanya activa</string>
<string name="sk_settings_true_black">Mode de negre pur</string>
<string name="sk_reacted_with">%1$s ha reaccionat amb %2$s</string>
<string name="sk_reacted">%s ha reaccionat</string>
<string name="sk_settings_hide_interaction">Amaga els botons d\'interacció</string>
<string name="sk_show_thread">Mostra el fil</string>
<string name="sk_bubble_timeline_info_banner">Aquestes són les publicacions més recents de la xarxa seleccionades per l\'administració de la instància.</string>
<string name="sk_icon_gauge">Indicador</string>
<string name="sk_search_fediverse">Cerca al fedivers</string>
<plurals name="sk_posts_count_label">
<item quantity="one">publicació</item>
<item quantity="other">publicacions</item>
</plurals>
</resources>

View File

@@ -425,7 +425,6 @@
<string name="welcome_to_mastodon">Vítejte na Mastodonu</string>
<string name="welcome_paragraph1">Mastodon je decentralizovaná sociální síť, což znamená, že ji neovládá žádná jednotlivá společnost. Skládá se z mnoha nezávisle spravovaných serverů, všechny jsou propojeny dohromady.</string>
<string name="what_are_servers">Co jsou to servery?</string>
<string name="welcome_paragraph2"><![CDATA[Každý účet Mastodon je hostován na serveru - každý s vlastními hodnotami, pravidly a správci. Bez ohledu na to, který si vyberete, můžete sledovat a komunikovat s lidmi na jakémkoliv serveru.]]></string>
<string name="opening_link">Odkaz se otevírá…</string>
<string name="link_not_supported">Tento odkaz není v aplikaci podporovaný</string>
<string name="log_out_all_accounts">Odhlásit se ze všech účtů</string>

View File

@@ -387,7 +387,6 @@
<string name="welcome_to_mastodon">Velkommen til Mastodon</string>
<string name="welcome_paragraph1">Mastodon er et decentraliseret socialt netværk, hvilket betyder at ingen enkelt virksomhed styrer det. Det består af mange uafhængige servere, alle forbundet sammen.</string>
<string name="what_are_servers">Hvad er servere?</string>
<string name="welcome_paragraph2"><![CDATA[Alle Mastodon-konti har plads på en server. Hver server har sine egne værdier, regler og administratorer. Ligegyldigt hvilken server du vælger, kan du følge og interagere med folk på alle andre servere.]]></string>
<string name="opening_link">Åbner link…</string>
<string name="link_not_supported">Linket er ikke understøttet i appen</string>
<string name="log_out_all_accounts">Log ud af alle konti</string>

View File

@@ -348,4 +348,45 @@
<string name="sk_tab_search">Suche</string>
<string name="sk_tab_notifications">Benachrichtigungen</string>
<string name="sk_tab_profile">Profil</string>
<string name="sk_enter_emoji_toast">Bitte geben Sie ein Emoji ein</string>
<string name="sk_settings_emoji_reactions">Emoji-Reaktionen einschalten</string>
<string name="sk_settings_emoji_reactions_explanation">Zeigt Emoji-Reaktionen zu Beiträgen an und lässt dich eigene hinzufügen. Einige Fediverse-Server unterstützen das, Mastodon jedoch nicht.</string>
<string name="sk_button_react">Mit Emoji reagieren</string>
<string name="sk_mute_label">Dauer</string>
<string name="sk_settings_show_emoji_reactions">Emoji-Reaktionen in Timelines anzeigen</string>
<string name="sk_settings_show_emoji_reactions_only_opened">Nur wenn der Beitrag geöffnet ist</string>
<string name="sk_duration_days_3">3 Tage</string>
<string name="sk_search_suicide_message">Wenn du auf ein Zeichen wartest, keinen Suizid zu begehen das hier ist es. Bitte ziehe in Erwägung, eine Suizid-Hotline zu kontaktieren, wenn du Hilfe brauchst.</string>
<string name="sk_settings_show_emoji_reactions_hide_empty">Leere Emoji-Reaktionen verbergen</string>
<string name="sk_settings_show_emoji_reactions_always">Hinzufügen-Button immer anzeigen</string>
<string name="sk_enter_emoji_hint">Emoji zum Reagieren eintippen</string>
<string name="sk_duration_indefinite">Unbestimmt</string>
<string name="sk_duration_minutes_5">5 Minuten</string>
<string name="sk_duration_minutes_30">30 Minuten</string>
<string name="sk_duration_hours_1">1 Stunde</string>
<string name="sk_duration_hours_6">6 Stunden</string>
<string name="sk_duration_days_1">1 Tag</string>
<string name="sk_duration_days_7">7 Tage</string>
<string name="sk_notification_mention">Du wurdest von %s erwähnt</string>
<string name="sk_suicide_search_terms">Suizid</string>
<string name="sk_search_suicide_title">Falls es dir schlecht geht…</string>
<string name="sk_search_suicide_hotlines">Hotline finden</string>
<string name="sk_do_not_show_again">Nicht mehr anzeigen</string>
<string name="sk_post_contains_media">Beitrag enthält Medien</string>
<plurals name="sk_users_reacted_with">
<item quantity="one">Ein User hat mit %2$s reagiert</item>
<item quantity="other">%1$,d User haben mit %2$s reagiert</item>
</plurals>
<plurals name="sk_posts_count_label">
<item quantity="one">Beitrag</item>
<item quantity="other">Beiträge</item>
</plurals>
<string name="sk_settings_show_labels_in_navigation_bar">Tab-Bezeichnungen in der Navigationsleiste anzeigen</string>
<string name="sk_time_seconds">%d Sekunden</string>
<string name="sk_time_minutes">%d Minuten</string>
<string name="sk_time_hours">%d Stunden</string>
<string name="sk_time_days">%d Tage</string>
<string name="sk_suicide_helplines_url">https://findahelpline.com</string>
<string name="sk_load_missing_posts_below">Ältere Beiträge laden</string>
<string name="sk_load_missing_posts_above">Neuere Beiträge laden</string>
</resources>

View File

@@ -387,7 +387,6 @@
<string name="welcome_to_mastodon">Καλώς ήρθες στο Mastodon</string>
<string name="welcome_paragraph1">Το Mastodon είναι ένα αποκεντρωμένο κοινωνικό δίκτυο που σημαίνει ότι καμία εταιρεία δεν το ελέγχει. Αποτελείται από πολλούς ανεξάρτητους διακομιστές, όλοι συνδεδεμένοι μαζί.</string>
<string name="what_are_servers">Τι είναι οι διακομιστές;</string>
<string name="welcome_paragraph2"><![CDATA[Κάθε λογαριασμός Mastodon φιλοξενείται σε ένα διακομιστή - ο καθένας με τις δικές του αξίες, κανόνες και διαχειριστές. Ανεξάρτητα από το ποιον μπορεί να επιλέξεις, μπορείς να ακολουθήσεις και να αλληλεπιδράσεις με άτομα από οποιονδήποτε διακομιστή.]]></string>
<string name="opening_link">Άνοιγμα συνδέσμου…</string>
<string name="link_not_supported">Αυτός ο σύνδεσμος δεν υποστηρίζεται στην εφαρμογή</string>
<string name="log_out_all_accounts">Αποσύνδεση από όλους τους λογαριασμούς</string>

View File

@@ -387,7 +387,6 @@
<string name="welcome_to_mastodon">Bienvenido/da a Mastodon</string>
<string name="welcome_paragraph1">Mastodon es una red social descentralizada, lo que significa que no la controla una sola compañía. Está formada por muchos servidores independientes, todos juntos conectados.</string>
<string name="what_are_servers">¿Qué son los servidores?</string>
<string name="welcome_paragraph2"><![CDATA[Cada cuenta de Mastodon está alojada en un servidor — cada uno con sus propios valores, reglas y administradores. No importa cual elijas, puede seguir e interactuar con personas en cualquier servidor.]]></string>
<string name="opening_link">Abriendo enlace…</string>
<string name="link_not_supported">Este enlace no es compatible con la aplicación</string>
<string name="log_out_all_accounts">Cerrar sesión en todas las cuentas</string>

View File

@@ -331,10 +331,10 @@
<string name="sk_gif_badge">GIF</string>
<string name="sk_spoiler_show">Mostrar el contenido</string>
<string name="sk_pronouns_label">Pronombres</string>
<string name="sk_switch_timeline">Cambiar la línea de tiempo</string>
<string name="sk_switch_timeline">Cambiar la cronología</string>
<string name="sk_settings_instance">Instancia</string>
<string name="sk_disable_pill_shaped_active_indicator">Desactivar el indicador de pestaña activa en forma de pastilla</string>
<string name="sk_settings_true_black">Modo negro intenso</string>
<string name="sk_settings_true_black">Usar tema negro</string>
<string name="sk_search_fediverse">Buscar en el Fediverso</string>
<string name="sk_settings_unifiedpush_choose">Selecciona un distribuidor</string>
<string name="sk_settings_unifiedpush_no_distributor">No se ha encontrado ningún distribuidor</string>
@@ -373,4 +373,21 @@
<string name="sk_settings_emoji_reactions_in_lists_explanation">Las reacciones con los emoticonos deben mostrarse en las líneas de tiempo. Si esta opción está desactivada, las reacciones con los emoticonos solo se mostrarán al ver un hilo.</string>
<string name="sk_button_react">Reacciona con un emoticono</string>
<string name="sk_again_for_system_keyboard">Pulsa de nuevo para el Teclado del sistema</string>
<plurals name="sk_posts_count_label">
<item quantity="one">tema</item>
<item quantity="many">temas</item>
<item quantity="other">temas</item>
</plurals>
<string name="sk_settings_show_emoji_reactions_hide_empty">Ocultar emoji vacíos</string>
<string name="sk_settings_show_emoji_reactions_only_opened">Sólo cuando se abre un tema</string>
<string name="sk_settings_show_emoji_reactions_always">Mostrar siempre el botón de añadir</string>
<string name="sk_search_suicide_hotlines">Encontrar un teléfono de ayuda</string>
<string name="sk_do_not_show_again">No mostrar de nuevo</string>
<string name="sk_post_contains_media">El tema contiene medios</string>
<string name="sk_load_missing_posts_oldest_first">El más antiguo primero (hacia arriba)</string>
<string name="sk_settings_show_emoji_reactions">Mostrar los emoji en las líneas de tiempo</string>
<string name="sk_search_suicide_title">En caso de que estés en apuros…</string>
<string name="sk_suicide_helplines_url">https://findahelpline.com</string>
<string name="sk_settings_load_missing_posts">Cargar los mensajes que faltan</string>
<string name="sk_load_missing_posts_newest_first">Lo más nuevo primero (hacia abajo)</string>
</resources>

View File

@@ -11,6 +11,10 @@
<string name="user_boosted">%s(e)k bultzatu du</string>
<string name="in_reply_to">%s-(r)i erantzunez</string>
<string name="notifications">Jakinarazpenak</string>
<string name="user_followed_you">%s(e)k jarraitu zaitu</string>
<string name="user_sent_follow_request">%s-(e)k jarraitzeko eskaera bidali dizu</string>
<string name="user_favorited">%s(e)k zure bidalketa gogoko du</string>
<string name="notification_boosted">%s(e)k zure bidalketa bultzatu du</string>
<string name="share_toot_title">Partekatu</string>
<string name="settings">Ezarpenak</string>
<string name="publish">Argitaratu</string>
@@ -32,6 +36,7 @@
<string name="button_follow">Jarraitu</string>
<string name="button_following">Jarraitzen</string>
<string name="edit_profile">Editatu profila</string>
<string name="share_user">Partekatu profila</string>
<string name="mute_user">Mututu %s</string>
<string name="unmute_user">Desmututu %s</string>
<string name="block_user">Blokeatu %s</string>

View File

@@ -387,7 +387,6 @@
<string name="welcome_to_mastodon">به ماستودون خوش آمدید</string>
<string name="welcome_paragraph1">ماستودون یک شبکه اجتماعی غیر متمرکز است،به این معنی که هیچ شرکتی آن را کنترل نمی کند. این از بسیاری از کارسازهای مستقل تشکیل شده است که همه به هم متصل هستند.</string>
<string name="what_are_servers">کارساز شما کجاست؟</string>
<string name="welcome_paragraph2"><![CDATA[هر حساب ماستودون بر روی یک سرور میزبانی می شود — هر کدام با مقادیر، قوانین و مدیران خاص خود. مهم نیست کدام یک را انتخاب می کنید، می توانید افراد را در هر کارسازی دنبال کنید و با آنها تعامل داشته باشید.]]></string>
<string name="opening_link">باز کردن پیوند…</string>
<string name="link_not_supported">این پیوند در کاره پشتیبانی نمی شود</string>
<string name="log_out_all_accounts">از همه حساب‌ها خارج شوید</string>

View File

@@ -1,3 +1,378 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="sk_pinned_posts">Kiinnitetty</string>
<string name="sk_app_name">Megalodon</string>
<string name="sk_filtered">Suodatettu: %s</string>
<string name="sk_settings_emoji_reactions">Ota emojireaktiot käyttöön</string>
<string name="sk_settings_emoji_reactions_in_lists">Näytä emojireaktiot aikajanoissa</string>
<string name="sk_settings_emoji_reactions_in_lists_explanation">Näytetäänkö emojireaktiot aikajanoissa. Jos tämä on pois käytöstä, emojireaktiot näkyvät vain lankaa katsottaessa.</string>
<string name="sk_button_react">Reagoi emojilla</string>
<string name="sk_again_for_system_keyboard">Järjestelmän näppäimistö seuraavalla painalluksella</string>
<string name="sk_enter_emoji_toast">Tähän tarvitaan emoji</string>
<string name="sk_enter_emoji_hint">Kirjoita vastataksesi emojilla</string>
<string name="sk_mute_label">Kesto</string>
<string name="sk_duration_indefinite">Loputon</string>
<string name="sk_duration_minutes_5">5 minuuttia</string>
<string name="sk_duration_minutes_30">30 minuuttia</string>
<string name="sk_duration_hours_1">1 tunti</string>
<string name="sk_duration_hours_6">6 tuntia</string>
<string name="sk_duration_days_1">1 päivä</string>
<string name="sk_duration_days_3">3 päivää</string>
<string name="sk_duration_days_7">7 päivää</string>
<string name="sk_notification_mention">%s mainitsi sinut</string>
<string name="sk_timeline_local">Paikallinen</string>
<string name="sk_timeline_home">Koti</string>
<string name="sk_delete_and_redraft">Poista ja kirjoita uudestaan</string>
<string name="sk_pin_post">Kiinnitä profiiliin</string>
<string name="sk_unpin_post">Irrota profiilista</string>
<string name="sk_confirm_delete_and_redraft_title">Poista ja kirjoita viesti uudelleen</string>
<string name="sk_confirm_pin_post_title">Kiinnitä viesti profiiliin</string>
<string name="sk_confirm_pin_post">Haluatko kiinnittää tämän viestin profiiliisi\?</string>
<string name="sk_confirm_delete_and_redraft">Oletko varma että haluat poistaa ja kirjoittaa viestin uudelleen\?</string>
<string name="sk_confirm_unpin_post_title">Poista viestin kiinnitys profiilista</string>
<string name="sk_unpinning">Viestiä irrotetaan…</string>
<string name="sk_pinning">Viestiä kiinnitetään…</string>
<string name="sk_image_description">Kuvaselitys</string>
<string name="sk_visibility_unlisted">Listaamaton</string>
<string name="sk_settings_show_replies">Näytä vastaukset</string>
<string name="sk_list_timelines">Listat</string>
<string name="sk_clear_recent_languages">Tyhjennä viimeksi käytetyt kielet</string>
<string name="sk_welcome_title">Tervetuloa!</string>
<string name="sk_settings_contribute">Tue Megalodonia</string>
<string name="sk_settings_auto_reveal_equal_spoilers">Avaa automaattisesti samat sisältövaroitukset vastauksissa</string>
<string name="sk_settings_auto_reveal_nobody">Ei koskaan</string>
<string name="sk_settings_auto_reveal_author">Saman tilin vastauksissa</string>
<string name="sk_settings_auto_reveal_anyone">Kaikkien vastauksissa</string>
<string name="sk_settings_translate_only_opened">Käännä vain avatut viestit</string>
<string name="sk_translate_show_original">Näytä alkuperäinen</string>
<string name="sk_available_languages">Käytettävissä olevat kielet</string>
<string name="sk_translated_using">Kännetty käyttäen %s</string>
<string name="sk_post_language">Kieli: %s</string>
<string name="sk_settings_profile">Luo profiili</string>
<string name="sk_settings_posting">Julkaisuasetukset</string>
<string name="sk_color_palette_material3">Järjestelmä</string>
<string name="sk_color_palette_pink">Pinkki</string>
<string name="sk_settings_color_palette">Väripaletti</string>
<string name="sk_delete_notification">Poista ilmoitus</string>
<string name="sk_settings_translation_availability_note_available">%s tukee käännöksiä!</string>
<string name="sk_open_in_app_failed">Sovelluksessa avaaminen ei onnistunut</string>
<string name="sk_external_share_title">Jaa tilinä</string>
<string name="sk_clear_all_notifications">Poista kaikki ilmoitukset</string>
<string name="sk_clear_all_notifications_confirm_action">Poista kaikki</string>
<string name="sk_clear_all_notifications_confirm">Oletko varma, että haluat poistaa kaikki ilmoitukset\?</string>
<string name="sk_loading_fediverse_resource_title">Etsitään Fediversestä</string>
<string name="sk_undo_reblog">Peru tehostus</string>
<string name="sk_reblog_with_visibility">Tehostuksen näkyvyysasetus</string>
<string name="sk_copy_link_to_post">Kopioi linkki viestiin</string>
<string name="sk_open_with_account">Avaa toisella tilillä</string>
<string name="sk_resource_not_found">Kohdetta ei löytynyt</string>
<string name="sk_settings_allow_remote_loading">Hae tietoa etäinstansseista</string>
<string name="sk_forward_report_to">Lähetä edelleen kohteeseen %s</string>
<string name="sk_unsent_posts">Julkaisemattomat viestit</string>
<string name="sk_settings_prefix_replies_always">Vastauksissa kaikille</string>
<string name="sk_settings_prefix_replies_never">Ei koskaan</string>
<string name="sk_confirm_save_draft">Tallenna luonnos\?</string>
<string name="sk_confirm_save_changes">Tallenna muutokset\?</string>
<string name="sk_mark_as_draft">Merkitse luonnokseksi</string>
<string name="sk_schedule_post">Ajasta julkaisu</string>
<string name="sk_icon_bed">Vuode</string>
<string name="sk_icon_verified">Todennettu</string>
<string name="sk_icon_doctor">Lääkäri</string>
<string name="sk_icon_diamond">Timantti</string>
<string name="sk_icon_umbrella">Sateenverjo</string>
<string name="sk_add_timeline">Lisää aikajana</string>
<string name="sk_edit_timeline_tag_main">Viestit joissa on aihetunniste…</string>
<string name="sk_edit_timeline_tag_any">...tai jokin näistä</string>
<string name="sk_icon_beaker">Kannu</string>
<string name="sk_content_type_unspecified">Ei määritelty</string>
<string name="sk_content_type_plain">Pelkkä teksti</string>
<string name="sk_content_type_html">HTML</string>
<string name="sk_content_type">Sisällön tyyppi</string>
<string name="sk_content_type_markdown">Markdown</string>
<string name="sk_settings_reduce_motion">Rajoita animaatioiden liikettä</string>
<string name="sk_settings_forward_report_default">Oletusarvo valinnalle \"Lähetä raportti edelleen\"</string>
<string name="sk_timeline_bubble">Bubble</string>
<string name="sk_mark_as_read">Merkitse luetuksi</string>
<string name="sk_announcements">Palvelinilmoitukset</string>
<string name="sk_settings_about_instance">Tietoja instanssista</string>
<string name="sk_settings_single_notification">Näytä vain yksi ilmoitus</string>
<string name="sk_create">Luo</string>
<string name="sk_in_reply">Vastauksena</string>
<string name="sk_delete_list_confirm">Oletko varma että haluat poistaa listan \"%s\"\?</string>
<string name="sk_remove_follower">Poista seuraajista</string>
<string name="sk_icon_cat">Kissa</string>
<string name="sk_icon_city">Kaupunki</string>
<string name="sk_icon_dog">Koira</string>
<string name="sk_icon_pin">Nasta</string>
<string name="sk_searching">Etsitään…</string>
<string name="sk_settings_see_new_posts_button">”Katso uudet viestit” -painike</string>
<string name="sk_icon_feed">Syöte</string>
<string name="sk_post_edited">muokattu</string>
<string name="sk_notification_type_update">Muokatut viestit</string>
<string name="sk_attach_file">Liitä tiedosto</string>
<string name="sk_settings_hide_interaction">Piilota reaktiopainikkeet</string>
<string name="sk_followed_as">Seurattu tilinä %s</string>
<string name="sk_settings_hide_fab">Piilota Julkaise-painike automaattisesti</string>
<string name="sk_follow_as">Seuraa toisena tilinä</string>
<string name="sk_notification_type_posts">Viesti-ilmoitukset</string>
<string name="sk_settings_tabs_disable_swipe">Estä välilehdestä toiseen pyyhkäiseminen</string>
<string name="sk_settings_enable_delete_notifications">Salli ilmoitusten poistaminen</string>
<string name="sk_gif_badge">GIF</string>
<string name="sk_no_alt_text">Selitys puuttuu</string>
<string name="sk_inline_direct">vain maininnat</string>
<string name="sk_settings_glitch_instance">Glitch local-only mode</string>
<string name="sk_settings_glitch_mode_explanation">Ota tämä käyttöön, jos koti-instanssisi käyttää Glitchiä. Hometown tai Akkoma eivät tarvitse tätä.</string>
<string name="sk_unfinished_attachments_message">Joitakin liitteitä ei ole vielä ladattu valmiiksi.</string>
<string name="sk_settings_content_types">Ota viestin muotoilu käyttöön</string>
<string name="sk_settings_default_content_type">Sisältötyypin oletusarvo</string>
<string name="sk_settings_default_content_type_explanation">Tämä mahdollistaa uusien viestien sisältötyypin ennaltavalinnan, ohittaa julkaisuasetuksissa asetetun arvon.</string>
<string name="sk_instance_info_unavailable">Tietoa instanssista ei juuri nyt ole saatavilla</string>
<string name="sk_open_in_app">Avaa sovelluksessa</string>
<string name="sk_external_share_or_open_title">Jaa tai avaa tilinä</string>
<string name="sk_settings_reply_visibility">Vastauksen näkyvyys</string>
<string name="sk_settings_reply_visibility_all">Kaikki vastaukset</string>
<string name="sk_show_thread">Näytä lanka</string>
<string name="sk_reply_line_above_avatar">\"Vastauksena\" -rivi käyttäjäkuvakkeen yläpuolella</string>
<string name="sk_compact_reblog_reply_line">Tiivistetty tehostus/vastaus-rivi</string>
<plurals name="sk_users_reacted_with">
<item quantity="one">Yksi käyttäjä reagoi näin: %2$s</item>
<item quantity="other">%1$,d käyttäjää reagoi näin: %2$s</item>
</plurals>
<plurals name="sk_posts_count_label">
<item quantity="one">viesti</item>
<item quantity="other">viestiä</item>
</plurals>
<string name="sk_settings_continues_playback">Ääniraita</string>
<string name="sk_settings_reply_visibility_following">Vastaukset seuraamilleni</string>
<string name="sk_settings_reply_visibility_self">Vastaukset minulle</string>
<string name="sk_settings_show_interaction_counts">Näytä laskimet</string>
<string name="sk_settings_app_version">Megalodon v%1$s (%2$d)</string>
<string name="sk_mark_media_as_sensitive">Merkitse media arkaluontoiseksi</string>
<string name="sk_federated_timeline_info_banner">Nämä ovat uusimmat viestit yleiseltä aikajanalta.</string>
<string name="sk_lists_with_user">Listoja joissa on %s</string>
<string name="sk_notification_type_status">Viestit</string>
<string name="sk_color_palette_blue">Sininen</string>
<string name="sk_color_palette_brown">Ruskea</string>
<string name="sk_color_palette_red">Punainen</string>
<string name="sk_color_palette_yellow">Keltainen</string>
<string name="sk_poll_allow_multiple">Salli useita valintoja</string>
<string name="sk_translate_post">Käännä</string>
<string name="sk_welcome_text">Hai tervehtii sinua! Päästäksesi alkuun kirjoita koti-instanssisi osoite alla olevaan ruutuun.</string>
<string name="sk_example_domain">example.social</string>
<string name="sk_settings_filters">Suodatinasetukset</string>
<string name="sk_settings_auth">Turvallisuusasetukset</string>
<string name="sk_settings_rules">Säännöt</string>
<string name="sk_settings_about">Tietoa sovelluksesta</string>
<string name="sk_settings_donate">Lahjoita</string>
<string name="sk_delete_notification_confirm">Oletko varma, että haluat poistaa ilmoituksen\?</string>
<string name="sk_settings_publish_button_text">Julkaisupainikkeen teksti</string>
<string name="sk_quote_post">Kirjoita viesti aiheena tämä</string>
<string name="sk_bookmark_as">Tee kirjamerkki toiselle tilille</string>
<string name="sk_already_bookmarked">Kirjamerkki jo tallennettu</string>
<string name="sk_favorite_as">Tykkä toisena tilinä</string>
<string name="sk_favorited_as">Tykätty tilinä %s</string>
<string name="sk_already_favorited">Tykkäys jo tallennettu</string>
<string name="sk_reply_as">Vastaa toisena tilinä</string>
<string name="sk_draft">Luonnos</string>
<string name="sk_schedule">Ajasta</string>
<string name="sk_confirm_delete_draft_title">Poista luonnos</string>
<string name="sk_confirm_delete_draft">Oletko varma, että haluat poistaa tämän viestiluonnoksen\?</string>
<string name="sk_confirm_delete_scheduled_post_title">Poista ajastettu julkaisu</string>
<string name="sk_user_post_notifications_off">Ilmoitukset käyttäjän %s viesteistä poistettu käyttöstä</string>
<string name="sk_settings_show_boosts">Näytä tehostukset</string>
<string name="sk_settings_load_new_posts">Lataa uudet viestit automaattisesti</string>
<string name="sk_draft_or_schedule">Luonnos tai ajastettu viesti</string>
<string name="sk_compose_scheduled">Ajastettu ajalle</string>
<string name="sk_draft_saved">Luonnos tallennettu</string>
<string name="sk_post_scheduled">Julkaisu ajastettu</string>
<string name="sk_scheduled_too_soon_title">Valittu aika on liian pian</string>
<string name="sk_schedule_or_draft">Ajasta tai kirjoita luonnos</string>
<string name="sk_compose_no_schedule">Älä ajasta</string>
<string name="sk_compose_no_draft">Älä kirjoita luonnosta</string>
<string name="sk_settings_unifiedpush">Ota käyttöön UnifiedPush</string>
<string name="sk_settings_unifiedpush_choose">Valitse jakelija</string>
<string name="sk_settings_unifiedpush_no_distributor">Jakelijaa ei löydetty</string>
<string name="sk_create_list_title">Luo lista</string>
<string name="sk_list_name_hint">Listan nimi</string>
<string name="sk_list_replies_policy">Näytä vastaukset kohteeseen</string>
<string name="sk_list_replies_policy_list">listan jäsenet</string>
<string name="sk_list_replies_policy_followed">seuratut tilit</string>
<string name="sk_list_replies_policy_none">ei mitään</string>
<string name="sk_delete_list">Poista lista</string>
<string name="sk_edit_list_title">Muokkaa listaa</string>
<string name="sk_your_lists">Listasi</string>
<string name="sk_timeline_federated">Yleinen</string>
<string name="sk_remove_follower_confirm">Poista %s seuraajista estämällä ja poistamalla esto välittömästi\?</string>
<string name="sk_do_remove_follower">Poista</string>
<string name="sk_remove_follower_success">Seuraaja poistettu onnistuneesti</string>
<string name="sk_changelog">Muutoslista</string>
<string name="sk_alt_text_missing_title">Kuvaselitys puuttuu</string>
<string name="sk_publish_anyway">Julkaise silti</string>
<string name="sk_settings_disable_alt_text_reminder">Poista muistutus mediakuvauksesta</string>
<string name="sk_notify_posts_info_banner">Jos otat käyttöön ilmoitukset joidenkin henkilöiden viesteistä, heidän uudet viestinsä näkyvät täällä.</string>
<string name="sk_timelines">Aikajanat</string>
<string name="sk_timeline_posts">Viestit</string>
<string name="sk_timelines_add">Lisää</string>
<string name="sk_timeline">Aikajana</string>
<string name="sk_list">Lista</string>
<string name="sk_hashtag">Aihetunniste</string>
<string name="sk_pin_timeline">Kiinnitä aikajana</string>
<string name="sk_unpin_timeline">Irrota aikajana</string>
<string name="sk_unpinned_timeline">Irrotettu kotinäytöstä</string>
<string name="sk_remove">Poista</string>
<string name="sk_timeline_icon">Kuvake</string>
<string name="sk_icon_heart">Sydän</string>
<string name="sk_icon_star">Tähti</string>
<string name="sk_icon_megaphone">Megafoni</string>
<string name="sk_icon_keyboard">Koskettimisto</string>
<string name="sk_icon_laugh">Nauru</string>
<string name="sk_icon_pi">Pii</string>
<string name="sk_icon_color_palette">Väripaletti</string>
<string name="sk_icon_academic_cap">Akateeminen päähine</string>
<string name="sk_icon_tag">Etiketti</string>
<string name="sk_icon_stethoscope">Stetoskooppi</string>
<string name="sk_icon_weather">Sää</string>
<string name="sk_icon_games">Pelit</string>
<string name="sk_icon_code">Koodi</string>
<string name="sk_icon_light_bulb">Hehkulamppu</string>
<string name="sk_icon_train">Juna</string>
<string name="sk_icon_leaves">Lehtiä</string>
<string name="sk_icon_sport">Urheilu</string>
<string name="sk_icon_aperture">Aukko</string>
<string name="sk_icon_music">Musiikki</string>
<string name="sk_icon_people">Ihmisiä</string>
<string name="sk_icon_health">Terveys</string>
<string name="sk_icon_important">Tärkeää</string>
<string name="sk_icon_chat">Juttelu</string>
<string name="sk_icon_shield">Kilpi</string>
<string name="sk_icon_book">Kirja</string>
<string name="sk_icon_bicycle">Polkupyörä</string>
<string name="sk_icon_map">Kartta</string>
<string name="sk_icon_math_formula">Laskukaava</string>
<string name="sk_icon_backpack">Reppu</string>
<string name="sk_icon_briefcase">Salkku</string>
<string name="sk_icon_fire">Tuli</string>
<string name="sk_icon_bug">Ötökkä</string>
<string name="sk_icon_gavel">Puheenjohtajan nuija</string>
<string name="sk_icon_gauge">Mittari</string>
<string name="sk_icon_headphones">Kuulokkeet</string>
<string name="sk_icon_human">Ihminen</string>
<string name="sk_icon_globe">Maapallo</string>
<string name="sk_edit_timeline">Muokkaa aikajanaa</string>
<string name="sk_edit_timeline_tag_all">... ja kaikki nämä</string>
<string name="sk_edit_timeline_tag_none">...muttei mitään näistä</string>
<string name="sk_edit_timeline_tag_hint">Kirjoita aihetunniste…</string>
<string name="sk_edit_timeline_tags_hint">Kirjoita aihetunnisteet…</string>
<string name="sk_hashtag_timeline_local_only_switch">Näytetäänkö vain paikalliset viestit\?</string>
<string name="sk_add_timeline_tag_error_empty">Aihetunniste ei voi olla tyhjä</string>
<string name="sk_alt_button">ALT</string>
<string name="sk_no_results">Ei tuloksia</string>
<string name="sk_save_draft">Tallenna luonnos\?</string>
<string name="sk_settings_show_alt_indicator">Ilmoitus kuvaselityksistä</string>
<string name="sk_settings_show_no_alt_indicator">Ilmoitus puuttuvista kuvaselityksistä</string>
<string name="sk_updater_enable_pre_releases">Salli pre-release-versiot</string>
<string name="sk_inline_local_only">vain paikallinen</string>
<string name="sk_separator">·</string>
<string name="sk_local_only">Vain paikallinen instanssi</string>
<string name="sk_settings_local_only_explanation">Jotta tämä toimii, koti-instanssisi on tuettava viestien julkaisemista ainoastaan paikallisesti. Useimmat Mastodonin muunnellut versiot tukevat, mutta Mastodon ei.</string>
<string name="sk_signed_up">rekisteröity</string>
<string name="sk_reported">raportoitu</string>
<string name="sk_sign_ups">Käyttäjät rekisteröityvät</string>
<string name="sk_settings_prefix_reply_cw_with_re">Lisää sisältövaroitukseen \"re:\" kun vastaat</string>
<string name="sk_unfinished_attachments">Korjataanko liitteet\?</string>
<string name="sk_content_type_bbcode">BBCode</string>
<string name="sk_content_type_mfm">MFM</string>
<string name="sk_settings_prefix_replies_to_others">Vain vastauksissa muille</string>
<string name="sk_exclusive_list">Erillinen lista</string>
<string name="sk_list_exclusive_switch">Tee listasta erillinen</string>
<string name="sk_list_exclusive_switch_explanation">Erillisen listan jäsenet eivät näy kotiaikajanallasi jos instanssisi tukee tätä.</string>
<string name="sk_advanced_options_show">Näytä lisäasetukset</string>
<string name="sk_advanced_options_hide">Piilota lisäasetukset</string>
<string name="sk_spoiler_show">Näytä sisältö</string>
<string name="sk_pronouns_label">Pronominit</string>
<string name="sk_switch_timeline">Vaihda aikajanaa</string>
<string name="sk_settings_instance">Instanssi</string>
<string name="sk_disable_pill_shaped_active_indicator">Ota aktiivisen välilehden pillerinmuotoinen osoitin pois käytöstä</string>
<string name="sk_settings_true_black">Täysmusta tila</string>
<string name="sk_settings_display_pronouns_in_timelines">Näytä pronominit aikajanoissa</string>
<string name="sk_settings_display_pronouns_in_threads">Näytä pronominit langoissa</string>
<string name="sk_settings_display_pronouns_in_user_listings">Näytä pronominit käyttäjälistoissa</string>
<string name="sk_tab_home">Koti</string>
<string name="sk_tab_search">Etsi</string>
<string name="sk_tab_notifications">Ilmoitukset</string>
<string name="sk_settings_show_labels_in_navigation_bar">Näytä välilehtien nimet navigointipalkissa</string>
<string name="sk_tab_profile">Profiili</string>
<string name="sk_reblogged_as">Tehostettu tililtä %s</string>
<string name="sk_already_reblogged">Jo tehostettu</string>
<string name="sk_reacted">%s reagoi</string>
<string name="sk_new_reports">Uusia raportteja</string>
<string name="sk_settings_server_version">Palvelimen versio: %s</string>
<string name="sk_notify_poll_results">Kyselyn tulokset</string>
<string name="sk_expand">Avaa</string>
<string name="sk_collapse">Kätke</string>
<string name="sk_settings_collapse_long_posts">Kätke pitkien viestien loppuosa</string>
<string name="sk_reacted_with">%1$s reagoi %2$s</string>
<string name="sk_notification_action_replied">Vastaus lähetetty käyttäjälle %s</string>
<string name="sk_update_ready">Megalodon %s on ladattu ja valmis asennettavaksi.</string>
<string name="sk_check_for_update">Etsi päivityksiä</string>
<string name="sk_no_update_available">Ei päivityksiä saatavilla</string>
<string name="sk_follow_requests">Seuraamispyynnöt</string>
<string name="sk_update_available">Megalodon %s on valmis ladattavaksi.</string>
<string name="sk_accept_follow_request">Hyväksy seuraamispyyntö</string>
<string name="sk_settings_always_reveal_content_warnings">Avaa sisältövaroitukset aina</string>
<string name="sk_settings_show_federated_timeline">Näytä yleinen aikajana</string>
<string name="sk_color_palette_purple">Violetti</string>
<string name="sk_color_palette_green">Vihreä</string>
<string name="sk_icon_turtle">Kilpikonna</string>
<string name="sk_icon_rabbit">Jänis</string>
<string name="sk_icon_balloon">Ilmapallo</string>
<string name="sk_icon_image">Kuva</string>
<string name="sk_icon_bot">Botti</string>
<string name="sk_icon_language">Kieli</string>
<string name="sk_icon_location">Sijainti</string>
<string name="sk_icon_microphone">Mikrofoni</string>
<string name="sk_icon_microscope">Mikroskooppi</string>
<string name="sk_instance_features">Instanssin ominaisuudet</string>
<string name="sk_search_fediverse">Etsi Fediversumista</string>
<string name="sk_settings_confirm_before_reblog">Kysy vahvistus ennen tehostamista</string>
<string name="sk_language_name">%1$s (%2$s)</string>
<string name="sk_confirm_clear_recent_languages">Oletko varma, että haluat tyhjentää viimeksi käytettyjen kielten listan\?</string>
<string name="sk_user_post_notifications_on">Ilmoitukset käyttäjän %s viesteistä otettu käyttöön</string>
<string name="sk_federated_timeline">Yleinen</string>
<string name="sk_delete_notification_confirm_action">Poista ilmoitus</string>
<string name="sk_settings_content_types_explanation">Mahdollistaa viestien sisältötyypin valinnan, esimerkiksi Markdown. Kaikki instanssit eivät tue tätä.</string>
<string name="sk_bubble_timeline_info_banner">Nämä ovat uusimmat viestit ihmisiltä, joiden tilejä sinun instanssisi isännöi.</string>
<string name="sk_settings_publish_button_text_title">Muokkaa Julkaise-painikkeen tekstiä</string>
<string name="sk_no_remote_info_hint">etäinfoa ei saatavilla</string>
<string name="sk_reject_follow_request">Hylkää seuraamispyyntö</string>
<string name="sk_settings_translation_availability_note_unavailable">%s ei näytä tukevan käännöksiä.</string>
<string name="sk_error_loading_profile">Profiilin lataaminen %s:n kautta epäonnistui</string>
<string name="sk_settings_enable_marquee">Salli tekstin rullaus otsikkolistoissa</string>
<string name="sk_loading_resource_on_instance_title">Etsitään %ssta</string>
<string name="sk_settings_allow_remote_loading_explanation">Yritä hakea tarkempia tietoja seuraajista, tykkäyksistä ja tehostuksista lataamalla tiedot alkuperäiseltä instanssilta.</string>
<string name="sk_hashtags_you_follow">Aihetunnisteet joita seuraat</string>
<string name="sk_bookmarked_as">Kirjamerkki tehty tilille %s</string>
<string name="sk_reblog_as">Tehosta toisena tilinä</string>
<string name="sk_settings_uniform_icon_for_notifications">Sama kuvake kaikille ilmoituksille</string>
<string name="sk_confirm_delete_scheduled_post">Oletko varma, että haluat poistaa tämän ajastetun julkaisun\?</string>
<string name="sk_compose_draft">Julkaisu tallennetaan luonnoksena.</string>
<string name="sk_scheduled_too_soon">Julkaisu on ajastettava vähintään 10 minuuttia tulevaisuuteen.</string>
<string name="sk_confirm_unpin_post">Oletko varma että haluat irrottaa tämän viestin\?</string>
<string name="sk_settings_unifiedpush_no_distributor_body">On asennettava jakelijaohjelma jotta UnifiedPush-ilmoitukset toimivat. Lisätietoja: https://unifiedpush.org/</string>
<string name="sk_settings_emoji_reactions_explanation">Näyttää viestien emojireaktiot ja mahdollistaa vuorovaikutuksen niiden kanssa. Jotkin Mastodonin muokatut versiot tukevat tätä, mutta Mastodon ei.</string>
<string name="sk_recent_searches_placeholder">Hae kirjoittamalla tähän</string>
<string name="sk_alt_text_missing">Selitys puuttuu vähintään yhdestä liitteestä.</string>
<string name="sk_pinned_timeline">Kiinnitetty kotinäyttöön</string>
<string name="sk_icon_coffee">Kahvi</string>
<string name="sk_icon_news">Uutiset</string>
<string name="sk_icon_clapper_board">Klaffitaulu</string>
<string name="sk_icon_pizza">Pitsa</string>
<string name="sk_icon_recycle_bin">Roskakori</string>
<string name="sk_edit_timelines">Muokkaa aikananoja</string>
<string name="sk_edit_timeline_tags_explanation">Ota huomioon, että palvelin tekee nämä operaatiot. Niiden yhdistelyä ei välttämättä tueta.</string>
<string name="sk_notify_update">Tämä muokkaa tehostettua viestiä</string>
<string name="sk_save_draft_message">Haluatko tallentaa muutokset tähän luonnokseen vai julkaista sen nyt\?</string>
<string name="sk_settings_support_local_only">Palvelin tukee paikallista julkaisemista</string>
<string name="sk_settings_continues_playback_summary">Anna mediatoiston jatkua lisäten uusi raita</string>
<string name="sk_quoting_user">Lainaus %s</string>
</resources>

View File

@@ -387,7 +387,7 @@
<string name="welcome_to_mastodon">Bienvenue sur Mastodon</string>
<string name="welcome_paragraph1">Mastodon est un réseau social décentralisé, ce qui signifie quaucune entreprise ne le contrôle. Il est composé de plusieurs serveurs indépendants, tous connectés ensemble.</string>
<string name="what_are_servers">Que sont les serveurs ?</string>
<string name="welcome_paragraph2"><![CDATA[Chaque compte Mastodon est hébergé sur un serveur, chacun ayant ses valeurs, ses règles, et ses administratrices ou administrateurs. Quel que soit le serveur que vous choisissez, vous pouvez suivre et interagir avec des personnes sur n\'importe quel serveur.]]></string>
<string name="welcome_paragraph2">Chaque compte Mastodon est hébergé sur un serveur, chacun ayant ses valeurs, ses règles, et ses administratrices ou administrateurs. Quel que soit le serveur que vous choisissez, vous pouvez suivre et interagir avec des personnes sur n\'importe quel autre serveur.</string>
<string name="opening_link">Ouverture du lien…</string>
<string name="link_not_supported">Ce lien nest pas pris en charge dans lapplication</string>
<string name="log_out_all_accounts">Se déconnecter de tous les comptes</string>

View File

@@ -29,7 +29,7 @@
<string name="sk_settings_always_reveal_content_warnings">Toujours afficher les avertissements de contenu</string>
<string name="sk_settings_enable_marquee">Désactiver le défilement du texte dans les barres de titre</string>
<string name="sk_settings_contribute">Contribuez à Megalodon</string>
<string name="sk_settings_show_federated_timeline">Afficher la timeline fédérée</string>
<string name="sk_settings_show_federated_timeline">Afficher le fil fédéré</string>
<string name="sk_app_name">Megalodon</string>
<string name="sk_delete_and_redraft">Supprimer et rééditer</string>
<string name="sk_pin_post">Épingler au profil</string>
@@ -141,7 +141,7 @@
<string name="sk_delete_list_confirm">Êtes-vous sûr de vouloir supprimer la liste \"%s\" \?</string>
<string name="sk_your_lists">Vos listes</string>
<string name="sk_timeline_federated">Fédération</string>
<string name="sk_timeline_local">Communauté</string>
<string name="sk_timeline_local">Local</string>
<string name="sk_timeline_home">Accueil</string>
<string name="sk_recent_searches_placeholder">Écrivez pour lancer la recherche</string>
<string name="sk_do_remove_follower">Supprimer</string>
@@ -149,28 +149,28 @@
<string name="sk_changelog">Journal des modifications</string>
<string name="sk_remove_follower_confirm">Supprimer %s en tant qu\'abonné en le bloquant et en le débloquant immédiatement \?</string>
<string name="sk_remove_follower">Supprimer comme abonné</string>
<string name="sk_unpin_timeline">Détacher la timeline</string>
<string name="sk_unpin_timeline">Détacher le fil</string>
<string name="sk_alt_text_missing_title">Texte alternatif manquant</string>
<string name="sk_alt_text_missing">Au moins une pièce jointe ne contient pas de description.</string>
<string name="sk_publish_anyway">Publier quand même</string>
<string name="sk_notify_posts_info_banner">Si vous activez les notifications de message pour certaines personnes, leurs nouveaux messages apparaîtront ici.</string>
<string name="sk_timelines">Chronologies</string>
<string name="sk_timelines">Fils</string>
<string name="sk_timeline_posts">Messages</string>
<string name="sk_timelines_add">Ajouter</string>
<string name="sk_timeline">Chronologie</string>
<string name="sk_timeline">Fil</string>
<string name="sk_list">Liste</string>
<string name="sk_hashtag">Hashtag</string>
<string name="sk_pin_timeline">Épingler la timeline</string>
<string name="sk_pin_timeline">Épingler le fil</string>
<string name="sk_unpinned_timeline">Détachée de l\'accueil</string>
<string name="sk_pinned_timeline">Épinglée à l\'accueil</string>
<string name="sk_pinned_timeline">Épinglé à laccueil</string>
<string name="sk_remove">Supprimer</string>
<string name="sk_timeline_icon">Icône</string>
<string name="sk_icon_heart">Cœur</string>
<string name="sk_icon_star">Favoris</string>
<string name="sk_edit_timelines">Modifier les timelines</string>
<string name="sk_edit_timelines">Modifier les fils</string>
<string name="sk_alt_button">ALT</string>
<string name="sk_post_edited">édité</string>
<string name="sk_edit_timeline">Modifier la timeline</string>
<string name="sk_edit_timeline">Modifier le fil</string>
<string name="sk_notify_update">Modifier un article boosté</string>
<string name="sk_settings_disable_alt_text_reminder">Désactiver le rappel pour ajouter du texte alternatif</string>
<string name="sk_notification_type_update">Messages modifiés</string>
@@ -290,7 +290,7 @@
<string name="sk_open_in_app">Ouvrir dans l\'application</string>
<string name="sk_external_share_title">Partager avec le compte</string>
<string name="sk_external_share_or_open_title">Partager ou ouvrir avec le compte</string>
<string name="sk_bubble_timeline_info_banner">Ce sont les messages les plus récents du réseau organisés par vos administrateurs d\'instance.</string>
<string name="sk_bubble_timeline_info_banner">Ce sont les messages les plus récents du réseau organisés par les administrateur·rice·s de votre instance.</string>
<string name="sk_timeline_bubble">Bulle</string>
<string name="sk_instance_info_unavailable">Informations sur l\'instance temporairement indisponibles</string>
<string name="sk_open_in_app_failed">Impossible de l\'ouvrir dans l\'application</string>
@@ -311,7 +311,7 @@
<string name="sk_icon_doctor">Docteur</string>
<string name="sk_icon_diamond">Diamant</string>
<string name="sk_icon_umbrella">Parapluie</string>
<string name="sk_add_timeline">Ajouter une timeline</string>
<string name="sk_add_timeline">Ajouter un fil</string>
<string name="sk_edit_timeline_tag_any">… ou l\'un d\'entre eux</string>
<string name="sk_edit_timeline_tag_all">… et chacun d\'entre eux</string>
<string name="sk_edit_timeline_tag_none">… mais aucun d\'entre eux</string>
@@ -327,11 +327,11 @@
<string name="sk_edit_timeline_tag_hint">Entrez le hashtag…</string>
<string name="sk_edit_timeline_tags_explanation">Veuillez noter que le serveur gère ces opérations. Les combiner peut ne pas être prise en charge.</string>
<string name="sk_exclusive_list">Liste exclusive</string>
<string name="sk_list_exclusive_switch_explanation">Les membres d\'une liste exclusive n\'apparaîtront pas sur votre chronologie personnelle - si votre instance le prend en charge.</string>
<string name="sk_list_exclusive_switch_explanation">Les membres d\'une liste exclusive n\'apparaîtront pas sur votre fil principal - si votre instance le prend en charge.</string>
<string name="sk_icon_feed">Flux</string>
<string name="sk_spoiler_show">Montrer le contenu</string>
<string name="sk_pronouns_label">Pronoms</string>
<string name="sk_switch_timeline">Changer la chronologie</string>
<string name="sk_switch_timeline">Changer de fil</string>
<string name="sk_settings_instance">Instance</string>
<string name="sk_settings_true_black">Mode noir absolu</string>
<string name="sk_gif_badge">GIF</string>
@@ -374,4 +374,23 @@
<string name="sk_again_for_system_keyboard">Appuyez à nouveau pour le clavier système</string>
<string name="sk_enter_emoji_hint">Tapez pour réagir avec un emoji</string>
<string name="sk_enter_emoji_toast">Vous devez saisir un emoji</string>
<plurals name="sk_posts_count_label">
<item quantity="one">message</item>
<item quantity="many">messages</item>
<item quantity="other">messages</item>
</plurals>
<string name="sk_settings_show_emoji_reactions_only_opened">Uniquement lorsque le message est ouvert</string>
<string name="sk_settings_show_emoji_reactions_always">Toujours afficher le bouton Ajouter</string>
<string name="sk_search_suicide_hotlines">Trouver un numéro d\'assistance</string>
<string name="sk_do_not_show_again">Ne plus afficher</string>
<string name="sk_suicide_helplines_url">https://findahelpline.com/fr</string>
<string name="sk_post_contains_media">Le message contient des médias</string>
<string name="sk_load_missing_posts_newest_first">Le plus récent en premier (descendant)</string>
<string name="sk_load_missing_posts_oldest_first">Le plus ancien en premier (ascendant)</string>
<string name="sk_settings_load_missing_posts">Comportement lors du chargement des messages manquants</string>
<string name="sk_settings_show_emoji_reactions">Afficher les réactions emoji dans les fils</string>
<string name="sk_settings_show_emoji_reactions_hide_empty">Masquer les réactions emoji vides</string>
<string name="sk_suicide_search_terms">Suicide</string>
<string name="sk_search_suicide_title">Dans le cas où vous seriez en détresse…</string>
<string name="sk_search_suicide_message">Si vous cherchez un signe pour ne pas vous suicider, le voici. Si vous êtes en détresse et/ou avez des pensées suicidaires, si vous voulez aider une personne en souffrance, vous pouvez contacter une ligne d\'assistance de prévention du suicide.</string>
</resources>

View File

@@ -425,7 +425,7 @@
<string name="welcome_to_mastodon">Fàilte gu Mastodon</string>
<string name="welcome_paragraph1">S e lìonra sòisealta sgaoilte a th ann am Mastodon agus is ciall dha seo nach eil e fo smachd aon chompanaidh a-mhàin. Tha e dèanta de ghrunn fhrithealaichean a tha gan ruith gu neo-eisimeileach ach ceangailte ri chèile.</string>
<string name="what_are_servers">Dè th anns na frithealaichean?</string>
<string name="welcome_paragraph2"><![CDATA[Tha gach cunntas Mastodon ga òstadh air frithealaiche tha luachan, riaghailtean ⁊ rianairean sònraichte aig gach fear. Ge b e dè am frithealaiche a thaghas tu, s urrainn dhut daoine air frithealaiche sam bith a leantainn is bruidhinn riutha.]]></string>
<string name="welcome_paragraph2">Tha gach cunntas Mastodon ga òstadh air frithealaiche tha luachan, riaghailtean ⁊ rianairean sònraichte aig gach fear. Ge b e dè am frithealaiche a thaghas tu, s urrainn dhut daoine air frithealaiche sam bith a leantainn is bruidhinn riutha.</string>
<string name="opening_link">A fosgladh a cheangail…</string>
<string name="link_not_supported">Cha chuir an aplacaid taic ris a cheangal seo</string>
<string name="log_out_all_accounts">Clàraich a-mach às a h-uile cunntas</string>

View File

@@ -1,3 +1,314 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="sk_filtered">Criathraichte: %s</string>
<string name="sk_collapse">Co-theannaich</string>
<string name="sk_poll_allow_multiple">Ceadaich iomadh roghainn</string>
<string name="sk_pinned_posts">Prìnichte</string>
<string name="sk_clear_recent_languages">Falamhaich na cànain o chionn goirid</string>
<string name="sk_app_name">Megalodon</string>
<string name="sk_pin_post">Prìnich ris a phròifil</string>
<string name="sk_settings_always_reveal_content_warnings">Leudaich rabhaidhean susbainte an-còmhnaidh</string>
<string name="sk_bookmark_as">Cuir ris na comharran-lìn aig cunntas eile</string>
<string name="sk_translate_show_original">Seall an tionndadh tùsail</string>
<string name="sk_translated_using">Air eadar-theangachadh le %s</string>
<string name="sk_settings_color_palette">Pailead nan dathan</string>
<string name="sk_delete_notification">Sguab às am brath</string>
<string name="sk_delete_notification_confirm_action">Sguab às am brath</string>
<string name="sk_settings_translation_availability_note_available">Tha %s a cur taic ri eadar-theangachadh!</string>
<string name="sk_settings_translation_availability_note_unavailable">Chan eil %s a cur taic ri eadar-theangachadh a-rèir coltais.</string>
<string name="sk_clear_all_notifications">Falamhaich a h-uile brath</string>
<string name="sk_clear_all_notifications_confirm_action">Sguab às na h-uile</string>
<string name="sk_clear_all_notifications_confirm">A bheil thu cinnteach gu bheil thu airson gach brath fhalamhachadh\?</string>
<string name="sk_loading_fediverse_resource_title">Ga lorg air a cho-shaoghal</string>
<string name="sk_undo_reblog">Na brosnaich tuilleadh</string>
<string name="sk_forward_report_to">Sìn air adhart gu %s</string>
<string name="sk_settings_prefix_replies_always">Ann am freagairtean gu duine sam bith</string>
<string name="sk_settings_prefix_replies_to_others">Ann am freagairtean do chàch a-mhàin</string>
<string name="sk_confirm_save_draft">A bheil thu airson a shàbhaladh na dhreachd\?</string>
<string name="sk_icon_beaker">Bìocar</string>
<string name="sk_icon_doctor">Dotair</string>
<string name="sk_icon_diamond">Daoimean</string>
<string name="sk_icon_umbrella">Sgàilean</string>
<string name="sk_add_timeline">Cuir loidhne-ama ris</string>
<string name="sk_edit_timeline_tag_main">Postaichean sa bheil taga hais…</string>
<string name="sk_edit_timeline_tag_any">… no gin sam bith dhen fheadhainn seo</string>
<string name="sk_edit_timeline_tag_all">s gach fear dhen fheadhainn seo</string>
<string name="sk_schedule_or_draft">Sgeideal no dreachd</string>
<string name="sk_content_type">Seòrsa na susbainte</string>
<string name="sk_settings_reduce_motion">Ìslich an gluasad sna beòthachaidhean</string>
<string name="sk_announcements">Brathan-fios</string>
<string name="sk_mark_as_read">Cuir comharra gun deach a leughadh</string>
<string name="sk_settings_about_instance">Mun ionstans</string>
<string name="sk_recent_searches_placeholder">Sgrìobh rud a thòiseachadh air lorg</string>
<string name="sk_remove_follower">Thoir an neach-leantainn air falbh</string>
<string name="sk_do_remove_follower">Thoir air falbh</string>
<string name="sk_icon_city">Baile</string>
<string name="sk_icon_cat">Cat</string>
<string name="sk_icon_dog"></string>
<string name="sk_icon_rabbit">Coineanach</string>
<string name="sk_icon_clapper_board">Bòrd-braig</string>
<string name="sk_icon_leaves">Duilleach</string>
<string name="sk_edit_timelines">Deasaich na loidhnichean-ama</string>
<string name="sk_alt_button">ALT</string>
<string name="sk_post_edited">air a dheasachadh</string>
<string name="sk_icon_pin">Prìne</string>
<string name="sk_notification_type_update">Postaichean air an deasachadh</string>
<string name="sk_searching">Ga lorg…</string>
<string name="sk_settings_see_new_posts_button">Putan “Seall na postaichean ùra”</string>
<string name="sk_icon_feed">Inbhir</string>
<string name="sk_settings_hide_interaction">Falaich putanan na h-eadar-ghabhail</string>
<string name="sk_settings_enable_marquee">Cuir an comas sgroladh teacsa air bàraichean-tiotail</string>
<string name="sk_quoting_user">A toirt iomradh air %s</string>
<string name="sk_draft">Dreachd</string>
<string name="sk_settings_continues_playback">Tar-chòmhdachadh fuaime</string>
<string name="sk_settings_continues_playback_summary">Leig le meadhanan a tha gan cluich cumail a dol thairis air a chluiche ùr</string>
<string name="sk_settings_load_new_posts">Luchdaich postaichean ùra gu fèin-obrachail</string>
<string name="sk_settings_show_interaction_counts">Seall cunntas na h-eadar-ghabhail</string>
<string name="sk_settings_app_version">Megalodon v%1$s (%2$d)</string>
<string name="sk_mark_media_as_sensitive">Cuir comharra gu bheil am meadhan frionasach</string>
<string name="sk_federated_timeline">Co-nasgadh</string>
<string name="sk_alt_text_missing_title">Tha roghainn teacsa a dhìth</string>
<string name="sk_alt_text_missing">Tha ceanglachan no dhà gun tuairisgeul ann.</string>
<string name="sk_publish_anyway">Foillsich e co-dhiù</string>
<string name="sk_settings_disable_alt_text_reminder">Cuir an cuimhneachan air roghainn teacsa dheth</string>
<string name="sk_notify_posts_info_banner">Ma chuireas tu brathan puist an comas do chuid, nochdaidh na postaichean ùra aca an-seo.</string>
<string name="sk_timelines">Loidhnichean-ama</string>
<string name="sk_timeline_posts">Postaichean</string>
<string name="sk_timelines_add">Cuir ris</string>
<string name="sk_timeline">Loidhne-ama</string>
<string name="sk_list">Liosta</string>
<string name="sk_hashtag">Taga hais</string>
<string name="sk_pin_timeline">Prìnich an loidhne-ama</string>
<string name="sk_unpin_timeline">Dì-phrìnich an loidhne-ama</string>
<string name="sk_pinned_timeline">Prìnichte ris an dachaigh</string>
<string name="sk_unpinned_timeline">Dì-phrìnichte on dachaigh</string>
<string name="sk_remove">Thoir air falbh</string>
<string name="sk_timeline_icon">Ìomhaigheag</string>
<string name="sk_icon_heart">Cridhe</string>
<string name="sk_gif_badge">GIF</string>
<string name="sk_notify_update">Post brosnaichte air a dheasachadh</string>
<string name="sk_attach_file">Ceangail faidhle ris</string>
<string name="sk_no_results">Gun toradh</string>
<string name="sk_save_draft">A bheil thu airson a shàbhaladh na dhreachd\?</string>
<string name="sk_save_draft_message">A bheil thu airson na h-atharraichean agad a shàbhaladh nan dreachd no am foillseachadh an-dràsta\?</string>
<string name="sk_no_alt_text">Chan eil roghainn teacsa ri fhaighinn</string>
<string name="sk_settings_show_alt_indicator">Taisbeanair dhan roghainn teacsa</string>
<string name="sk_settings_show_no_alt_indicator">Taisbeanair do roghainn teacsa a dhìth</string>
<string name="sk_updater_enable_pre_releases">Cuir na ro-sgaoilidhean an comas</string>
<string name="sk_inline_local_only">ionadail a-mhàin</string>
<string name="sk_inline_direct">le iomradh ort a-mhàin</string>
<string name="sk_separator">·</string>
<string name="sk_local_only">An t-ionstans ionadail a-mhàin</string>
<string name="sk_instance_features">Gleusan an ionstans</string>
<string name="sk_settings_support_local_only">Cuiridh am frithealaiche taic ri postadh gu h-ionadail</string>
<string name="sk_settings_local_only_explanation">Feumaidh an ionstans-dachaigh agad taic a chur ri postaichean a bhios ionadail a-mhàin. Cuiridh a mhòrchuid de thionndaidhean atharraichte de Mhastdon taic ri seo ach cha chuir Mastodon àbhaisteach.</string>
<string name="sk_settings_glitch_instance">Modh ionadail a-mhàin aig Glitch</string>
<string name="sk_settings_glitch_mode_explanation">Cuir seo an comas ma tha an t-ionstans-dachaigh agad a ruith Glitch. Chan eil feum air seo airson Hometown no Akkoma.</string>
<string name="sk_content_type_html">HTML</string>
<string name="sk_settings_confirm_before_reblog">Dearbh mus dèan thu brosnachadh</string>
<string name="sk_language_name">%1$s (%2$s)</string>
<string name="sk_reblog_as">Brosnaich le cunntas eile</string>
<string name="sk_compact_reblog_reply_line">Loidhne brosnachaidh/freagairt dhùmhlaichte</string>
<string name="sk_bubble_timeline_info_banner">Seo na postaichean as ùire on lìonra a tha rianairean an ionstans agad a curaideachadh.</string>
<string name="sk_accept_follow_request">Gabh ris an iarrtas leantainn</string>
<string name="sk_reject_follow_request">Diùlt an t-iarrtas leantainn</string>
<string name="sk_lists_with_user">Liostaichean le %s</string>
<string name="sk_color_palette_pink">Pinc</string>
<string name="sk_color_palette_purple">Purpaidh</string>
<string name="sk_color_palette_green">Uaine</string>
<string name="sk_color_palette_blue">Gorm</string>
<string name="sk_color_palette_brown">Donn</string>
<string name="sk_color_palette_red">Dearg</string>
<string name="sk_color_palette_yellow">Buidhe</string>
<string name="sk_confirm_clear_recent_languages">A bheil thu cinnteach gu bheil thu airson na cànain o chionn goirid fhalamhachadh\?</string>
<string name="sk_welcome_title">Fàilte!</string>
<string name="sk_welcome_text">Tha an cearban gad fhàilteachadh! Airson tòiseachadh, cuir a-steach ainm àrainne an ionstans-dhachaigh agad gu h-ìosal.</string>
<string name="sk_example_domain">ball-eisimpleir.social</string>
<string name="sk_settings_profile">Suidhich pròifil</string>
<string name="sk_settings_posting">Roghainnean postaidh</string>
<string name="sk_settings_filters">Rèitich na criathragan</string>
<string name="sk_settings_auth">Roghainnean tèarainteachd</string>
<string name="sk_settings_rules">Riaghailtean</string>
<string name="sk_settings_publish_button_text">Teacsa a phutain-fhoillseachaidh</string>
<string name="sk_settings_publish_button_text_title">Gnàthaich teacsa a phutain-fhoillseachaidh</string>
<string name="sk_icon_megaphone">Meaga-fòn</string>
<string name="sk_icon_microphone">Micreofon</string>
<string name="sk_icon_microscope">Micreosgop</string>
<string name="sk_icon_keyboard">Meur-chlàr</string>
<string name="sk_icon_coffee">Cofaidh</string>
<string name="sk_icon_laugh">Gàire</string>
<string name="sk_icon_news">Naidheachdan</string>
<string name="sk_icon_pi">Pi</string>
<string name="sk_icon_color_palette">Pailead nan dathan</string>
<string name="sk_icon_academic_cap">Currac sgoilearachd</string>
<string name="sk_icon_tag">Taga</string>
<string name="sk_icon_stethoscope">Steatasgop</string>
<string name="sk_icon_weather">Aimsir</string>
<string name="sk_icon_games">Geamannan</string>
<string name="sk_icon_code">Còd</string>
<string name="sk_icon_light_bulb">Bolgan solais</string>
<string name="sk_icon_train">Trèana</string>
<string name="sk_icon_sport">Spòrs</string>
<string name="sk_edit_timeline_tags_explanation">Thoir an aire gur e am frithealaiche a làimhsicheas na gnìomhan seo. Dhfhaoidte nach obraich an cur ri chèile aca.</string>
<string name="sk_hashtag_timeline_local_only_switch">A bheil thu airson na postaichean ionadail a shealltainn a-mhàin\?</string>
<string name="sk_add_timeline_tag_error_empty">Chan fhaod an taga hais a bhith falamh</string>
<string name="sk_signed_up">air a chlàradh</string>
<string name="sk_reported">air gearan a dhèanamh</string>
<string name="sk_reacted_with">Fhreagair %1$s le %2$s</string>
<string name="sk_reacted">Fhreagair %s</string>
<string name="sk_sign_ups">Cleachdaichean a clàradh</string>
<string name="sk_new_reports">Gearanan ùra</string>
<string name="sk_notify_poll_results">Toraidhean cunntais-bheachd</string>
<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_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>
<string name="sk_settings_hide_fab">Falaich putan an sgrìobhaidh gu fèin-obrachail</string>
<string name="sk_notification_action_replied">Chaidh freagairt a chur gu %s</string>
<string name="sk_in_reply">San fhreagairt</string>
<string name="sk_reply_line_above_avatar">Loidhne nam freagairtean os cionn an avatar</string>
<string name="sk_show_thread">Seall an snàithlean</string>
<string name="sk_content_type_unspecified">Cha deach a shònrachadh</string>
<string name="sk_content_type_plain">Teacsa lom</string>
<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">Cuir fòrmatadh nam postaichean an comas</string>
<string name="sk_settings_server_version">Tionndadh an fhrithealaiche: %s</string>
<string name="sk_delete_and_redraft">Sguab às is dèan dreachd ùr air</string>
<string name="sk_confirm_delete_and_redraft_title">Sguab às is dèan dreachd ùr air a phost</string>
<string name="sk_confirm_delete_and_redraft">A bheil thu cinnteach gu bheil thu airson am post seo a sguabadh às s dreachd ùr a dhèanamh air\?</string>
<string name="sk_confirm_pin_post_title">Prìnich am post ris a phròifil</string>
<string name="sk_confirm_pin_post">A bheil thu airson am post seo a phrìneachadh ris a phròifil agad\?</string>
<string name="sk_pinning">A prìneachadh a phuist…</string>
<string name="sk_unpin_post">Dì-phrìnich on phròifil</string>
<string name="sk_confirm_unpin_post_title">Dì-phrìnich am post on phròifil</string>
<string name="sk_confirm_unpin_post">A bheil thu cinnteach gu bheil thu airson am post seo a dì-phrìneachadh\?</string>
<string name="sk_unpinning">A dì-phrìneachadh a phuist…</string>
<string name="sk_image_description">Tuairisgeul an deilbh</string>
<string name="sk_visibility_unlisted">Falaichte o liostaichean</string>
<string name="sk_settings_show_replies">Seall na freagairtean</string>
<string name="sk_settings_reply_visibility">Faicsinneach nam freagairtean</string>
<string name="sk_settings_reply_visibility_all">A h-uile freagairt</string>
<string name="sk_settings_reply_visibility_following">Freagairtean dhan luchd-leantainn agam</string>
<string name="sk_settings_reply_visibility_self">Freagairtean dhomhsa</string>
<string name="sk_settings_show_boosts">Seall na brosnachaidhean</string>
<string name="sk_user_post_notifications_on">Chuir thu brathan nam post air dha %s</string>
<string name="sk_user_post_notifications_off">Chuir thu brathan nam post dheth dha %s</string>
<string name="sk_federated_timeline_info_banner">Seo na postaichean as ùire leis na daoine sa cho-nasgadh agad.</string>
<string name="sk_update_available">Tha Megalodon %s deiseil ri luchdadh a-nuas.</string>
<string name="sk_update_ready">Chaidh Megalodon %s a luchdadh a-nuas is tha e deiseil ri stàladh.</string>
<string name="sk_check_for_update">Thoir sùil airson ùrachadh</string>
<string name="sk_no_update_available">Chan eil ùrachadh ri fhaighinn</string>
<string name="sk_list_timelines">Liostaichean</string>
<string name="sk_follow_requests">Iarrtasan leantainn</string>
<string name="sk_settings_contribute">Cuidich le leasachadh Megalodon</string>
<string name="sk_settings_show_federated_timeline">Seall an loidhne-ama cho-naisgte</string>
<string name="sk_notification_type_status">Postaichean</string>
<string name="sk_notification_type_posts">Brathan puist</string>
<string name="sk_color_palette_material3">An siostam</string>
<string name="sk_translate_post">Eadar-theangaich</string>
<string name="sk_post_language">Cànan: %s</string>
<string name="sk_available_languages">Cànain ri am faighinn</string>
<string name="sk_settings_tabs_disable_swipe">Cuir grad-shlaighdeadh eadar tabaichean à comas</string>
<string name="sk_settings_about">Mun aplacaid</string>
<string name="sk_settings_donate">Thoir tabhartas dhuinn</string>
<string name="sk_delete_notification_confirm">A bheil thu cinnteach gu bheil thu airson am brath seo a sguabadh às\?</string>
<string name="sk_settings_enable_delete_notifications">Cuir sguabadh às nam brathan an comas</string>
<string name="sk_settings_translate_only_opened">Na eadar-theangaich ach postaichean a chaidh fhosgladh</string>
<string name="sk_loading_resource_on_instance_title">Ga lorg air %s</string>
<string name="sk_reblogged_as">Chaidh a bhrosnachadh mar %s</string>
<string name="sk_reblog_with_visibility">Brosnaich le so-fhaicsinneachd</string>
<string name="sk_quote_post">Postaich mu dhèidhinn seo</string>
<string name="sk_hashtags_you_follow">Tagaichean hais gan leantainn</string>
<string name="sk_copy_link_to_post">Dèan lethbhreac dhen cheangal dhan phost</string>
<string name="sk_open_with_account">Fosgail le cunntas eile</string>
<string name="sk_resource_not_found">Cha deach an goireas a lorg</string>
<string name="sk_bookmarked_as">Chaidh a chur ris na comharran-lìn mar %s</string>
<string name="sk_already_bookmarked">Tha seo na chomharra-lìn mu thràth</string>
<string name="sk_favorite_as">Cuir ris na h-annsachdan aig cunntas eile</string>
<string name="sk_favorited_as">Chaidh a chur ris na h-annsachdan mar %s</string>
<string name="sk_already_favorited">Tha seo na annsachd mu thràth</string>
<string name="sk_already_reblogged">Tha seo ga bhrosnachadh mu thràth</string>
<string name="sk_reply_as">Freagair le cunntas eile</string>
<string name="sk_settings_uniform_icon_for_notifications">Ìomhaigheag chunbhalach dhan a h-uile brath</string>
<string name="sk_unsent_posts">Postaichean gun chur</string>
<string name="sk_schedule">Sgeidealaich</string>
<string name="sk_confirm_delete_draft_title">Sguab às an dreachd</string>
<string name="sk_confirm_delete_draft">A bheil thu cinnteach gu bheil thu airson an dreachd seo a sguabadh às\?</string>
<string name="sk_confirm_delete_scheduled_post_title">Sguab às am post sgeidealaichte</string>
<string name="sk_confirm_delete_scheduled_post">A bheil thu cinnteach gu bheil thu airson am post sgeidealaichte seo a sguabadh às\?</string>
<string name="sk_draft_or_schedule">Dèan dreachd no sgeidealaich</string>
<string name="sk_compose_draft">Thèid am post a shàbhaladh mar dhreachd.</string>
<string name="sk_compose_scheduled">Air an sgeideal</string>
<string name="sk_draft_saved">Chaidh an dreachd a shàbhaladh</string>
<string name="sk_post_scheduled">Chaidh am post a chur air an sgeideal</string>
<string name="sk_scheduled_too_soon_title">Tha àm an sgeideil ro thràth</string>
<string name="sk_scheduled_too_soon">Feumaidh post sgeidealaichte a bhith 10 mionaidean san àm ri teachd air a char as tràithe.</string>
<string name="sk_confirm_save_changes">A bheil thu airson na dhatharraich thu a shàbhaladh\?</string>
<string name="sk_mark_as_draft">Cuir comharra gur e dreachd a th ann</string>
<string name="sk_schedule_post">Cuir am post air an sgeideal</string>
<string name="sk_compose_no_schedule">Na cuir air an sgeideal</string>
<string name="sk_compose_no_draft">Na dèan dreachd dheth</string>
<string name="sk_settings_single_notification">Na seall ach aon bhrath</string>
<string name="sk_settings_unifiedpush">Cleachd UnifiedPush</string>
<string name="sk_settings_unifiedpush_choose">Tagh sgaoileadair</string>
<string name="sk_settings_unifiedpush_no_distributor">Cha deach sgaoileadair a lorg</string>
<string name="sk_settings_unifiedpush_no_distributor_body">Feumaidh tu sgaoileadair a stàladh mus obraich brathan le UnifiedPush. Airson barrachd fiosrachaidh, tadhail air https://unifiedpush.org/</string>
<string name="sk_create">Cruthaich</string>
<string name="sk_create_list_title">Cruthaich liosta</string>
<string name="sk_list_name_hint">Ainm na liosta</string>
<string name="sk_list_replies_policy">Seall na freagairtean gu</string>
<string name="sk_list_replies_policy_list">buill na liosta</string>
<string name="sk_list_replies_policy_followed">cleachdaichean a leanas tu</string>
<string name="sk_list_replies_policy_none">na seall idir</string>
<string name="sk_delete_list">Sguab às an liosta</string>
<string name="sk_delete_list_confirm">A bheil thu cinnteach gu bheil thu airson an liosta “%s” a sguabadh às\?</string>
<string name="sk_edit_list_title">Deasaich an liosta</string>
<string name="sk_your_lists">Na liostaichean agad</string>
<string name="sk_timeline_home">Dachaigh</string>
<string name="sk_timeline_local">Ionadail</string>
<string name="sk_timeline_federated">Co-nasgadh</string>
<string name="sk_timeline_bubble">Do cuideachd</string>
<string name="sk_remove_follower_confirm">A bheil thu airson %s a thoirt air falbh na neach-leantainn le bacadh s dì-bhacadh sa bhad\?</string>
<string name="sk_remove_follower_success">Chaidh an neach-leantainn a thoirt air falbh</string>
<string name="sk_changelog">Loga nan atharraichean</string>
<string name="sk_icon_star">Rionnag</string>
<string name="sk_icon_turtle">Turtar</string>
<string name="sk_icon_balloon">Bailiùn</string>
<string name="sk_icon_image">Dealbh</string>
<string name="sk_icon_bot">Bot</string>
<string name="sk_icon_language">Cànan</string>
<string name="sk_icon_location">Ionad</string>
<string name="sk_icon_aperture">Fosgladh</string>
<string name="sk_icon_music">Ceòl</string>
<string name="sk_icon_people">Daoine</string>
<string name="sk_icon_health">Slàinte</string>
<string name="sk_icon_important">Cudromach</string>
<string name="sk_icon_chat">Cabadaich</string>
<string name="sk_icon_shield">Sgiath</string>
<string name="sk_icon_book">Leabhar</string>
<string name="sk_icon_bicycle">Baidhseagal</string>
<string name="sk_icon_map">Mapa</string>
<string name="sk_icon_math_formula">Foirmle matamataig</string>
<string name="sk_icon_backpack">Màla-droma</string>
<string name="sk_icon_briefcase">Màileid-oifise</string>
<string name="sk_icon_fire">Teine</string>
<string name="sk_icon_bug">Biastag</string>
<string name="sk_icon_pizza">Pizza</string>
<string name="sk_icon_gavel">Casar</string>
<string name="sk_icon_gauge">Gèidse</string>
<string name="sk_icon_headphones">Cluais-fhòn</string>
<string name="sk_icon_human">Daonna</string>
<string name="sk_icon_globe">Cruinne</string>
<string name="sk_icon_bed">Leabaidh</string>
<string name="sk_icon_recycle_bin">Biona ath-chuairteachaidh</string>
<string name="sk_icon_verified">Air a dhearbhadh</string>
<string name="sk_edit_timeline">Deasaich an loidhne-ama</string>
<string name="sk_edit_timeline_tag_none">… ach gun gin sam bith dhen fheadhainn seo</string>
<string name="sk_edit_timeline_tag_hint">Cuir a-steach taga hais…</string>
<string name="sk_edit_timeline_tags_hint">Cuir a-steach tagaichean hais…</string>
</resources>

View File

@@ -336,7 +336,6 @@
<string name="welcome_to_mastodon">Benvida a Mastodon</string>
<string name="welcome_paragraph1">Mastodon é unha rede social descentralizada, onde ningunha empresa ten o control. Está formada por moitos servidores independentes comunicándose entre si.</string>
<string name="what_are_servers">Que son os servidores?</string>
<string name="welcome_paragraph2"><![CDATA[Cada conta Mastodon está hospedada nun servidor — cada unha coas súas regras, valores e admins. Non importa cal elixas, podes seguir e interactuar con persoas de outros servidores.]]></string>
<!-- %s is formatted file size ("467 KB image") -->
<!-- %s is the server domain -->
<!-- Shown on the "stamp" on the screen that appears after you report a post/user. Please keep the translation short, preferably a single word -->

View File

@@ -1,3 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="sk_app_name">मेगालोडॉन</string>
<string name="sk_pinned_posts">पिन किया गया</string>
<string name="sk_delete_and_redraft">हटाएं और पुनः ड्राफ्ट करें</string>
<string name="sk_confirm_delete_and_redraft_title">हटाएं और पोस्ट को पुनः ड्राफ्ट करें</string>
<string name="sk_pin_post">प्रोफाइल पर पिन करें</string>
<string name="sk_confirm_pin_post_title">पोस्ट को प्रोफाइल पर पिन करें</string>
<string name="sk_pinning">पोस्ट पिन की जा रही है…</string>
<string name="sk_unpin_post">प्रोफाइल से अनपिन करें</string>
<string name="sk_confirm_unpin_post_title">पोस्ट को प्रोफाइल से अनपिन करें</string>
<string name="sk_unpinning">पोस्ट अनपिन की जा रही है…</string>
<string name="sk_image_description">चित्र विवरण</string>
<string name="sk_visibility_unlisted">असूचित</string>
<string name="sk_confirm_delete_and_redraft">क्या आप निश्चित हैं कि आप इस पोस्ट को हटाकर पुनः ड्राफ़्ट करना चाहते हैं\?</string>
<string name="sk_confirm_unpin_post">क्या आप निश्चित हैं कि आपको यह पोस्ट अनपिन करनी है\?</string>
<string name="sk_confirm_pin_post">क्या आप इस पोस्ट को अपनी प्रोफाइल पर पिन करना चाहते हैं\?</string>
</resources>

View File

@@ -303,7 +303,6 @@
<string name="welcome_to_mastodon">Բարի գալուստ Մաստոդոն</string>
<string name="welcome_paragraph1">Մաստոդոնը ապակենտրոնացված սոցցանց է, այսինքն՝ այն չի պատկանում մի ընկերության։ Այն բաղկացած է բազմաթիվ անկախ և կապակցված սերվերներից։</string>
<string name="what_are_servers">Ի՞նչ է սերվերը։</string>
<string name="welcome_paragraph2"><![CDATA[Մաստոդոնի որևէ հաշիվ գտնվում է սերվերի վրա - ամեն մեկը՝ իր արժեքներով, կանոններով և ադմիններով։ Դուք կարող եք հետևել և շփվել որևէ սերվերի մարդկանց հետ՝ անկախ ձեր ընտրությունից։]]></string>
<string name="retry">Կրկին</string>
<!-- %s is formatted file size ("467 KB image") -->
<string name="alt_text">Բացատրություն</string>

View File

@@ -368,7 +368,6 @@
<string name="welcome_to_mastodon">Selamat datang di Mastodon</string>
<string name="welcome_paragraph1">Mastodon adalah jejaring sosial terdesentralisasi, tidak ada satu pun perusahaan yang mengontrol. Semua dijalankan oleh server independen, terkoneksi bersama.</string>
<string name="what_are_servers">Apa itu server?</string>
<string name="welcome_paragraph2"><![CDATA[Semua akun Mastodon berada pada sebuah server — dengan nilai, aturan, dan admin masing-masing. Mana pun yang kamu pilih, kamu bisa mengikuti dan berinteraksi dengan server mana pun.]]></string>
<string name="opening_link">Membuka tautan…</string>
<string name="link_not_supported">Tautan ini tidak didukung dalam aplikasi</string>
<string name="log_out_all_accounts">Keluar dari semua akun</string>

View File

@@ -372,4 +372,7 @@
<string name="sk_settings_emoji_reactions_in_lists_explanation">"Menentukan apakah reaksi emoji ditampilkan di lini masa. Jika opsi ini mati, reaksi emoji hanya akan ditampilkan ketika melihat sebuah utas."</string>
<string name="sk_button_react">Bereaksi dengan emoji</string>
<string name="sk_again_for_system_keyboard">Ketuk lagi untuk Papan Ketik Sistem</string>
<plurals name="sk_posts_count_label">
<item quantity="other">kiriman</item>
</plurals>
</resources>

View File

@@ -387,7 +387,7 @@
<string name="welcome_to_mastodon">Velkomin í Mastodon</string>
<string name="welcome_paragraph1">Mastodon er dreyfhýst samfélagsnet, sem þýðir að ekkert eitt fyrirtæki ræður yfir því. Netið samanstendur af mörgum sjálfstætt reknum netþjónum sem tengjast innbyrðis.</string>
<string name="what_are_servers">Hvað eru netþjónar?</string>
<string name="welcome_paragraph2"><![CDATA[Hver einasti Mastodon-aðgangur er hýstur á sínum netþjóni — hver slíkur er með sín eigin gildi, reglur og stjórnendur. Það skiftir ekki máli hvern þeirra þú velur, þú getur fylgst fylgst með og átt í samskiptum við fólk á hvaða netþjóni sem er.]]></string>
<string name="welcome_paragraph2">Hver einasti Mastodon-aðgangur er hýstur á sínum netþjóni — hver slíkur er með sín eigin gildi, reglur og stjórnendur. Það skiftir ekki máli hvern þeirra þú velur, þú getur fylgst fylgst með og átt í samskiptum við fólk á hvaða netþjóni sem er.</string>
<string name="opening_link">Opna tengil…</string>
<string name="link_not_supported">Það er ekki stuðningur við tengilinn í forritinu</string>
<string name="log_out_all_accounts">Skrá út úr öllum aðgöngum</string>

View File

@@ -387,7 +387,7 @@
<string name="welcome_to_mastodon">Benvenuto/a su Mastodon</string>
<string name="welcome_paragraph1">Mastodon è un social network decentralizzato, il che significa che nessuna singola azienda lo controlla. È composto da molti server indipendenti e tutti connessi insieme.</string>
<string name="what_are_servers">Cosa sono i server?</string>
<string name="welcome_paragraph2"><![CDATA[Ogni account Mastodon è ospitato su un server — ognuno con i propri valori, regole, e amministratori. Non importa quale scegliere, è possibile seguire e interagire con le persone su qualsiasi server.]]></string>
<string name="welcome_paragraph2">Ogni account Mastodon è ospitato su un server — ognuno con i propri valori, regole, &amp; amministratori. Non importa quale scegliere, è possibile seguire e interagire con persone su altri server.</string>
<string name="opening_link">Apertura del collegamento…</string>
<string name="link_not_supported">Questo collegamento non è supportato nell\'app</string>
<string name="log_out_all_accounts">Esci da tutti gli account</string>

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