Compare commits
226 Commits
1.1.4+fork
...
1.1.4+fork
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
90bef7fddb | ||
|
|
c1b382ef34 | ||
|
|
028b88aa24 | ||
|
|
9d0ce33f5e | ||
|
|
dbb23d952c | ||
|
|
7fe7e47d53 | ||
|
|
d0c93dfd4d | ||
|
|
acdccaf80a | ||
|
|
769293ce1a | ||
|
|
8d0fe18b70 | ||
|
|
6926432a6c | ||
|
|
83f12b0840 | ||
|
|
290b7db7e4 | ||
|
|
f352c20ed9 | ||
|
|
2ccbffa165 | ||
|
|
06cd80a352 | ||
|
|
de97493e6a | ||
|
|
3a24ff0d15 | ||
|
|
c463a3fc39 | ||
|
|
fc845685cc | ||
|
|
0ef0aa1a44 | ||
|
|
337689aa45 | ||
|
|
f7e3423f9c | ||
|
|
b465c09cc8 | ||
|
|
06f2f67f0c | ||
|
|
05c33be3f4 | ||
|
|
ac6c0651d6 | ||
|
|
18af6f5a12 | ||
|
|
d11ee3a702 | ||
|
|
6d9f9ce2d2 | ||
|
|
e274b7e6d5 | ||
|
|
ec1496a4cc | ||
|
|
41e19185e8 | ||
|
|
e15dd6024f | ||
|
|
0806d0c5ea | ||
|
|
5c67dd0188 | ||
|
|
e52dffeece | ||
|
|
b4358f51cb | ||
|
|
622c6d503d | ||
|
|
b190480d77 | ||
|
|
9a085beea8 | ||
|
|
1a42a77e24 | ||
|
|
e35794ef7d | ||
|
|
1f9611fc3e | ||
|
|
563afd487c | ||
|
|
5b85bb427d | ||
|
|
4d62388617 | ||
|
|
04b8055474 | ||
|
|
e10faeefc4 | ||
|
|
65dbbb3d61 | ||
|
|
fa69868ca1 | ||
|
|
9c18de7b90 | ||
|
|
61bd19f6ff | ||
|
|
ba0689aef7 | ||
|
|
ad54e6bb4b | ||
|
|
f15fcb43da | ||
|
|
4e5c2a9ecf | ||
|
|
66208f5694 | ||
|
|
68863f28eb | ||
|
|
7feaf093e2 | ||
|
|
4ab9e25fec | ||
|
|
e14dfda2fd | ||
|
|
c9aae828e2 | ||
|
|
f346c0af26 | ||
|
|
f2557b7815 | ||
|
|
a2726f5b61 | ||
|
|
834ec1575d | ||
|
|
a30f5bdee8 | ||
|
|
4cef005286 | ||
|
|
58a05681fe | ||
|
|
2589faf499 | ||
|
|
a5bdf34289 | ||
|
|
09fdd7f492 | ||
|
|
519d8b887d | ||
|
|
a2f2263bf7 | ||
|
|
5b73b10b34 | ||
|
|
b7a4364a28 | ||
|
|
3f075aff7b | ||
|
|
f4c33a5970 | ||
|
|
809af0ec18 | ||
|
|
4ee640e072 | ||
|
|
1cbf310555 | ||
|
|
f1fdc8aa43 | ||
|
|
d696daece3 | ||
|
|
967bb09282 | ||
|
|
136d910b3b | ||
|
|
51eb48a455 | ||
|
|
6ee8afcf96 | ||
|
|
a59f2d4609 | ||
|
|
b75d871837 | ||
|
|
c72f93b990 | ||
|
|
586d337ead | ||
|
|
d84e10a22e | ||
|
|
351ec89207 | ||
|
|
7db7bf0220 | ||
|
|
a9764c4f46 | ||
|
|
a430b6a280 | ||
|
|
6a01124d13 | ||
|
|
2843e445e2 | ||
|
|
5c947d14b2 | ||
|
|
590adba3e3 | ||
|
|
efee249173 | ||
|
|
6d2ed27364 | ||
|
|
55716d742f | ||
|
|
e4555da735 | ||
|
|
8b4b99bec7 | ||
|
|
5de4b19969 | ||
|
|
a9460f401e | ||
|
|
012cca550e | ||
|
|
0c743db412 | ||
|
|
b819ee7d6d | ||
|
|
e7e3a249b5 | ||
|
|
980c580b55 | ||
|
|
e23c530e74 | ||
|
|
a64caccca2 | ||
|
|
829bcafcf2 | ||
|
|
e2a935c647 | ||
|
|
2e7afdb49e | ||
|
|
cdc965e026 | ||
|
|
dd4faa005e | ||
|
|
726ec7159c | ||
|
|
e74256ef6f | ||
|
|
a18718ca81 | ||
|
|
5a9bc0e269 | ||
|
|
2d39c62ff0 | ||
|
|
0da4f79413 | ||
|
|
2bdef776a2 | ||
|
|
1819d6f042 | ||
|
|
2f6a707847 | ||
|
|
4aaf017824 | ||
|
|
fb05ed48d0 | ||
|
|
49203ae539 | ||
|
|
d17660d516 | ||
|
|
513ce34671 | ||
|
|
44ce48009b | ||
|
|
a57ad67308 | ||
|
|
e63d04cea9 | ||
|
|
cf48cb6f75 | ||
|
|
542e53cf6a | ||
|
|
bab1d40038 | ||
|
|
2f4a8247e8 | ||
|
|
f0b9006c55 | ||
|
|
4bc14ef797 | ||
|
|
47d2cee3f1 | ||
|
|
088f53f5a9 | ||
|
|
fee660bf6c | ||
|
|
e97ecb89a9 | ||
|
|
1ab6a4532b | ||
|
|
b43ddd0d8b | ||
|
|
d0c4c2d594 | ||
|
|
e0ae079ea0 | ||
|
|
dfddbd15a9 | ||
|
|
29242c45a1 | ||
|
|
7ff0e59f4d | ||
|
|
2d0fe57a47 | ||
|
|
ba2b87749b | ||
|
|
0806af1261 | ||
|
|
09e92f3a18 | ||
|
|
eb5d0bb795 | ||
|
|
a8afba4067 | ||
|
|
7d66141c37 | ||
|
|
b6f3ea2eec | ||
|
|
2570445133 | ||
|
|
acbd22cf22 | ||
|
|
ef251b040a | ||
|
|
6c5bb69ba9 | ||
|
|
18f605e5c5 | ||
|
|
7599406449 | ||
|
|
670e4c8538 | ||
|
|
30458b115c | ||
|
|
da8933ec58 | ||
|
|
dc8ac51c83 | ||
|
|
c4747fdc72 | ||
|
|
58ba748ade | ||
|
|
c0d51ad58a | ||
|
|
a0da73f76f | ||
|
|
34b8888c8f | ||
|
|
74ad40f67c | ||
|
|
a7a29db8d5 | ||
|
|
86a938d31d | ||
|
|
d8d0830631 | ||
|
|
bba3b7476a | ||
|
|
4880c642fe | ||
|
|
76ad896461 | ||
|
|
b49159f9e0 | ||
|
|
cd8a80a6a1 | ||
|
|
3ce8aa7894 | ||
|
|
5f3645f716 | ||
|
|
5af96597d5 | ||
|
|
c2baf4e05f | ||
|
|
b356794da9 | ||
|
|
afe8f6cf6a | ||
|
|
ed0df82fe9 | ||
|
|
d3bc7a9790 | ||
|
|
9e7923bc50 | ||
|
|
851bf94c90 | ||
|
|
ae80b7d098 | ||
|
|
633c0f870d | ||
|
|
f9fe7819f9 | ||
|
|
f3d13545e7 | ||
|
|
f6b77777b5 | ||
|
|
340990fbd9 | ||
|
|
a7687f8e35 | ||
|
|
52aa4a5289 | ||
|
|
268accea14 | ||
|
|
101cde4d84 | ||
|
|
8863446f6a | ||
|
|
28a0824f6b | ||
|
|
b1f9d0516d | ||
|
|
5b21747d5d | ||
|
|
9fda48cff0 | ||
|
|
0e6f3df212 | ||
|
|
a8c3f1555e | ||
|
|
cd797a637b | ||
|
|
53b2eb59d3 | ||
|
|
09e2224596 | ||
|
|
5999aad21b | ||
|
|
874ce07c3e | ||
|
|
1787d08718 | ||
|
|
9a12be88da | ||
|
|
8f6bb74e61 | ||
|
|
e67bd2972a | ||
|
|
de5929d8d2 | ||
|
|
d7699ef079 | ||
|
|
3ab04ebca8 | ||
|
|
78d2aa96d7 |
32
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: bug
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
|
||||||
|
**Screenshots and screen recordings**
|
||||||
|
If applicable, add screenshots (and screen recordings, if possible) to help explain your problem.
|
||||||
|
|
||||||
|
**Version**
|
||||||
|
Megalodon version: [e.g. v1.1.4+fork.#]
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
- Does this issue also occur with the respective upstream release? (Please test using the respective `upstream-xxxxxx.apk` provided in [Releases](https://github.com/sk22/megalodon/releases)) No / Yes (`mastodon#…`)
|
||||||
|
|
||||||
|
> In this case, please consider filing an [upstream bug report](https://github.com/mastodon/mastodon-android/issues) instead. If this bug is seriously impacting your usage or you think I might want to try to fix it for Megalodon, feel free to still create this issue!
|
||||||
|
|
||||||
|
**Crash log**
|
||||||
|
If you know your way around Android development tools, please consider attaching a crash log, if possible.
|
||||||
20
.github/ISSUE_TEMPLATE/feature-ui-request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
name: Feature/UI request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: feature
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
If applicable: a clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
||||||
10
.github/ISSUE_TEMPLATE/something-else.md
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
name: It's something else…
|
||||||
|
about: Issues that can't be categorized as feature requests or bug reports
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
43
README.md
@@ -4,15 +4,27 @@
|
|||||||
|
|
||||||
> A fork of [megalodon](https://github.com/sk22/megalodon) which is a fork of [official Mastodon Android app](https://github.com/mastodon/mastodon-android) adding important features that are missing in the official app and possibly won’t ever be implemented, such as the federated timeline, unlisted posting, bookmarks and an image description viewer.
|
> A fork of [megalodon](https://github.com/sk22/megalodon) which is a fork of [official Mastodon Android app](https://github.com/mastodon/mastodon-android) adding important features that are missing in the official app and possibly won’t ever be implemented, such as the federated timeline, unlisted posting, bookmarks and an image description viewer.
|
||||||
|
|
||||||
**Warning! [The last version's integrated updater was broken](https://github.com/sk22/megalodon/issues/106) – I already published a fixed version! If you're not updating through Izzy's F-Droid repository (more sources to come, hopefully!), you'll have to download the current release manually. Sorry about that!**
|
|
||||||
|
|
||||||
[](https://github.com/sk22/megalodon/releases/latest/download/megalodon.apk)
|
[](https://github.com/LucasGGamerM/moshidon/releases/latest/download/moshidon.apk)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
## Key features
|
## Key features
|
||||||
|
|
||||||
|
### **Translate button**
|
||||||
|
|
||||||
|
**Allows you to translate posts in instances with the translate feature!**
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
### **Color themes**
|
||||||
|
|
||||||
|
**Allows you to change theme within the app. Supports Purple, pink, green, blue, orange and yellow!**
|
||||||
|
|
||||||
### **Unlisted posting**
|
### **Unlisted posting**
|
||||||
|
|
||||||
**Allows you to post publicly without having your post show up in trends, hashtags or public timelines (i.e., in the tabs “Local”, “Community” and “Posts”).**
|
**Allows you to post publicly without having your post show up in trends, hashtags or public timelines (i.e., in the tabs “Local”, “Community” and “Posts”).**
|
||||||
@@ -49,34 +61,21 @@ To bookmark a post, press the button between the Favorite and Share buttons on t
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
**Press the download button above to download the APK. Open the downloaded file on your Android device to install it. Megalodon will automatically notify you about new updates inside the app.**
|
**Press the download button above to download the APK. Open the downloaded file on your Android device to install it. Moshidon will automatically notify you about new updates inside the app.**
|
||||||
|
|
||||||
To install this app on your Android device, download the [latest release from GitHub](https://github.com/sk22/megalodon/releases/latest/download/megalodon.apk) and open it. You might have to accept installing APK files from your browser when trying to install it. You can also take a look at all releases on the [Releases](https://github.com/sk22/megalodon/releases) page.
|
To install this app on your Android device, download the [latest release from GitHub](https://github.com/LucasGGamerM/moshidon/releases/latest/download/moshidon.apk) and open it. You might have to accept installing APK files from your browser when trying to install it. You can also take a look at all releases on the [Releases](https://github.com/LucasGGamerM/moshidon/releases) page.
|
||||||
|
|
||||||
Megalodon makes use of [Mastodon for Android](https://github.com/mastodon/mastodon-android)’s automatic update checker. Megalodon will check for new updates available on GitHub and offer to download and install them. You can also manually press “Check for updates” at the bottom of the settings page!
|
Moshidon makes use of [Mastodon for Android](https://github.com/mastodon/mastodon-android)’s automatic update checker. Megalodon will check for new updates available on GitHub and offer to download and install them. You can also manually press “Check for updates” at the bottom of the settings page!
|
||||||
|
|
||||||
### Other sources
|
|
||||||
|
|
||||||
* **[Izzy's F-Droid repository](https://apt.izzysoft.de/fdroid/repo)**: https://apt.izzysoft.de/fdroid/index/apk/org.joinmastodon.android.sk
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
||||||
## Release variants
|
## Release variants
|
||||||
|
|
||||||
All downloads can be found on the [Releases](https://github.com/sk22/megalodon/releases) page.
|
All downloads can be found on the [Releases](https://github.com/LucasGGamerM/moshidon/releases) page.
|
||||||
|
|
||||||
**`megalodon.apk`**
|
**`moshidon.apk`**
|
||||||
|
|
||||||
Variant with an integrated updater. If you download Megalodon from here (and not from an app store), just download the regular `megalodon.apk`.
|
Variant with an integrated updater. If you download Moshidon from here (and not from an app store), just download the regular `moshidon.apk`.
|
||||||
|
|
||||||
**`upstream-1234abc.apk`**
|
|
||||||
|
|
||||||
This is an **unmodified version** of the official [Mastodon for Android](https://github.com/mastodon/mastodon-android) app the respective Megalodon release is based on. Should you find any bugs in Megalodon (which you will), try to see if it occurs with this variant, too. The last 7 digits of the file name are important to know which version of the official app you're using.
|
|
||||||
|
|
||||||
<!-- **`megalodon-fdroid.apk`**
|
|
||||||
|
|
||||||
Variant without the integrated updater. This is the variant to be published to F-Droid.org where an integrated updater is not necessary. -->
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -139,4 +138,4 @@ This project is released under the [GPL-3 License](./LICENSE).
|
|||||||
|
|
||||||
## Links
|
## Links
|
||||||
|
|
||||||
<a rel="me" href="https://floss.social/@megalodon">@megalodon<wbr>@floss.social</a>
|
<a rel="me" href="https://floss.social/@moshidon">@moshidon<wbr>@floss.social</a>
|
||||||
|
|||||||
16
fastlane/metadata/android/cs-CZ/full_description.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
Mastodon je největší decentralizovanou sociální sítí na internetu. Místo jediné webové stránky je to síť pro miliony uživatelů v nezávislých komunitách, ve kterých mohou všichni vzájemně a bezproblémově komunikovat. Bez ohledu na to, co vás baví, můžete se setkat s vášnivými lidmi, kteří o tom přispívají na Mastodon!
|
||||||
|
|
||||||
|
Připojte se ke komunitě a vytvořte svůj profil. Najděte a sledujte fascinující lidi a přečtěte si jejich příspěvky v chronologické časové ose bez reklam. Vyjádřete se pomocí vlastních emoji, obrázků, GIFů, videí a zvuku v 500-znakových příspěvcích. Odpovězte na vlákna a boostujte příspěvky od kohokoliv, abyste mohli sdílet skvělé věci. Najděte nové účty pro sledování a populární hashtagy pro rozšíření vaší sítě.
|
||||||
|
|
||||||
|
Mastodon je postaven se zaměřením na soukromí a bezpečnost. Rozhodněte, zda jsou vaše příspěvky sdíleny se vašimi sledujícími, jen s lidmi, které zmíníte, nebo s celým světem. Upozornění na obsah vám umožní skrýt příspěvky obsahující citlivý nebo spouštěcí materiál, dokud se s nimi nezačnete zabývat. Každá komunita má vlastní pokyny a moderátory, aby udržela své členy v bezpečí, a robustní blokování a nahlašovací nástroje pomáhácí předcházení zneužití.
|
||||||
|
|
||||||
|
Více funkcí:
|
||||||
|
|
||||||
|
• Tmavý režim: Čtěte příspěvky ve světlém, tmavém nebo pravém černém režimu
|
||||||
|
• Ankety: Požádejte sledující o jejich názor a sečtěte jejich hlasy
|
||||||
|
• Objevit: Populární hashtagy a účty jsou pryč na jedno klepnutí
|
||||||
|
• Oznámení: Dostávejte oznámení o nových sledujících, odpovědích a boostech
|
||||||
|
• Sdílení: Odesílání přímo do Mastodonu z libovolného seznamu sdílení v jakékoliv aplikaci
|
||||||
|
• Roztomilost: Naším maskotem je roztomilý slon, kterého čas od času uvidíte
|
||||||
|
|
||||||
|
Mastodon je registrovaný neziskový projekt a vývojový program je podporován přímo vašimi dary. Neexistuje žádná reklama, žádná monetizace a žádný rizikový kapitál a máme v plánu to udržet.
|
||||||
16
fastlane/metadata/android/de-DE/full_description.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
Mastodon ist das größte dezentralisierte soziale Netzwerk im Internet. Statt einer einzigen Webseite ist es ein Netzwerk von Millionen von Benutzer*innen in unabhängigen Gemeinschaften, die alle miteinander interagieren können. Egal, was du magst, auf Mastodon kannst du begeisterte Menschen treffen, die darüber schreiben!
|
||||||
|
|
||||||
|
Tritt einer Gemeinschaft bei und erstelle dein Profil. Finde und folge faszinierenden Leuten und lies ihre Beiträge in einer werbefreien, chronologischen Zeitachse. Drücke dich mit eigenen Emojis, Bildern, GIFs, Videos und Klängen in 500-Zeichen-Beiträgen aus. Antworte auf Themen und teile Beiträge von anderen, um tolle Dinge zu verbreiten. Finde neue Konten zum Folgen und angesagte Hashtags, um dein Netzwerk zu erweitern.
|
||||||
|
|
||||||
|
Mastodon wurde mit einem Schwerpunkt auf Privatsphäre und Sicherheit gebaut. Entscheide, ob du deine Beiträge mit deinen Followern, nur mit den Menschen, die du erwähnst, oder mit der ganzen Welt teilen möchtest. Mit Inhaltswarnungen kannst du Beiträge mit sensiblem oder bedenklichen Inhalten ausblenden, bis du bereit bist, dich damit auseinanderzusetzen. Jede Gemeinschaft hat ihre eigenen Regeln und Moderator*innen, um die Sicherheit ihrer Mitglieder zu gewährleisten, sowie robuste Sperr- und Meldewerkzeuge, um Missbrauch vorzubeugen.
|
||||||
|
|
||||||
|
Weitere Funktionen:
|
||||||
|
|
||||||
|
• Dunkler Modus: Beiträge im hellen, dunklen oder schwarzen Modus lesen
|
||||||
|
• Umfragen: frage deine Follower nach ihrer Meinung und zähle die Stimmen
|
||||||
|
• Entdecken: trendende Hashtags und Profile sind nur einen Fingertipp entfernt
|
||||||
|
• Benachrichtigungen: erhalte Benachrichtigungen über neue Follower, Antworten und geteilte Beiträge
|
||||||
|
• Teilen: veröffentliche auf Mastodon aus jeder beliebigen anderen App
|
||||||
|
• Niedlichkeit: unser Maskottchen ist ein entzückender Elefant und du wirst ihn von Zeit zu Zeit auftauchen sehen
|
||||||
|
|
||||||
|
Mastodon ist eine eingetragene gemeinnützige Organisation und die Entwicklung wird direkt durch deine Spenden unterstützt. Es gibt keine Werbung, keine Monetarisierung und kein Risikokapital und so soll es auch bleiben.
|
||||||
16
fastlane/metadata/android/fil-PH/full_description.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
Mastodon is the largest decentralized social network on the internet. Instead of a single website, it’s a network of millions of users in independent communities that can all interact with one another, seamlessly. No matter what you’re into, you can meet passionate people posting about it on Mastodon!
|
||||||
|
|
||||||
|
Join a community and create your profile. Find and and follow fascinating folks and read their posts in an ad-free, chronological timeline. Express yourself with custom emoji, images, GIFs, videos, and audio in 500-character posts. Reply to threads and reblog posts from anyone to share great stuff. Find new accounts to follow and trending hashtags to expand your network.
|
||||||
|
|
||||||
|
Mastodon is built with a focus on privacy and safety. Decide whether your posts are shared with your followers, just the people you mention, or the whole world. Content warnings let you hide posts containing sensitive or triggering material until you're ready to engage with them. Each community has its own guidelines and moderators to keep its members safe, and robust blocking and reporting tools help prevent abuse.
|
||||||
|
|
||||||
|
More features:
|
||||||
|
|
||||||
|
• Dark Mode: Read posts in light, dark, or true black mode
|
||||||
|
• Polls: Ask followers for their opinion and tally the votes
|
||||||
|
• Explore: Trending hashtags and accounts are a tap away
|
||||||
|
• Notifications: Get notified about new follows, replies, and reblogs
|
||||||
|
• Sharing: Post directly to Mastodon from any share sheet in any app
|
||||||
|
• Cuteness: Our mascot is an adorable elephant, and you'll see them pop up from time to time
|
||||||
|
|
||||||
|
Mastodon is a registered nonprofit and development is supported directly by your donations. There’s no advertising, no monetization, and no venture capital, and we plan to keep it that way.
|
||||||
1
fastlane/metadata/android/fil-PH/short_description.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Decentralized social network
|
||||||
1
fastlane/metadata/android/fil-PH/title.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Mastodon
|
||||||
16
fastlane/metadata/android/hu-HU/full_description.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
A Mastodon a legnagyobb decentralizált közösségi hálózat az interneten. Egyetlen weboldal helyett, ez több millió felhasználóból álló, független közösségek hálózata, amelyek egymással kapcsolatba tudnak lépni, zökkenőmentesen. Nem számít, mi a hobbid, a Mastodonon találkozhatsz róla posztoló lelkes emberekkel!
|
||||||
|
|
||||||
|
Csatlakozz egy közösséghez és készítsd el a profilodat. Keress és kövess lenyűgöző embereket, és olvasd egy reklámmentes, kronologikus idővonalon a bejegyzéseiket. Fejezd ki magad egyedi hangulatjelekkel, képekkel, GIFekkel, videókkal és hanggal, 500 karakter hosszúságú posztokban. Reply to threads and reblog posts from anyone to share great stuff. Fedezz fel új fiókokat amiket követhetsz és felkapott hashtageket, hogy bővíthesd a kapcsolataidat.
|
||||||
|
|
||||||
|
A Mastodon az adatvédelemre és a biztonságra összpontosítva épült. Döntsd el, hogy a posztjaidat csak a követőiddel, csak azokkal akiket megemlítesz, vagy az egész világgal osztod meg. Content warnings let you hide posts containing sensitive or triggering material until you're ready to engage with them. Each community has its own guidelines and moderators to keep its members safe, and robust blocking and reporting tools help prevent abuse.
|
||||||
|
|
||||||
|
More features:
|
||||||
|
|
||||||
|
• Dark Mode: Read posts in light, dark, or true black mode
|
||||||
|
• Polls: Ask followers for their opinion and tally the votes
|
||||||
|
• Explore: Trending hashtags and accounts are a tap away
|
||||||
|
• Notifications: Get notified about new follows, replies, and reblogs
|
||||||
|
• Sharing: Post directly to Mastodon from any share sheet in any app
|
||||||
|
• Cuteness: Our mascot is an adorable elephant, and you'll see them pop up from time to time
|
||||||
|
|
||||||
|
Mastodon is a registered nonprofit and development is supported directly by your donations. There’s no advertising, no monetization, and no venture capital, and we plan to keep it that way.
|
||||||
1
fastlane/metadata/android/hu-HU/short_description.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Decentralizált szociális hálózat
|
||||||
1
fastlane/metadata/android/hu-HU/title.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Mastodon
|
||||||
BIN
img/f-droid-badge.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
@@ -9,8 +9,8 @@ android {
|
|||||||
applicationId "org.joinmastodon.android.moshinda"
|
applicationId "org.joinmastodon.android.moshinda"
|
||||||
minSdk 23
|
minSdk 23
|
||||||
targetSdk 33
|
targetSdk 33
|
||||||
versionCode 54
|
versionCode 62
|
||||||
versionName "1.1.4+fork.54.moshinda"
|
versionName "1.1.4+fork.62.moshinda"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
resConfigs "en", "ar-rSA", "bs-rBA", "ca-rES", "cs-rCZ", "de-rDE", "el-rGR", "es-rES",
|
resConfigs "en", "ar-rSA", "bs-rBA", "ca-rES", "cs-rCZ", "de-rDE", "el-rGR", "es-rES",
|
||||||
"eu-rES", "fi-rFI", "fr-rFR", "gl-rES", "hr-rHR", "hy-rAM", "it-rIT", "iw-rIL",
|
"eu-rES", "fi-rFI", "fr-rFR", "gl-rES", "hr-rHR", "hy-rAM", "it-rIT", "iw-rIL",
|
||||||
@@ -32,9 +32,11 @@ android {
|
|||||||
githubRelease{
|
githubRelease{
|
||||||
initWith release
|
initWith release
|
||||||
}
|
}
|
||||||
noFederatedRelease{
|
playRelease{
|
||||||
initWith release
|
initWith release
|
||||||
versionNameSuffix '-nofederated'
|
minifyEnabled true
|
||||||
|
shrinkResources true
|
||||||
|
versionNameSuffix '-play'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
<action android:name="android.intent.action.VIEW"/>
|
<action android:name="android.intent.action.VIEW"/>
|
||||||
<category android:name="android.intent.category.BROWSABLE"/>
|
<category android:name="android.intent.category.BROWSABLE"/>
|
||||||
<category android:name="android.intent.category.DEFAULT"/>
|
<category android:name="android.intent.category.DEFAULT"/>
|
||||||
<data android:scheme="megalodon-android-auth" android:host="callback"/>
|
<data android:scheme="moshidon-android-auth" android:host="callback"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".ExternalShareActivity" android:exported="true" android:configChanges="orientation|screenSize" android:windowSoftInputMode="adjustResize">
|
<activity android:name=".ExternalShareActivity" android:exported="true" android:configChanges="orientation|screenSize" android:windowSoftInputMode="adjustResize">
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 358 KiB After Width: | Height: | Size: 15 KiB |
@@ -51,7 +51,10 @@ public class ExternalShareActivity extends FragmentStackActivity{
|
|||||||
getWindow().setBackgroundDrawable(null);
|
getWindow().setBackgroundDrawable(null);
|
||||||
|
|
||||||
Intent intent=getIntent();
|
Intent intent=getIntent();
|
||||||
String text=intent.getStringExtra(Intent.EXTRA_TEXT);
|
StringBuilder builder=new StringBuilder();
|
||||||
|
if (intent.hasExtra(Intent.EXTRA_SUBJECT)) builder.append(intent.getStringExtra(Intent.EXTRA_SUBJECT)).append("\n");
|
||||||
|
if (intent.hasExtra(Intent.EXTRA_TEXT)) builder.append(intent.getStringExtra(Intent.EXTRA_TEXT)).append("\n");
|
||||||
|
String text=builder.toString();
|
||||||
List<Uri> mediaUris;
|
List<Uri> mediaUris;
|
||||||
if(Intent.ACTION_SEND.equals(intent.getAction())){
|
if(Intent.ACTION_SEND.equals(intent.getAction())){
|
||||||
Uri singleUri=intent.getParcelableExtra(Intent.EXTRA_STREAM);
|
Uri singleUri=intent.getParcelableExtra(Intent.EXTRA_STREAM);
|
||||||
|
|||||||
@@ -10,9 +10,11 @@ public class GlobalUserPreferences{
|
|||||||
public static boolean showReplies;
|
public static boolean showReplies;
|
||||||
public static boolean showBoosts;
|
public static boolean showBoosts;
|
||||||
public static boolean loadNewPosts;
|
public static boolean loadNewPosts;
|
||||||
|
public static boolean showFederatedTimeline;
|
||||||
public static boolean showInteractionCounts;
|
public static boolean showInteractionCounts;
|
||||||
public static boolean alwaysExpandContentWarnings;
|
public static boolean alwaysExpandContentWarnings;
|
||||||
public static boolean disableMarquee;
|
public static boolean disableMarquee;
|
||||||
|
public static boolean voteButtonForSingleChoice;
|
||||||
public static ThemePreference theme;
|
public static ThemePreference theme;
|
||||||
public static ColorPreference color;
|
public static ColorPreference color;
|
||||||
|
|
||||||
@@ -28,9 +30,11 @@ public class GlobalUserPreferences{
|
|||||||
showReplies=prefs.getBoolean("showReplies", true);
|
showReplies=prefs.getBoolean("showReplies", true);
|
||||||
showBoosts=prefs.getBoolean("showBoosts", true);
|
showBoosts=prefs.getBoolean("showBoosts", true);
|
||||||
loadNewPosts=prefs.getBoolean("loadNewPosts", true);
|
loadNewPosts=prefs.getBoolean("loadNewPosts", true);
|
||||||
|
showFederatedTimeline=prefs.getBoolean("showFederatedTimeline", !BuildConfig.BUILD_TYPE.equals("playRelease"));
|
||||||
showInteractionCounts=prefs.getBoolean("showInteractionCounts", false);
|
showInteractionCounts=prefs.getBoolean("showInteractionCounts", false);
|
||||||
alwaysExpandContentWarnings=prefs.getBoolean("alwaysExpandContentWarnings", false);
|
alwaysExpandContentWarnings=prefs.getBoolean("alwaysExpandContentWarnings", false);
|
||||||
disableMarquee=prefs.getBoolean("disableMarquee", false);
|
disableMarquee=prefs.getBoolean("disableMarquee", false);
|
||||||
|
voteButtonForSingleChoice=prefs.getBoolean("voteButtonForSingleChoice", true);
|
||||||
theme=ThemePreference.values()[prefs.getInt("theme", 0)];
|
theme=ThemePreference.values()[prefs.getInt("theme", 0)];
|
||||||
color=ColorPreference.values()[prefs.getInt("color", 1)];
|
color=ColorPreference.values()[prefs.getInt("color", 1)];
|
||||||
}
|
}
|
||||||
@@ -42,6 +46,7 @@ public class GlobalUserPreferences{
|
|||||||
.putBoolean("showReplies", showReplies)
|
.putBoolean("showReplies", showReplies)
|
||||||
.putBoolean("showBoosts", showBoosts)
|
.putBoolean("showBoosts", showBoosts)
|
||||||
.putBoolean("loadNewPosts", loadNewPosts)
|
.putBoolean("loadNewPosts", loadNewPosts)
|
||||||
|
.putBoolean("showFederatedTimeline", showFederatedTimeline)
|
||||||
.putBoolean("trueBlackTheme", trueBlackTheme)
|
.putBoolean("trueBlackTheme", trueBlackTheme)
|
||||||
.putBoolean("showInteractionCounts", showInteractionCounts)
|
.putBoolean("showInteractionCounts", showInteractionCounts)
|
||||||
.putBoolean("alwaysExpandContentWarnings", alwaysExpandContentWarnings)
|
.putBoolean("alwaysExpandContentWarnings", alwaysExpandContentWarnings)
|
||||||
@@ -57,7 +62,8 @@ public class GlobalUserPreferences{
|
|||||||
GREEN,
|
GREEN,
|
||||||
BLUE,
|
BLUE,
|
||||||
ORANGE,
|
ORANGE,
|
||||||
YELLOW
|
YELLOW,
|
||||||
|
MATERIAL3
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ThemePreference{
|
public enum ThemePreference{
|
||||||
@@ -66,4 +72,3 @@ public class GlobalUserPreferences{
|
|||||||
DARK
|
DARK
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ public class PushNotificationReceiver extends BroadcastReceiver{
|
|||||||
.setShowWhen(true)
|
.setShowWhen(true)
|
||||||
.setCategory(Notification.CATEGORY_SOCIAL)
|
.setCategory(Notification.CATEGORY_SOCIAL)
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
.setColor(context.getColor(R.color.primary_700));
|
.setColor(context.getColor(R.color.shortcut_icon_background));
|
||||||
if(avatar!=null){
|
if(avatar!=null){
|
||||||
builder.setLargeIcon(UiUtils.getBitmapFromDrawable(avatar));
|
builder.setLargeIcon(UiUtils.getBitmapFromDrawable(avatar));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ public class CreateOAuthApp extends MastodonAPIRequest<Application>{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class Request{
|
private static class Request{
|
||||||
public String clientName="Megalodon";
|
public String clientName="Moshidon";
|
||||||
public String redirectUris=AccountSessionManager.REDIRECT_URI;
|
public String redirectUris=AccountSessionManager.REDIRECT_URI;
|
||||||
public String scopes=AccountSessionManager.SCOPE;
|
public String scopes=AccountSessionManager.SCOPE;
|
||||||
public String website="https://sk22.github.io/megalodon";
|
public String website="https://github.com/LucasGGamerM/moshidon";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package org.joinmastodon.android.api.requests.statuses;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.api.AllFieldsAreRequired;
|
||||||
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
|
import org.joinmastodon.android.model.BaseModel;
|
||||||
|
import org.joinmastodon.android.model.Status;
|
||||||
|
import org.joinmastodon.android.model.StatusTranslation;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public class GetStatusTranslation extends MastodonAPIRequest<StatusTranslation>{
|
||||||
|
public GetStatusTranslation(String id){
|
||||||
|
super(HttpMethod.POST, "/statuses/"+id+"/translate", StatusTranslation.class);
|
||||||
|
Request r = new Request();
|
||||||
|
setRequestBody(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Request{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -61,7 +61,7 @@ import me.grishka.appkit.api.ErrorResponse;
|
|||||||
public class AccountSessionManager{
|
public class AccountSessionManager{
|
||||||
private static final String TAG="AccountSessionManager";
|
private static final String TAG="AccountSessionManager";
|
||||||
public static final String SCOPE="read write follow push";
|
public static final String SCOPE="read write follow push";
|
||||||
public static final String REDIRECT_URI="megalodon-android-auth://callback";
|
public static final String REDIRECT_URI="moshidon-android-auth://callback";
|
||||||
|
|
||||||
private static final AccountSessionManager instance=new AccountSessionManager();
|
private static final AccountSessionManager instance=new AccountSessionManager();
|
||||||
|
|
||||||
@@ -211,7 +211,7 @@ public class AccountSessionManager{
|
|||||||
.path("/oauth/authorize")
|
.path("/oauth/authorize")
|
||||||
.appendQueryParameter("response_type", "code")
|
.appendQueryParameter("response_type", "code")
|
||||||
.appendQueryParameter("client_id", result.clientId)
|
.appendQueryParameter("client_id", result.clientId)
|
||||||
.appendQueryParameter("redirect_uri", "megalodon-android-auth://callback")
|
.appendQueryParameter("redirect_uri", "moshidon-android-auth://callback")
|
||||||
.appendQueryParameter("scope", SCOPE)
|
.appendQueryParameter("scope", SCOPE)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|||||||
@@ -400,10 +400,12 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
|||||||
public void onPollOptionClick(PollOptionStatusDisplayItem.Holder holder){
|
public void onPollOptionClick(PollOptionStatusDisplayItem.Holder holder){
|
||||||
Poll poll=holder.getItem().poll;
|
Poll poll=holder.getItem().poll;
|
||||||
Poll.Option option=holder.getItem().option;
|
Poll.Option option=holder.getItem().option;
|
||||||
if(poll.multiple){
|
if(poll.multiple || GlobalUserPreferences.voteButtonForSingleChoice){
|
||||||
if(poll.selectedOptions==null)
|
if(poll.selectedOptions==null)
|
||||||
poll.selectedOptions=new ArrayList<>();
|
poll.selectedOptions=new ArrayList<>();
|
||||||
if(poll.selectedOptions.contains(option)){
|
boolean optionContained=poll.selectedOptions.contains(option);
|
||||||
|
if(!poll.multiple) poll.selectedOptions.clear();
|
||||||
|
if(optionContained){
|
||||||
poll.selectedOptions.remove(option);
|
poll.selectedOptions.remove(option);
|
||||||
holder.itemView.setSelected(false);
|
holder.itemView.setSelected(false);
|
||||||
}else{
|
}else{
|
||||||
@@ -412,6 +414,9 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
|||||||
}
|
}
|
||||||
for(int i=0;i<list.getChildCount();i++){
|
for(int i=0;i<list.getChildCount();i++){
|
||||||
RecyclerView.ViewHolder vh=list.getChildViewHolder(list.getChildAt(i));
|
RecyclerView.ViewHolder vh=list.getChildViewHolder(list.getChildAt(i));
|
||||||
|
if(!poll.multiple && vh instanceof PollOptionStatusDisplayItem.Holder item){
|
||||||
|
if (item != holder) item.itemView.setSelected(false);
|
||||||
|
}
|
||||||
if(vh instanceof PollFooterStatusDisplayItem.Holder footer){
|
if(vh instanceof PollFooterStatusDisplayItem.Holder footer){
|
||||||
if(footer.getItemID().equals(holder.getItemID())){
|
if(footer.getItemID().equals(holder.getItemID())){
|
||||||
footer.rebind();
|
footer.rebind();
|
||||||
@@ -457,6 +462,21 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
|||||||
Status status=holder.getItem().status;
|
Status status=holder.getItem().status;
|
||||||
revealSpoiler(status, holder.getItemID());
|
revealSpoiler(status, holder.getItemID());
|
||||||
}
|
}
|
||||||
|
public void onRevealTranslationClick(HeaderStatusDisplayItem.Holder holder){
|
||||||
|
Status status=holder.getItem().status;
|
||||||
|
revealTranslation(status, holder.getItemID());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void revealTranslation(Status status, String itemID){
|
||||||
|
status.wantsTranslation=!status.wantsTranslation;
|
||||||
|
TextStatusDisplayItem.Holder text=findHolderOfType(itemID, TextStatusDisplayItem.Holder.class);
|
||||||
|
if(text!=null)
|
||||||
|
adapter.notifyItemChanged(text.getAbsoluteAdapterPosition()-getMainAdapterOffset());
|
||||||
|
HeaderStatusDisplayItem.Holder header=findHolderOfType(itemID, HeaderStatusDisplayItem.Holder.class);
|
||||||
|
if(header!=null)
|
||||||
|
header.rebind();
|
||||||
|
updateImagesSpoilerState(status, itemID);
|
||||||
|
}
|
||||||
|
|
||||||
protected void revealSpoiler(Status status, String itemID){
|
protected void revealSpoiler(Status status, String itemID){
|
||||||
status.spoilerRevealed=true;
|
status.spoilerRevealed=true;
|
||||||
|
|||||||
@@ -487,7 +487,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||||||
replyText.setText(getString(R.string.in_reply_to, replyTo.account.displayName));
|
replyText.setText(getString(R.string.in_reply_to, replyTo.account.displayName));
|
||||||
int visibilityNameRes = switch (statusVisibility) {
|
int visibilityNameRes = switch (statusVisibility) {
|
||||||
case PUBLIC -> R.string.visibility_public;
|
case PUBLIC -> R.string.visibility_public;
|
||||||
case UNLISTED -> R.string.visibility_unlisted;
|
case UNLISTED -> R.string.sk_visibility_unlisted;
|
||||||
case PRIVATE -> R.string.visibility_followers_only;
|
case PRIVATE -> R.string.visibility_followers_only;
|
||||||
case DIRECT -> R.string.visibility_private;
|
case DIRECT -> R.string.visibility_private;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public class FollowRequestsListFragment extends BaseRecyclerFragment<FollowReque
|
|||||||
@Override
|
@Override
|
||||||
public void onAttach(Activity activity) {
|
public void onAttach(Activity activity) {
|
||||||
super.onAttach(activity);
|
super.onAttach(activity);
|
||||||
setTitle(R.string.follow_requests);
|
setTitle(R.string.sk_follow_requests);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
|
|||||||
public void onCreate(Bundle savedInstanceState){
|
public void onCreate(Bundle savedInstanceState){
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
accountID=getArguments().getString("account");
|
accountID=getArguments().getString("account");
|
||||||
setTitle(R.string.app_name);
|
setTitle(R.string.sk_app_name);
|
||||||
|
|
||||||
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N)
|
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N)
|
||||||
setRetainInstance(true);
|
setRetainInstance(true);
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ public class ListTimelinesFragment extends BaseRecyclerFragment<ListTimeline> im
|
|||||||
if(args.containsKey("profileAccount")){
|
if(args.containsKey("profileAccount")){
|
||||||
profileAccountId=args.getString("profileAccount");
|
profileAccountId=args.getString("profileAccount");
|
||||||
profileDisplayUsername=args.getString("profileDisplayUsername");
|
profileDisplayUsername=args.getString("profileDisplayUsername");
|
||||||
setTitle(getString(R.string.lists_with_user, profileDisplayUsername));
|
setTitle(getString(R.string.sk_lists_with_user, profileDisplayUsername));
|
||||||
// setHasOptionsMenu(true);
|
// setHasOptionsMenu(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -249,7 +249,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
|||||||
tab.setText(switch(position){
|
tab.setText(switch(position){
|
||||||
case 0 -> R.string.posts;
|
case 0 -> R.string.posts;
|
||||||
case 1 -> R.string.posts_and_replies;
|
case 1 -> R.string.posts_and_replies;
|
||||||
case 2 -> R.string.pinned_posts;
|
case 2 -> R.string.sk_pinned_posts;
|
||||||
case 3 -> R.string.media;
|
case 3 -> R.string.media;
|
||||||
case 4 -> R.string.profile_about;
|
case 4 -> R.string.profile_about;
|
||||||
default -> throw new IllegalStateException();
|
default -> throw new IllegalStateException();
|
||||||
@@ -555,11 +555,14 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
|||||||
menu.findItem(R.id.mute).setTitle(getString(relationship.muting ? R.string.unmute_user : R.string.mute_user, account.getDisplayUsername()));
|
menu.findItem(R.id.mute).setTitle(getString(relationship.muting ? R.string.unmute_user : R.string.mute_user, account.getDisplayUsername()));
|
||||||
menu.findItem(R.id.block).setTitle(getString(relationship.blocking ? R.string.unblock_user : R.string.block_user, account.getDisplayUsername()));
|
menu.findItem(R.id.block).setTitle(getString(relationship.blocking ? R.string.unblock_user : R.string.block_user, account.getDisplayUsername()));
|
||||||
menu.findItem(R.id.report).setTitle(getString(R.string.report_user, account.getDisplayUsername()));
|
menu.findItem(R.id.report).setTitle(getString(R.string.report_user, account.getDisplayUsername()));
|
||||||
|
MenuItem manageUserLists=menu.findItem(R.id.manage_user_lists);
|
||||||
if(relationship.following) {
|
if(relationship.following) {
|
||||||
menu.findItem(R.id.hide_boosts).setTitle(getString(relationship.showingReblogs ? R.string.hide_boosts_from_user : R.string.show_boosts_from_user, account.getDisplayUsername()));
|
menu.findItem(R.id.hide_boosts).setTitle(getString(relationship.showingReblogs ? R.string.hide_boosts_from_user : R.string.show_boosts_from_user, account.getDisplayUsername()));
|
||||||
|
manageUserLists.setTitle(getString(R.string.sk_lists_with_user, account.getDisplayUsername()));
|
||||||
|
manageUserLists.setVisible(true);
|
||||||
}else {
|
}else {
|
||||||
menu.findItem(R.id.hide_boosts).setVisible(false);
|
menu.findItem(R.id.hide_boosts).setVisible(false);
|
||||||
menu.findItem(R.id.manage_user_lists).setVisible(false);
|
manageUserLists.setVisible(false);
|
||||||
}
|
}
|
||||||
if(!account.isLocal())
|
if(!account.isLocal())
|
||||||
menu.findItem(R.id.block_domain).setTitle(getString(relationship.domainBlocking ? R.string.unblock_domain : R.string.block_domain, account.getDomain()));
|
menu.findItem(R.id.block_domain).setTitle(getString(relationship.domainBlocking ? R.string.unblock_domain : R.string.block_domain, account.getDomain()));
|
||||||
@@ -658,7 +661,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
|||||||
notifyProgress.setIndeterminateTintList(notifyButton.getTextColors());
|
notifyProgress.setIndeterminateTintList(notifyButton.getTextColors());
|
||||||
followsYouView.setVisibility(relationship.followedBy ? View.VISIBLE : View.GONE);
|
followsYouView.setVisibility(relationship.followedBy ? View.VISIBLE : View.GONE);
|
||||||
notifyButton.setSelected(relationship.notifying);
|
notifyButton.setSelected(relationship.notifying);
|
||||||
if (getActivity() != null) notifyButton.setContentDescription(getString(relationship.notifying ? R.string.user_post_notifications_on : R.string.user_post_notifications_off, '@'+account.username));
|
if (getActivity() != null) notifyButton.setContentDescription(getString(relationship.notifying ? R.string.sk_user_post_notifications_on : R.string.sk_user_post_notifications_off, '@'+account.username));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onScrollChanged(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY){
|
private void onScrollChanged(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY){
|
||||||
|
|||||||
@@ -9,14 +9,12 @@ import android.graphics.Canvas;
|
|||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.provider.Settings;
|
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.WindowInsets;
|
import android.view.WindowInsets;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.view.animation.AlphaAnimation;
|
|
||||||
import android.view.animation.LinearInterpolator;
|
import android.view.animation.LinearInterpolator;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
@@ -71,6 +69,7 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
|||||||
private NotificationPolicyItem notificationPolicyItem;
|
private NotificationPolicyItem notificationPolicyItem;
|
||||||
private String accountID;
|
private String accountID;
|
||||||
private boolean needUpdateNotificationSettings;
|
private boolean needUpdateNotificationSettings;
|
||||||
|
private boolean needAppRestart;
|
||||||
private PushSubscription pushSubscription;
|
private PushSubscription pushSubscription;
|
||||||
|
|
||||||
private ImageView themeTransitionWindowView;
|
private ImageView themeTransitionWindowView;
|
||||||
@@ -111,7 +110,7 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
|||||||
GlobalUserPreferences.useCustomTabs=i.checked;
|
GlobalUserPreferences.useCustomTabs=i.checked;
|
||||||
GlobalUserPreferences.save();
|
GlobalUserPreferences.save();
|
||||||
}));
|
}));
|
||||||
items.add(new SwitchItem(R.string.settings_show_interaction_counts, R.drawable.ic_fluent_number_row_24_regular, GlobalUserPreferences.showInteractionCounts, i->{
|
items.add(new SwitchItem(R.string.sk_settings_show_interaction_counts, R.drawable.ic_fluent_number_row_24_regular, GlobalUserPreferences.showInteractionCounts, i->{
|
||||||
GlobalUserPreferences.showInteractionCounts=i.checked;
|
GlobalUserPreferences.showInteractionCounts=i.checked;
|
||||||
GlobalUserPreferences.save();
|
GlobalUserPreferences.save();
|
||||||
}));
|
}));
|
||||||
@@ -121,18 +120,23 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
items.add(new HeaderItem(R.string.home_timeline));
|
items.add(new HeaderItem(R.string.home_timeline));
|
||||||
items.add(new SwitchItem(R.string.settings_show_replies, R.drawable.ic_fluent_chat_multiple_24_regular, GlobalUserPreferences.showReplies, i->{
|
items.add(new SwitchItem(R.string.sk_settings_show_replies, R.drawable.ic_fluent_chat_multiple_24_regular, GlobalUserPreferences.showReplies, i->{
|
||||||
GlobalUserPreferences.showReplies=i.checked;
|
GlobalUserPreferences.showReplies=i.checked;
|
||||||
GlobalUserPreferences.save();
|
GlobalUserPreferences.save();
|
||||||
}));
|
}));
|
||||||
items.add(new SwitchItem(R.string.settings_show_boosts, R.drawable.ic_fluent_arrow_repeat_all_24_regular, GlobalUserPreferences.showBoosts, i->{
|
items.add(new SwitchItem(R.string.sk_settings_show_boosts, R.drawable.ic_fluent_arrow_repeat_all_24_regular, GlobalUserPreferences.showBoosts, i->{
|
||||||
GlobalUserPreferences.showBoosts=i.checked;
|
GlobalUserPreferences.showBoosts=i.checked;
|
||||||
GlobalUserPreferences.save();
|
GlobalUserPreferences.save();
|
||||||
}));
|
}));
|
||||||
items.add(new SwitchItem(R.string.settings_load_new_posts, R.drawable.ic_fluent_arrow_up_24_regular, GlobalUserPreferences.loadNewPosts, i->{
|
items.add(new SwitchItem(R.string.sk_settings_load_new_posts, R.drawable.ic_fluent_arrow_up_24_regular, GlobalUserPreferences.loadNewPosts, i->{
|
||||||
GlobalUserPreferences.loadNewPosts=i.checked;
|
GlobalUserPreferences.loadNewPosts=i.checked;
|
||||||
GlobalUserPreferences.save();
|
GlobalUserPreferences.save();
|
||||||
}));
|
}));
|
||||||
|
items.add(new SwitchItem(R.string.sk_settings_show_federated_timeline, R.drawable.ic_fluent_earth_24_regular, GlobalUserPreferences.showFederatedTimeline, i->{
|
||||||
|
GlobalUserPreferences.showFederatedTimeline=i.checked;
|
||||||
|
GlobalUserPreferences.save();
|
||||||
|
needAppRestart=true;
|
||||||
|
}));
|
||||||
|
|
||||||
items.add(new HeaderItem(R.string.settings_notifications));
|
items.add(new HeaderItem(R.string.settings_notifications));
|
||||||
items.add(notificationPolicyItem=new NotificationPolicyItem());
|
items.add(notificationPolicyItem=new NotificationPolicyItem());
|
||||||
@@ -141,6 +145,7 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
|||||||
items.add(new SwitchItem(R.string.notify_follow, R.drawable.ic_fluent_person_add_24_regular, pushSubscription.alerts.follow, i->onNotificationsChanged(PushNotification.Type.FOLLOW, i.checked)));
|
items.add(new SwitchItem(R.string.notify_follow, R.drawable.ic_fluent_person_add_24_regular, pushSubscription.alerts.follow, i->onNotificationsChanged(PushNotification.Type.FOLLOW, i.checked)));
|
||||||
items.add(new SwitchItem(R.string.notify_reblog, R.drawable.ic_fluent_arrow_repeat_all_24_regular, pushSubscription.alerts.reblog, i->onNotificationsChanged(PushNotification.Type.REBLOG, i.checked)));
|
items.add(new SwitchItem(R.string.notify_reblog, R.drawable.ic_fluent_arrow_repeat_all_24_regular, pushSubscription.alerts.reblog, i->onNotificationsChanged(PushNotification.Type.REBLOG, i.checked)));
|
||||||
items.add(new SwitchItem(R.string.notify_mention, R.drawable.ic_at_symbol, pushSubscription.alerts.mention, i->onNotificationsChanged(PushNotification.Type.MENTION, i.checked)));
|
items.add(new SwitchItem(R.string.notify_mention, R.drawable.ic_at_symbol, pushSubscription.alerts.mention, i->onNotificationsChanged(PushNotification.Type.MENTION, i.checked)));
|
||||||
|
items.add(new SwitchItem(R.string.sk_notify_posts, R.drawable.ic_fluent_alert_24_regular, pushSubscription.alerts.status, i->onNotificationsChanged(PushNotification.Type.STATUS, i.checked)));
|
||||||
|
|
||||||
items.add(new HeaderItem(R.string.settings_boring));
|
items.add(new HeaderItem(R.string.settings_boring));
|
||||||
items.add(new TextItem(R.string.settings_account, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/auth/edit")));
|
items.add(new TextItem(R.string.settings_account, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/auth/edit")));
|
||||||
@@ -149,10 +154,10 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
|||||||
|
|
||||||
items.add(new RedHeaderItem(R.string.settings_spicy));
|
items.add(new RedHeaderItem(R.string.settings_spicy));
|
||||||
if (GithubSelfUpdater.needSelfUpdating()) {
|
if (GithubSelfUpdater.needSelfUpdating()) {
|
||||||
checkForUpdateItem = new TextItem(R.string.check_for_update, GithubSelfUpdater.getInstance()::checkForUpdates);
|
checkForUpdateItem = new TextItem(R.string.sk_check_for_update, GithubSelfUpdater.getInstance()::checkForUpdates);
|
||||||
items.add(checkForUpdateItem);
|
items.add(checkForUpdateItem);
|
||||||
}
|
}
|
||||||
items.add(new TextItem(R.string.settings_contribute_fork, ()->UiUtils.launchWebBrowser(getActivity(), "https://github.com/LucasGGamerM/moshidon")));
|
items.add(new TextItem(R.string.settings_contribute_fork, ()->UiUtils.launchWebBrowser(getActivity(), "https://github.com/sk22/megalodon")));
|
||||||
items.add(new TextItem(R.string.settings_clear_cache, this::clearImageCache));
|
items.add(new TextItem(R.string.settings_clear_cache, this::clearImageCache));
|
||||||
items.add(new TextItem(R.string.log_out, this::confirmLogOut));
|
items.add(new TextItem(R.string.log_out, this::confirmLogOut));
|
||||||
|
|
||||||
@@ -204,6 +209,11 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
|||||||
if(needUpdateNotificationSettings && PushSubscriptionManager.arePushNotificationsAvailable()){
|
if(needUpdateNotificationSettings && PushSubscriptionManager.arePushNotificationsAvailable()){
|
||||||
AccountSessionManager.getInstance().getAccount(accountID).getPushSubscriptionManager().updatePushSettings(pushSubscription);
|
AccountSessionManager.getInstance().getAccount(accountID).getPushSubscriptionManager().updatePushSettings(pushSubscription);
|
||||||
}
|
}
|
||||||
|
if(needAppRestart){
|
||||||
|
Intent intent = Intent.makeRestartActivityTask(MastodonApp.context.getPackageManager().getLaunchIntentForPackage(MastodonApp.context.getPackageName()).getComponent());
|
||||||
|
MastodonApp.context.startActivity(intent);
|
||||||
|
Runtime.getRuntime().exit(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -227,6 +237,7 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void onColorPreferenceClick(GlobalUserPreferences.ColorPreference color){
|
private void onColorPreferenceClick(GlobalUserPreferences.ColorPreference color){
|
||||||
|
|
||||||
GlobalUserPreferences.color=color;
|
GlobalUserPreferences.color=color;
|
||||||
GlobalUserPreferences.save();
|
GlobalUserPreferences.save();
|
||||||
restartActivityToApplyNewTheme();
|
restartActivityToApplyNewTheme();
|
||||||
@@ -291,6 +302,7 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
|||||||
case FOLLOW -> subscription.alerts.follow=enabled;
|
case FOLLOW -> subscription.alerts.follow=enabled;
|
||||||
case REBLOG -> subscription.alerts.reblog=enabled;
|
case REBLOG -> subscription.alerts.reblog=enabled;
|
||||||
case MENTION -> subscription.alerts.mention=subscription.alerts.poll=enabled;
|
case MENTION -> subscription.alerts.mention=subscription.alerts.poll=enabled;
|
||||||
|
case STATUS -> subscription.alerts.status=enabled;
|
||||||
}
|
}
|
||||||
needUpdateNotificationSettings=true;
|
needUpdateNotificationSettings=true;
|
||||||
}
|
}
|
||||||
@@ -385,7 +397,7 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ev.state == GithubSelfUpdater.UpdateState.NO_UPDATE) {
|
if (ev.state == GithubSelfUpdater.UpdateState.NO_UPDATE) {
|
||||||
Toast.makeText(getActivity(), R.string.no_update_available, Toast.LENGTH_SHORT).show();
|
Toast.makeText(getActivity(), R.string.sk_no_update_available, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -693,6 +705,15 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
|||||||
pref = GlobalUserPreferences.ColorPreference.YELLOW;
|
pref = GlobalUserPreferences.ColorPreference.YELLOW;
|
||||||
onColorPreferenceClick(pref);
|
onColorPreferenceClick(pref);
|
||||||
}
|
}
|
||||||
|
else if(id==R.id.m3_color) {
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
pref = GlobalUserPreferences.ColorPreference.MATERIAL3;
|
||||||
|
onColorPreferenceClick(pref);
|
||||||
|
}else{
|
||||||
|
Toast.makeText(getActivity(), R.string.sk_not_supported,
|
||||||
|
Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
@@ -706,12 +727,13 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
|||||||
public void onBind(ColorPicker item){
|
public void onBind(ColorPicker item){
|
||||||
icon.setImageResource(R.drawable.ic_color_theme_preference);
|
icon.setImageResource(R.drawable.ic_color_theme_preference);
|
||||||
button.setText(switch(GlobalUserPreferences.color){
|
button.setText(switch(GlobalUserPreferences.color){
|
||||||
case PINK -> R.string.pink_color;
|
case PINK -> R.string.sk_color_theme_pink;
|
||||||
case PURPLE -> R.string.purple_color;
|
case PURPLE -> R.string.sk_color_theme_purple;
|
||||||
case GREEN -> R.string.green_color;
|
case GREEN -> R.string.sk_color_theme_green;
|
||||||
case BLUE -> R.string.blue_color;
|
case BLUE -> R.string.sk_color_theme_blue;
|
||||||
case ORANGE -> R.string.orange_color;
|
case ORANGE -> R.string.sk_color_theme_brown;
|
||||||
case YELLOW -> R.string.yellow_color;
|
case YELLOW -> R.string.sk_color_theme_yellow;
|
||||||
|
case MATERIAL3 -> R.string.sk_color_theme_material_you;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package org.joinmastodon.android.fragments;
|
package org.joinmastodon.android.fragments;
|
||||||
|
|
||||||
import android.content.res.Configuration;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -10,7 +9,8 @@ import android.view.WindowInsets;
|
|||||||
|
|
||||||
import org.joinmastodon.android.MastodonApp;
|
import org.joinmastodon.android.MastodonApp;
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
import org.joinmastodon.android.fragments.onboarding.InstanceCatalogFragment;
|
import org.joinmastodon.android.fragments.onboarding.InstanceCatalogSignupFragment;
|
||||||
|
import org.joinmastodon.android.fragments.onboarding.InstanceChooserLoginFragment;
|
||||||
import org.joinmastodon.android.ui.InterpolatingMotionEffect;
|
import org.joinmastodon.android.ui.InterpolatingMotionEffect;
|
||||||
import org.joinmastodon.android.ui.views.SizeListenerFrameLayout;
|
import org.joinmastodon.android.ui.views.SizeListenerFrameLayout;
|
||||||
|
|
||||||
@@ -66,8 +66,9 @@ public class SplashFragment extends AppKitFragment{
|
|||||||
|
|
||||||
private void onButtonClick(View v){
|
private void onButtonClick(View v){
|
||||||
Bundle extras=new Bundle();
|
Bundle extras=new Bundle();
|
||||||
extras.putBoolean("signup", v.getId()==R.id.btn_get_started);
|
boolean isSignup=v.getId()==R.id.btn_get_started;
|
||||||
Nav.go(getActivity(), InstanceCatalogFragment.class, extras);
|
extras.putBoolean("signup", isSignup);
|
||||||
|
Nav.go(getActivity(), isSignup ? InstanceCatalogSignupFragment.class : InstanceChooserLoginFragment.class, extras);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateArtSize(int w, int h){
|
private void updateArtSize(int w, int h){
|
||||||
|
|||||||
@@ -286,13 +286,16 @@ public abstract class BaseAccountListFragment extends BaseRecyclerFragment<BaseA
|
|||||||
menu.findItem(R.id.mute).setTitle(getString(relationship.muting ? R.string.unmute_user : R.string.mute_user, account.getDisplayUsername()));
|
menu.findItem(R.id.mute).setTitle(getString(relationship.muting ? R.string.unmute_user : R.string.mute_user, account.getDisplayUsername()));
|
||||||
menu.findItem(R.id.block).setTitle(getString(relationship.blocking ? R.string.unblock_user : R.string.block_user, account.getDisplayUsername()));
|
menu.findItem(R.id.block).setTitle(getString(relationship.blocking ? R.string.unblock_user : R.string.block_user, account.getDisplayUsername()));
|
||||||
menu.findItem(R.id.report).setTitle(getString(R.string.report_user, account.getDisplayUsername()));
|
menu.findItem(R.id.report).setTitle(getString(R.string.report_user, account.getDisplayUsername()));
|
||||||
menu.findItem(R.id.manage_user_lists).setTitle(getString(R.string.lists_with_user, account.getDisplayUsername()));
|
|
||||||
MenuItem hideBoosts=menu.findItem(R.id.hide_boosts);
|
MenuItem hideBoosts=menu.findItem(R.id.hide_boosts);
|
||||||
|
MenuItem manageUserLists=menu.findItem(R.id.manage_user_lists);
|
||||||
if(relationship.following){
|
if(relationship.following){
|
||||||
hideBoosts.setTitle(getString(relationship.showingReblogs ? R.string.hide_boosts_from_user : R.string.show_boosts_from_user, account.getDisplayUsername()));
|
hideBoosts.setTitle(getString(relationship.showingReblogs ? R.string.hide_boosts_from_user : R.string.show_boosts_from_user, account.getDisplayUsername()));
|
||||||
hideBoosts.setVisible(true);
|
hideBoosts.setVisible(true);
|
||||||
|
manageUserLists.setTitle(getString(R.string.sk_lists_with_user, account.getDisplayUsername()));
|
||||||
|
manageUserLists.setVisible(true);
|
||||||
}else{
|
}else{
|
||||||
hideBoosts.setVisible(false);
|
hideBoosts.setVisible(false);
|
||||||
|
manageUserLists.setVisible(true);
|
||||||
}
|
}
|
||||||
MenuItem blockDomain=menu.findItem(R.id.block_domain);
|
MenuItem blockDomain=menu.findItem(R.id.block_domain);
|
||||||
if(!account.isLocal()){
|
if(!account.isLocal()){
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import android.widget.ProgressBar;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.joinmastodon.android.BuildConfig;
|
import org.joinmastodon.android.BuildConfig;
|
||||||
|
import org.joinmastodon.android.GlobalUserPreferences;
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
import org.joinmastodon.android.fragments.ScrollableToTop;
|
import org.joinmastodon.android.fragments.ScrollableToTop;
|
||||||
import org.joinmastodon.android.fragments.ListTimelinesFragment;
|
import org.joinmastodon.android.fragments.ListTimelinesFragment;
|
||||||
@@ -61,7 +62,7 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
|||||||
private String accountID;
|
private String accountID;
|
||||||
private Runnable searchDebouncer=this::onSearchChangedDebounced;
|
private Runnable searchDebouncer=this::onSearchChangedDebounced;
|
||||||
|
|
||||||
private static final boolean noFederated = BuildConfig.BUILD_TYPE.equals("noFederatedRelease");
|
private final boolean noFederated = !GlobalUserPreferences.showFederatedTimeline;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState){
|
public void onCreate(Bundle savedInstanceState){
|
||||||
@@ -163,12 +164,12 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
|||||||
if (noFederated && position > 0) position++;
|
if (noFederated && position > 0) position++;
|
||||||
tab.setText(switch(position){
|
tab.setText(switch(position){
|
||||||
case 0 -> R.string.local_timeline;
|
case 0 -> R.string.local_timeline;
|
||||||
case 1 -> R.string.federated_timeline;
|
case 1 -> R.string.sk_federated_timeline;
|
||||||
case 2 -> R.string.hashtags;
|
case 2 -> R.string.hashtags;
|
||||||
case 3 -> R.string.posts;
|
case 3 -> R.string.posts;
|
||||||
case 4 -> R.string.news;
|
case 4 -> R.string.news;
|
||||||
case 5 -> R.string.for_you;
|
case 5 -> R.string.for_you;
|
||||||
case 6 -> R.string.list_timelines;
|
case 6 -> R.string.sk_list_timelines;
|
||||||
default -> throw new IllegalStateException("Unexpected value: "+position);
|
default -> throw new IllegalStateException("Unexpected value: "+position);
|
||||||
});
|
});
|
||||||
tab.view.textView.setAllCaps(true);
|
tab.view.textView.setAllCaps(true);
|
||||||
|
|||||||
@@ -2,46 +2,30 @@ package org.joinmastodon.android.fragments.onboarding;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.content.Context;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.LocaleList;
|
import android.os.LocaleList;
|
||||||
import android.text.Editable;
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.TextWatcher;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.WindowInsets;
|
import android.view.WindowInsets;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.RadioButton;
|
import android.widget.RadioButton;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
import org.joinmastodon.android.api.MastodonAPIController;
|
import org.joinmastodon.android.api.MastodonAPIController;
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
|
||||||
import org.joinmastodon.android.api.MastodonErrorResponse;
|
import org.joinmastodon.android.api.MastodonErrorResponse;
|
||||||
import org.joinmastodon.android.api.requests.instance.GetInstance;
|
import org.joinmastodon.android.api.requests.instance.GetInstance;
|
||||||
import org.joinmastodon.android.api.requests.catalog.GetCatalogCategories;
|
|
||||||
import org.joinmastodon.android.api.requests.catalog.GetCatalogInstances;
|
|
||||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
|
||||||
import org.joinmastodon.android.model.Instance;
|
import org.joinmastodon.android.model.Instance;
|
||||||
import org.joinmastodon.android.model.catalog.CatalogCategory;
|
|
||||||
import org.joinmastodon.android.model.catalog.CatalogInstance;
|
import org.joinmastodon.android.model.catalog.CatalogInstance;
|
||||||
import org.joinmastodon.android.ui.BetterItemAnimator;
|
|
||||||
import org.joinmastodon.android.ui.DividerItemDecoration;
|
|
||||||
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||||
import org.joinmastodon.android.ui.tabs.TabLayout;
|
|
||||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
import org.parceler.Parcels;
|
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
import org.xml.sax.InputSource;
|
import org.xml.sax.InputSource;
|
||||||
|
|
||||||
@@ -59,49 +43,42 @@ import java.util.stream.Collectors;
|
|||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.recyclerview.widget.DiffUtil;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import me.grishka.appkit.Nav;
|
|
||||||
import me.grishka.appkit.api.Callback;
|
import me.grishka.appkit.api.Callback;
|
||||||
import me.grishka.appkit.api.ErrorResponse;
|
import me.grishka.appkit.api.ErrorResponse;
|
||||||
import me.grishka.appkit.fragments.BaseRecyclerFragment;
|
import me.grishka.appkit.fragments.BaseRecyclerFragment;
|
||||||
import me.grishka.appkit.utils.BindableViewHolder;
|
import me.grishka.appkit.utils.BindableViewHolder;
|
||||||
import me.grishka.appkit.utils.MergeRecyclerAdapter;
|
import me.grishka.appkit.utils.MergeRecyclerAdapter;
|
||||||
import me.grishka.appkit.utils.SingleViewRecyclerAdapter;
|
|
||||||
import me.grishka.appkit.utils.V;
|
import me.grishka.appkit.utils.V;
|
||||||
import me.grishka.appkit.views.UsableRecyclerView;
|
import me.grishka.appkit.views.UsableRecyclerView;
|
||||||
import okhttp3.Call;
|
import okhttp3.Call;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
|
|
||||||
public class InstanceCatalogFragment extends BaseRecyclerFragment<CatalogInstance>{
|
abstract class InstanceCatalogFragment extends BaseRecyclerFragment<CatalogInstance>{
|
||||||
private InstancesAdapter adapter;
|
protected RecyclerView.Adapter adapter;
|
||||||
private MergeRecyclerAdapter mergeAdapter;
|
protected MergeRecyclerAdapter mergeAdapter;
|
||||||
private View headerView;
|
protected CatalogInstance chosenInstance;
|
||||||
private CatalogInstance chosenInstance;
|
protected Button nextButton;
|
||||||
private List<CatalogInstance> filteredData=new ArrayList<>();
|
protected EditText searchEdit;
|
||||||
private Button nextButton;
|
protected Runnable searchDebouncer=this::onSearchChangedDebounced;
|
||||||
private MastodonAPIRequest<?> getCategoriesRequest;
|
protected String currentSearchQuery;
|
||||||
private EditText searchEdit;
|
protected String loadingInstanceDomain;
|
||||||
private TabLayout categoriesList;
|
protected HashMap<String, Instance> instancesCache=new HashMap<>();
|
||||||
private Runnable searchDebouncer=this::onSearchChangedDebounced;
|
protected View buttonBar;
|
||||||
private String currentSearchQuery;
|
protected List<CatalogInstance> filteredData=new ArrayList<>();
|
||||||
private String currentCategory="all";
|
protected GetInstance loadingInstanceRequest;
|
||||||
private List<CatalogCategory> categories=new ArrayList<>();
|
protected Call loadingInstanceRedirectRequest;
|
||||||
private String loadingInstanceDomain;
|
protected ProgressDialog instanceProgressDialog;
|
||||||
private GetInstance loadingInstanceRequest;
|
protected HashMap<String, String> redirects=new HashMap<>();
|
||||||
private Call loadingInstanceRedirectRequest;
|
protected HashMap<String, String> redirectsInverse=new HashMap<>();
|
||||||
private HashMap<String, Instance> instancesCache=new HashMap<>();
|
protected boolean isSignup;
|
||||||
private ProgressDialog instanceProgressDialog;
|
protected CatalogInstance fakeInstance=new CatalogInstance();
|
||||||
private View buttonBar;
|
|
||||||
private HashMap<String, String> redirects=new HashMap<>(), redirectsInverse=new HashMap<>();
|
|
||||||
|
|
||||||
private boolean isSignup;
|
|
||||||
|
|
||||||
private static final double DUNBAR=Math.log(800);
|
private static final double DUNBAR=Math.log(800);
|
||||||
|
|
||||||
public InstanceCatalogFragment(){
|
public InstanceCatalogFragment(int layout, int perPage){
|
||||||
super(R.layout.fragment_onboarding_common, 10);
|
super(layout, perPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -110,21 +87,31 @@ public class InstanceCatalogFragment extends BaseRecyclerFragment<CatalogInstanc
|
|||||||
isSignup=getArguments().getBoolean("signup");
|
isSignup=getArguments().getBoolean("signup");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected abstract void proceedWithAuthOrSignup(Instance instance);
|
||||||
public void onAttach(Context context){
|
|
||||||
super.onAttach(context);
|
protected boolean onSearchEnterPressed(TextView v, int actionId, KeyEvent event){
|
||||||
setRefreshEnabled(false);
|
if(event!=null && event.getAction()!=KeyEvent.ACTION_DOWN)
|
||||||
loadData();
|
return true;
|
||||||
|
currentSearchQuery=searchEdit.getText().toString().toLowerCase();
|
||||||
|
updateFilteredList();
|
||||||
|
searchEdit.removeCallbacks(searchDebouncer);
|
||||||
|
Instance instance=instancesCache.get(normalizeInstanceDomain(currentSearchQuery));
|
||||||
|
if(instance==null){
|
||||||
|
showProgressDialog();
|
||||||
|
loadInstanceInfo(currentSearchQuery, false);
|
||||||
|
}else{
|
||||||
|
proceedWithAuthOrSignup(instance);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected void onSearchChangedDebounced(){
|
||||||
protected void doLoadData(int offset, int count){
|
currentSearchQuery=searchEdit.getText().toString().toLowerCase();
|
||||||
currentRequest=new GetCatalogInstances(null, null)
|
updateFilteredList();
|
||||||
.setCallback(new Callback<>(){
|
loadInstanceInfo(currentSearchQuery, false);
|
||||||
@Override
|
}
|
||||||
public void onSuccess(List<CatalogInstance> result){
|
|
||||||
if(getActivity()==null)
|
protected List<CatalogInstance> sortInstances(List<CatalogInstance> result){
|
||||||
return;
|
|
||||||
Map<String, List<CatalogInstance>> byLang=result.stream().collect(Collectors.groupingBy(ci->ci.language));
|
Map<String, List<CatalogInstance>> byLang=result.stream().collect(Collectors.groupingBy(ci->ci.language));
|
||||||
for(List<CatalogInstance> group:byLang.values()){
|
for(List<CatalogInstance> group:byLang.values()){
|
||||||
Collections.sort(group, (a, b)->{
|
Collections.sort(group, (a, b)->{
|
||||||
@@ -165,280 +152,26 @@ public class InstanceCatalogFragment extends BaseRecyclerFragment<CatalogInstanc
|
|||||||
}
|
}
|
||||||
return group;
|
return group;
|
||||||
}).sorted(Comparator.comparingInt((InstanceGroup g)->g.activeUsers).reversed()).forEachOrdered(ig->sortedList.addAll(ig.instances));
|
}).sorted(Comparator.comparingInt((InstanceGroup g)->g.activeUsers).reversed()).forEachOrdered(ig->sortedList.addAll(ig.instances));
|
||||||
onDataLoaded(sortedList, false);
|
return sortedList;
|
||||||
updateFilteredList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected abstract void updateFilteredList();
|
||||||
public void onError(ErrorResponse error){
|
|
||||||
error.showToast(getActivity());
|
|
||||||
onDataLoaded(Collections.emptyList(), false);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.execNoAuth("");
|
|
||||||
getCategoriesRequest=new GetCatalogCategories(null)
|
|
||||||
.setCallback(new Callback<>(){
|
|
||||||
@Override
|
|
||||||
public void onSuccess(List<CatalogCategory> result){
|
|
||||||
getCategoriesRequest=null;
|
|
||||||
CatalogCategory all=new CatalogCategory();
|
|
||||||
all.category="all";
|
|
||||||
categories.add(all);
|
|
||||||
result.stream().sorted(Comparator.comparingInt((CatalogCategory cc)->cc.serversCount).reversed()).forEach(categories::add);
|
|
||||||
updateCategories();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
protected void showProgressDialog(){
|
||||||
public void onError(ErrorResponse error){
|
|
||||||
getCategoriesRequest=null;
|
|
||||||
error.showToast(getActivity());
|
|
||||||
CatalogCategory all=new CatalogCategory();
|
|
||||||
all.category="all";
|
|
||||||
categories.add(all);
|
|
||||||
updateCategories();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.execNoAuth("");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateCategories(){
|
|
||||||
categoriesList.removeAllTabs();
|
|
||||||
for(CatalogCategory cat:categories){
|
|
||||||
int titleRes=getTitleForCategory(cat.category);
|
|
||||||
TabLayout.Tab tab=categoriesList.newTab().setText(titleRes!=0 ? getString(titleRes) : cat.category).setCustomView(R.layout.item_instance_category);
|
|
||||||
ImageView emoji=tab.getCustomView().findViewById(R.id.emoji);
|
|
||||||
emoji.setImageResource(getEmojiForCategory(cat.category));
|
|
||||||
categoriesList.addTab(tab);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy(){
|
|
||||||
super.onDestroy();
|
|
||||||
if(getCategoriesRequest!=null)
|
|
||||||
getCategoriesRequest.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected RecyclerView.Adapter getAdapter(){
|
|
||||||
headerView=getActivity().getLayoutInflater().inflate(R.layout.header_onboarding_instance_catalog, list, false);
|
|
||||||
searchEdit=headerView.findViewById(R.id.search_edit);
|
|
||||||
categoriesList=headerView.findViewById(R.id.categories_list);
|
|
||||||
categoriesList.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener(){
|
|
||||||
@Override
|
|
||||||
public void onTabSelected(TabLayout.Tab tab){
|
|
||||||
CatalogCategory category=categories.get(tab.getPosition());
|
|
||||||
currentCategory=category.category;
|
|
||||||
updateFilteredList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTabUnselected(TabLayout.Tab tab){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTabReselected(TabLayout.Tab tab){
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
searchEdit.setOnEditorActionListener(this::onSearchEnterPressed);
|
|
||||||
searchEdit.addTextChangedListener(new TextWatcher(){
|
|
||||||
@Override
|
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count){
|
|
||||||
searchEdit.removeCallbacks(searchDebouncer);
|
|
||||||
searchEdit.postDelayed(searchDebouncer, 300);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterTextChanged(Editable s){
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mergeAdapter=new MergeRecyclerAdapter();
|
|
||||||
mergeAdapter.addAdapter(new SingleViewRecyclerAdapter(headerView));
|
|
||||||
mergeAdapter.addAdapter(adapter=new InstancesAdapter());
|
|
||||||
return mergeAdapter;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onViewCreated(View view, Bundle savedInstanceState){
|
|
||||||
super.onViewCreated(view, savedInstanceState);
|
|
||||||
nextButton=view.findViewById(R.id.btn_next);
|
|
||||||
nextButton.setOnClickListener(this::onNextClick);
|
|
||||||
nextButton.setEnabled(chosenInstance!=null);
|
|
||||||
view.findViewById(R.id.btn_back).setOnClickListener(v->Nav.finish(this));
|
|
||||||
list.setItemAnimator(new BetterItemAnimator());
|
|
||||||
list.addItemDecoration(new DividerItemDecoration(getActivity(), R.attr.colorPollVoted, 1, 16, 16, DividerItemDecoration.NOT_FIRST));
|
|
||||||
view.setBackgroundColor(UiUtils.getThemeColor(getActivity(), R.attr.colorBackgroundLight));
|
|
||||||
buttonBar=view.findViewById(R.id.button_bar);
|
|
||||||
setStatusBarColor(UiUtils.getThemeColor(getActivity(), R.attr.colorBackgroundLight));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onNextClick(View v){
|
|
||||||
String domain=chosenInstance.domain;
|
|
||||||
Instance instance=instancesCache.get(domain);
|
|
||||||
if(instance!=null){
|
|
||||||
proceedWithAuthOrSignup(instance);
|
|
||||||
}else{
|
|
||||||
showProgressDialog();
|
|
||||||
if(!domain.equals(loadingInstanceDomain)){
|
|
||||||
loadInstanceInfo(domain, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void proceedWithAuthOrSignup(Instance instance){
|
|
||||||
getActivity().getSystemService(InputMethodManager.class).hideSoftInputFromWindow(contentView.getWindowToken(), 0);
|
|
||||||
if(isSignup){
|
|
||||||
if(!instance.registrations){
|
|
||||||
new M3AlertDialogBuilder(getActivity())
|
|
||||||
.setTitle(R.string.error)
|
|
||||||
.setMessage(R.string.instance_signup_closed)
|
|
||||||
.setPositiveButton(R.string.ok, null)
|
|
||||||
.show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Bundle args=new Bundle();
|
|
||||||
args.putParcelable("instance", Parcels.wrap(instance));
|
|
||||||
Nav.go(getActivity(), InstanceRulesFragment.class, args);
|
|
||||||
}else{
|
|
||||||
AccountSessionManager.getInstance().authenticate(getActivity(), instance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// private String getEmojiForCategory(String category){
|
|
||||||
// return switch(category){
|
|
||||||
// case "all" -> "💬";
|
|
||||||
// case "academia" -> "📚";
|
|
||||||
// case "activism" -> "✊";
|
|
||||||
// case "food" -> "🍕";
|
|
||||||
// case "furry" -> "🦁";
|
|
||||||
// case "games" -> "🕹";
|
|
||||||
// case "general" -> "🐘";
|
|
||||||
// case "journalism" -> "📰";
|
|
||||||
// case "lgbt" -> "🏳️🌈";
|
|
||||||
// case "regional" -> "📍";
|
|
||||||
// case "art" -> "🎨";
|
|
||||||
// case "music" -> "🎼";
|
|
||||||
// case "tech" -> "📱";
|
|
||||||
// default -> "❓";
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
private int getEmojiForCategory(String category){
|
|
||||||
return switch(category){
|
|
||||||
case "all" -> R.drawable.ic_category_all;
|
|
||||||
case "academia" -> R.drawable.ic_category_academia;
|
|
||||||
case "activism" -> R.drawable.ic_category_activism;
|
|
||||||
case "food" -> R.drawable.ic_category_food;
|
|
||||||
case "furry" -> R.drawable.ic_category_furry;
|
|
||||||
case "games" -> R.drawable.ic_category_games;
|
|
||||||
case "general" -> R.drawable.ic_category_general;
|
|
||||||
case "journalism" -> R.drawable.ic_category_journalism;
|
|
||||||
case "lgbt" -> R.drawable.ic_category_lgbt;
|
|
||||||
case "regional" -> R.drawable.ic_category_regional;
|
|
||||||
case "art" -> R.drawable.ic_category_art;
|
|
||||||
case "music" -> R.drawable.ic_category_music;
|
|
||||||
case "tech" -> R.drawable.ic_category_tech;
|
|
||||||
default -> R.drawable.ic_category_unknown;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getTitleForCategory(String category){
|
|
||||||
return switch(category){
|
|
||||||
case "all" -> R.string.category_all;
|
|
||||||
case "academia" -> R.string.category_academia;
|
|
||||||
case "activism" -> R.string.category_activism;
|
|
||||||
case "food" -> R.string.category_food;
|
|
||||||
case "furry" -> R.string.category_furry;
|
|
||||||
case "games" -> R.string.category_games;
|
|
||||||
case "general" -> R.string.category_general;
|
|
||||||
case "journalism" -> R.string.category_journalism;
|
|
||||||
case "lgbt" -> R.string.category_lgbt;
|
|
||||||
case "regional" -> R.string.category_regional;
|
|
||||||
case "art" -> R.string.category_art;
|
|
||||||
case "music" -> R.string.category_music;
|
|
||||||
case "tech" -> R.string.category_tech;
|
|
||||||
default -> 0;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean onSearchEnterPressed(TextView v, int actionId, KeyEvent event){
|
|
||||||
if(event!=null && event.getAction()!=KeyEvent.ACTION_DOWN)
|
|
||||||
return true;
|
|
||||||
currentSearchQuery=searchEdit.getText().toString().toLowerCase();
|
|
||||||
updateFilteredList();
|
|
||||||
searchEdit.removeCallbacks(searchDebouncer);
|
|
||||||
Instance instance=instancesCache.get(normalizeInstanceDomain(currentSearchQuery));
|
|
||||||
if(instance==null){
|
|
||||||
showProgressDialog();
|
|
||||||
loadInstanceInfo(currentSearchQuery, false);
|
|
||||||
}else{
|
|
||||||
proceedWithAuthOrSignup(instance);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onSearchChangedDebounced(){
|
|
||||||
currentSearchQuery=searchEdit.getText().toString().toLowerCase();
|
|
||||||
updateFilteredList();
|
|
||||||
loadInstanceInfo(currentSearchQuery, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateFilteredList(){
|
|
||||||
ArrayList<CatalogInstance> prevData=new ArrayList<>(filteredData);
|
|
||||||
filteredData.clear();
|
|
||||||
for(CatalogInstance instance:data){
|
|
||||||
if(currentCategory.equals("all") || instance.categories.contains(currentCategory)){
|
|
||||||
if(TextUtils.isEmpty(currentSearchQuery) || instance.domain.contains(currentSearchQuery)){
|
|
||||||
if(instance.domain.equals(currentSearchQuery) || !isSignup || !instance.approvalRequired)
|
|
||||||
filteredData.add(instance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DiffUtil.calculateDiff(new DiffUtil.Callback(){
|
|
||||||
@Override
|
|
||||||
public int getOldListSize(){
|
|
||||||
return prevData.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getNewListSize(){
|
|
||||||
return filteredData.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition){
|
|
||||||
return prevData.get(oldItemPosition)==filteredData.get(newItemPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition){
|
|
||||||
return prevData.get(oldItemPosition)==filteredData.get(newItemPosition);
|
|
||||||
}
|
|
||||||
}).dispatchUpdatesTo(adapter);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showProgressDialog(){
|
|
||||||
instanceProgressDialog=new ProgressDialog(getActivity());
|
instanceProgressDialog=new ProgressDialog(getActivity());
|
||||||
instanceProgressDialog.setMessage(getString(R.string.loading_instance));
|
instanceProgressDialog.setMessage(getString(R.string.loading_instance));
|
||||||
instanceProgressDialog.setOnCancelListener(dialog->cancelLoadingInstanceInfo());
|
instanceProgressDialog.setOnCancelListener(dialog->cancelLoadingInstanceInfo());
|
||||||
instanceProgressDialog.show();
|
instanceProgressDialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String normalizeInstanceDomain(String _domain){
|
protected String normalizeInstanceDomain(String _domain){
|
||||||
if(TextUtils.isEmpty(_domain))
|
if(TextUtils.isEmpty(_domain))
|
||||||
return null;
|
return null;
|
||||||
if(_domain.contains(":")){
|
if(_domain.contains(":")){
|
||||||
try{
|
try{
|
||||||
_domain=Uri.parse(_domain).getAuthority();
|
_domain=Uri.parse(_domain).getAuthority();
|
||||||
}catch(Exception ignore){}
|
}catch(Exception ignore){
|
||||||
|
}
|
||||||
if(TextUtils.isEmpty(_domain))
|
if(TextUtils.isEmpty(_domain))
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -453,12 +186,12 @@ public class InstanceCatalogFragment extends BaseRecyclerFragment<CatalogInstanc
|
|||||||
return domain;
|
return domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadInstanceInfo(String _domain, boolean isFromRedirect){
|
protected void loadInstanceInfo(String _domain, boolean isFromRedirect){
|
||||||
String domain=normalizeInstanceDomain(_domain);
|
String domain=normalizeInstanceDomain(_domain);
|
||||||
Instance cachedInstance=instancesCache.get(domain);
|
Instance cachedInstance=instancesCache.get(domain);
|
||||||
if(cachedInstance!=null){
|
if(cachedInstance!=null){
|
||||||
for(CatalogInstance ci : filteredData){
|
for(CatalogInstance ci : filteredData){
|
||||||
if(ci.domain.equals(domain))
|
if(ci.domain.equals(domain) && ci!=fakeInstance)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CatalogInstance ci=cachedInstance.toCatalogInstance();
|
CatalogInstance ci=cachedInstance.toCatalogInstance();
|
||||||
@@ -490,18 +223,23 @@ public class InstanceCatalogFragment extends BaseRecyclerFragment<CatalogInstanc
|
|||||||
if(Objects.equals(domain, currentSearchQuery) || Objects.equals(currentSearchQuery, redirects.get(domain)) || Objects.equals(currentSearchQuery, redirectsInverse.get(domain))){
|
if(Objects.equals(domain, currentSearchQuery) || Objects.equals(currentSearchQuery, redirects.get(domain)) || Objects.equals(currentSearchQuery, redirectsInverse.get(domain))){
|
||||||
boolean found=false;
|
boolean found=false;
|
||||||
for(CatalogInstance ci : filteredData){
|
for(CatalogInstance ci : filteredData){
|
||||||
if(ci.domain.equals(domain)){
|
if(ci.domain.equals(domain) && ci!=fakeInstance){
|
||||||
found=true;
|
found=true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!found){
|
if(!found){
|
||||||
CatalogInstance ci=result.toCatalogInstance();
|
CatalogInstance ci=result.toCatalogInstance();
|
||||||
|
if(filteredData.size()==1 && filteredData.get(0)==fakeInstance){
|
||||||
|
filteredData.set(0, ci);
|
||||||
|
adapter.notifyItemChanged(0);
|
||||||
|
}else{
|
||||||
filteredData.add(0, ci);
|
filteredData.add(0, ci);
|
||||||
adapter.notifyItemInserted(0);
|
adapter.notifyItemInserted(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(ErrorResponse error){
|
public void onError(ErrorResponse error){
|
||||||
@@ -512,6 +250,14 @@ public class InstanceCatalogFragment extends BaseRecyclerFragment<CatalogInstanc
|
|||||||
}
|
}
|
||||||
loadingInstanceDomain=null;
|
loadingInstanceDomain=null;
|
||||||
showInstanceInfoLoadError(domain, error);
|
showInstanceInfoLoadError(domain, error);
|
||||||
|
if(fakeInstance!=null){
|
||||||
|
fakeInstance.description=getString(R.string.error);
|
||||||
|
if(filteredData.size()>0 && filteredData.get(0)==fakeInstance){
|
||||||
|
if(list.findViewHolderForAdapterPosition(1) instanceof BindableViewHolder<?> ivh){
|
||||||
|
ivh.rebind();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}).execNoAuth(domain);
|
}).execNoAuth(domain);
|
||||||
}
|
}
|
||||||
@@ -616,78 +362,26 @@ public class InstanceCatalogFragment extends BaseRecyclerFragment<CatalogInstanc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class InstancesAdapter extends UsableRecyclerView.Adapter<InstanceViewHolder>{
|
|
||||||
public InstancesAdapter(){
|
|
||||||
super(imgLoader);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
@Override
|
||||||
public InstanceViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType){
|
public void onViewCreated(View view, Bundle savedInstanceState){
|
||||||
return new InstanceViewHolder();
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
nextButton=view.findViewById(R.id.btn_next);
|
||||||
|
nextButton.setOnClickListener(this::onNextClick);
|
||||||
|
nextButton.setEnabled(chosenInstance!=null);
|
||||||
|
buttonBar=view.findViewById(R.id.button_bar);
|
||||||
|
setRefreshEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected void onNextClick(View v){
|
||||||
public void onBindViewHolder(InstanceViewHolder holder, int position){
|
String domain=chosenInstance.domain;
|
||||||
holder.bind(filteredData.get(position));
|
Instance instance=instancesCache.get(domain);
|
||||||
super.onBindViewHolder(holder, position);
|
if(instance!=null){
|
||||||
}
|
proceedWithAuthOrSignup(instance);
|
||||||
|
}else{
|
||||||
@Override
|
showProgressDialog();
|
||||||
public int getItemCount(){
|
if(!domain.equals(loadingInstanceDomain)){
|
||||||
return filteredData.size();
|
loadInstanceInfo(domain, false);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemViewType(int position){
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class InstanceViewHolder extends BindableViewHolder<CatalogInstance> implements UsableRecyclerView.Clickable{
|
|
||||||
private final TextView title, description, userCount, lang;
|
|
||||||
private final RadioButton radioButton;
|
|
||||||
|
|
||||||
public InstanceViewHolder(){
|
|
||||||
super(getActivity(), R.layout.item_instance_catalog, list);
|
|
||||||
title=findViewById(R.id.title);
|
|
||||||
description=findViewById(R.id.description);
|
|
||||||
userCount=findViewById(R.id.user_count);
|
|
||||||
lang=findViewById(R.id.lang);
|
|
||||||
radioButton=findViewById(R.id.radiobtn);
|
|
||||||
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.N){
|
|
||||||
UiUtils.fixCompoundDrawableTintOnAndroid6(userCount);
|
|
||||||
UiUtils.fixCompoundDrawableTintOnAndroid6(lang);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBind(CatalogInstance item){
|
|
||||||
title.setText(item.normalizedDomain);
|
|
||||||
description.setText(item.description);
|
|
||||||
userCount.setText(UiUtils.abbreviateNumber(item.totalUsers));
|
|
||||||
lang.setText(item.language.toUpperCase());
|
|
||||||
radioButton.setChecked(chosenInstance==item);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(){
|
|
||||||
if(chosenInstance==item)
|
|
||||||
return;
|
|
||||||
if(chosenInstance!=null){
|
|
||||||
int idx=filteredData.indexOf(chosenInstance);
|
|
||||||
if(idx!=-1){
|
|
||||||
RecyclerView.ViewHolder holder=list.findViewHolderForAdapterPosition(mergeAdapter.getPositionForAdapter(adapter)+idx);
|
|
||||||
if(holder instanceof InstanceViewHolder ivh){
|
|
||||||
ivh.radioButton.setChecked(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
radioButton.setChecked(true);
|
|
||||||
if(chosenInstance==null)
|
|
||||||
nextButton.setEnabled(true);
|
|
||||||
chosenInstance=item;
|
|
||||||
loadInstanceInfo(chosenInstance.domain, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,374 @@
|
|||||||
|
package org.joinmastodon.android.fragments.onboarding;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.LocaleList;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.text.TextWatcher;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.RadioButton;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.R;
|
||||||
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
|
import org.joinmastodon.android.api.requests.catalog.GetCatalogCategories;
|
||||||
|
import org.joinmastodon.android.api.requests.catalog.GetCatalogInstances;
|
||||||
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
|
import org.joinmastodon.android.model.Instance;
|
||||||
|
import org.joinmastodon.android.model.catalog.CatalogCategory;
|
||||||
|
import org.joinmastodon.android.model.catalog.CatalogInstance;
|
||||||
|
import org.joinmastodon.android.ui.BetterItemAnimator;
|
||||||
|
import org.joinmastodon.android.ui.DividerItemDecoration;
|
||||||
|
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||||
|
import org.joinmastodon.android.ui.tabs.TabLayout;
|
||||||
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
|
import org.parceler.Parcels;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.DiffUtil;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
import me.grishka.appkit.Nav;
|
||||||
|
import me.grishka.appkit.api.Callback;
|
||||||
|
import me.grishka.appkit.api.ErrorResponse;
|
||||||
|
import me.grishka.appkit.utils.BindableViewHolder;
|
||||||
|
import me.grishka.appkit.utils.MergeRecyclerAdapter;
|
||||||
|
import me.grishka.appkit.utils.SingleViewRecyclerAdapter;
|
||||||
|
import me.grishka.appkit.views.UsableRecyclerView;
|
||||||
|
|
||||||
|
public class InstanceCatalogSignupFragment extends InstanceCatalogFragment{
|
||||||
|
private View headerView;
|
||||||
|
private MastodonAPIRequest<?> getCategoriesRequest;
|
||||||
|
private TabLayout categoriesList;
|
||||||
|
private String currentCategory="all";
|
||||||
|
private List<CatalogCategory> categories=new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
|
public InstanceCatalogSignupFragment(){
|
||||||
|
super(R.layout.fragment_onboarding_common, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Context context){
|
||||||
|
super.onAttach(context);
|
||||||
|
setRefreshEnabled(false);
|
||||||
|
loadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doLoadData(int offset, int count){
|
||||||
|
currentRequest=new GetCatalogInstances(null, null)
|
||||||
|
.setCallback(new Callback<>(){
|
||||||
|
@Override
|
||||||
|
public void onSuccess(List<CatalogInstance> result){
|
||||||
|
if(getActivity()==null)
|
||||||
|
return;
|
||||||
|
onDataLoaded(sortInstances(result), false);
|
||||||
|
updateFilteredList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(ErrorResponse error){
|
||||||
|
error.showToast(getActivity());
|
||||||
|
onDataLoaded(Collections.emptyList(), false);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.execNoAuth("");
|
||||||
|
getCategoriesRequest=new GetCatalogCategories(null)
|
||||||
|
.setCallback(new Callback<>(){
|
||||||
|
@Override
|
||||||
|
public void onSuccess(List<CatalogCategory> result){
|
||||||
|
getCategoriesRequest=null;
|
||||||
|
CatalogCategory all=new CatalogCategory();
|
||||||
|
all.category="all";
|
||||||
|
categories.add(all);
|
||||||
|
result.stream().sorted(Comparator.comparingInt((CatalogCategory cc)->cc.serversCount).reversed()).forEach(categories::add);
|
||||||
|
updateCategories();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(ErrorResponse error){
|
||||||
|
getCategoriesRequest=null;
|
||||||
|
error.showToast(getActivity());
|
||||||
|
CatalogCategory all=new CatalogCategory();
|
||||||
|
all.category="all";
|
||||||
|
categories.add(all);
|
||||||
|
updateCategories();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.execNoAuth("");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateCategories(){
|
||||||
|
categoriesList.removeAllTabs();
|
||||||
|
for(CatalogCategory cat:categories){
|
||||||
|
int titleRes=getTitleForCategory(cat.category);
|
||||||
|
TabLayout.Tab tab=categoriesList.newTab().setText(titleRes!=0 ? getString(titleRes) : cat.category).setCustomView(R.layout.item_instance_category);
|
||||||
|
ImageView emoji=tab.getCustomView().findViewById(R.id.emoji);
|
||||||
|
emoji.setImageResource(getEmojiForCategory(cat.category));
|
||||||
|
categoriesList.addTab(tab);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy(){
|
||||||
|
super.onDestroy();
|
||||||
|
if(getCategoriesRequest!=null)
|
||||||
|
getCategoriesRequest.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RecyclerView.Adapter getAdapter(){
|
||||||
|
headerView=getActivity().getLayoutInflater().inflate(R.layout.header_onboarding_instance_catalog, list, false);
|
||||||
|
searchEdit=headerView.findViewById(R.id.search_edit);
|
||||||
|
categoriesList=headerView.findViewById(R.id.categories_list);
|
||||||
|
categoriesList.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener(){
|
||||||
|
@Override
|
||||||
|
public void onTabSelected(TabLayout.Tab tab){
|
||||||
|
CatalogCategory category=categories.get(tab.getPosition());
|
||||||
|
currentCategory=category.category;
|
||||||
|
updateFilteredList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTabUnselected(TabLayout.Tab tab){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTabReselected(TabLayout.Tab tab){
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
searchEdit.setOnEditorActionListener(this::onSearchEnterPressed);
|
||||||
|
searchEdit.addTextChangedListener(new TextWatcher(){
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count){
|
||||||
|
searchEdit.removeCallbacks(searchDebouncer);
|
||||||
|
searchEdit.postDelayed(searchDebouncer, 300);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s){
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mergeAdapter=new MergeRecyclerAdapter();
|
||||||
|
mergeAdapter.addAdapter(new SingleViewRecyclerAdapter(headerView));
|
||||||
|
mergeAdapter.addAdapter(adapter=new InstancesAdapter());
|
||||||
|
return mergeAdapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(View view, Bundle savedInstanceState){
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
view.findViewById(R.id.btn_back).setOnClickListener(v->Nav.finish(this));
|
||||||
|
list.setItemAnimator(new BetterItemAnimator());
|
||||||
|
list.addItemDecoration(new DividerItemDecoration(getActivity(), R.attr.colorPollVoted, 1, 16, 16, DividerItemDecoration.NOT_FIRST));
|
||||||
|
view.setBackgroundColor(UiUtils.getThemeColor(getActivity(), R.attr.colorBackgroundLight));
|
||||||
|
setStatusBarColor(UiUtils.getThemeColor(getActivity(), R.attr.colorBackgroundLight));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void proceedWithAuthOrSignup(Instance instance){
|
||||||
|
getActivity().getSystemService(InputMethodManager.class).hideSoftInputFromWindow(contentView.getWindowToken(), 0);
|
||||||
|
if(isSignup){
|
||||||
|
if(!instance.registrations){
|
||||||
|
new M3AlertDialogBuilder(getActivity())
|
||||||
|
.setTitle(R.string.error)
|
||||||
|
.setMessage(R.string.instance_signup_closed)
|
||||||
|
.setPositiveButton(R.string.ok, null)
|
||||||
|
.show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Bundle args=new Bundle();
|
||||||
|
args.putParcelable("instance", Parcels.wrap(instance));
|
||||||
|
Nav.go(getActivity(), InstanceRulesFragment.class, args);
|
||||||
|
}else{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// private String getEmojiForCategory(String category){
|
||||||
|
// return switch(category){
|
||||||
|
// case "all" -> "💬";
|
||||||
|
// case "academia" -> "📚";
|
||||||
|
// case "activism" -> "✊";
|
||||||
|
// case "food" -> "🍕";
|
||||||
|
// case "furry" -> "🦁";
|
||||||
|
// case "games" -> "🕹";
|
||||||
|
// case "general" -> "🐘";
|
||||||
|
// case "journalism" -> "📰";
|
||||||
|
// case "lgbt" -> "🏳️🌈";
|
||||||
|
// case "regional" -> "📍";
|
||||||
|
// case "art" -> "🎨";
|
||||||
|
// case "music" -> "🎼";
|
||||||
|
// case "tech" -> "📱";
|
||||||
|
// default -> "❓";
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
private int getEmojiForCategory(String category){
|
||||||
|
return switch(category){
|
||||||
|
case "all" -> R.drawable.ic_category_all;
|
||||||
|
case "academia" -> R.drawable.ic_category_academia;
|
||||||
|
case "activism" -> R.drawable.ic_category_activism;
|
||||||
|
case "food" -> R.drawable.ic_category_food;
|
||||||
|
case "furry" -> R.drawable.ic_category_furry;
|
||||||
|
case "games" -> R.drawable.ic_category_games;
|
||||||
|
case "general" -> R.drawable.ic_category_general;
|
||||||
|
case "journalism" -> R.drawable.ic_category_journalism;
|
||||||
|
case "lgbt" -> R.drawable.ic_category_lgbt;
|
||||||
|
case "regional" -> R.drawable.ic_category_regional;
|
||||||
|
case "art" -> R.drawable.ic_category_art;
|
||||||
|
case "music" -> R.drawable.ic_category_music;
|
||||||
|
case "tech" -> R.drawable.ic_category_tech;
|
||||||
|
default -> R.drawable.ic_category_unknown;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getTitleForCategory(String category){
|
||||||
|
return switch(category){
|
||||||
|
case "all" -> R.string.category_all;
|
||||||
|
case "academia" -> R.string.category_academia;
|
||||||
|
case "activism" -> R.string.category_activism;
|
||||||
|
case "food" -> R.string.category_food;
|
||||||
|
case "furry" -> R.string.category_furry;
|
||||||
|
case "games" -> R.string.category_games;
|
||||||
|
case "general" -> R.string.category_general;
|
||||||
|
case "journalism" -> R.string.category_journalism;
|
||||||
|
case "lgbt" -> R.string.category_lgbt;
|
||||||
|
case "regional" -> R.string.category_regional;
|
||||||
|
case "art" -> R.string.category_art;
|
||||||
|
case "music" -> R.string.category_music;
|
||||||
|
case "tech" -> R.string.category_tech;
|
||||||
|
default -> 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateFilteredList(){
|
||||||
|
ArrayList<CatalogInstance> prevData=new ArrayList<>(filteredData);
|
||||||
|
filteredData.clear();
|
||||||
|
for(CatalogInstance instance:data){
|
||||||
|
if(currentCategory.equals("all") || instance.categories.contains(currentCategory)){
|
||||||
|
if(TextUtils.isEmpty(currentSearchQuery) || instance.domain.contains(currentSearchQuery)){
|
||||||
|
if(instance.domain.equals(currentSearchQuery) || !isSignup || !instance.approvalRequired)
|
||||||
|
filteredData.add(instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DiffUtil.calculateDiff(new DiffUtil.Callback(){
|
||||||
|
@Override
|
||||||
|
public int getOldListSize(){
|
||||||
|
return prevData.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNewListSize(){
|
||||||
|
return filteredData.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition){
|
||||||
|
return prevData.get(oldItemPosition)==filteredData.get(newItemPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition){
|
||||||
|
return prevData.get(oldItemPosition)==filteredData.get(newItemPosition);
|
||||||
|
}
|
||||||
|
}).dispatchUpdatesTo(adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class InstancesAdapter extends UsableRecyclerView.Adapter<InstanceCatalogSignupFragment.InstanceViewHolder>{
|
||||||
|
public InstancesAdapter(){
|
||||||
|
super(imgLoader);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public InstanceCatalogSignupFragment.InstanceViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType){
|
||||||
|
return new InstanceCatalogSignupFragment.InstanceViewHolder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(InstanceCatalogSignupFragment.InstanceViewHolder holder, int position){
|
||||||
|
holder.bind(filteredData.get(position));
|
||||||
|
super.onBindViewHolder(holder, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount(){
|
||||||
|
return filteredData.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemViewType(int position){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class InstanceViewHolder extends BindableViewHolder<CatalogInstance> implements UsableRecyclerView.Clickable{
|
||||||
|
private final TextView title, description, userCount, lang;
|
||||||
|
private final RadioButton radioButton;
|
||||||
|
|
||||||
|
public InstanceViewHolder(){
|
||||||
|
super(getActivity(), R.layout.item_instance_catalog, list);
|
||||||
|
title=findViewById(R.id.title);
|
||||||
|
description=findViewById(R.id.description);
|
||||||
|
userCount=findViewById(R.id.user_count);
|
||||||
|
lang=findViewById(R.id.lang);
|
||||||
|
radioButton=findViewById(R.id.radiobtn);
|
||||||
|
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.N){
|
||||||
|
UiUtils.fixCompoundDrawableTintOnAndroid6(userCount);
|
||||||
|
UiUtils.fixCompoundDrawableTintOnAndroid6(lang);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBind(CatalogInstance item){
|
||||||
|
title.setText(item.normalizedDomain);
|
||||||
|
description.setText(item.description);
|
||||||
|
userCount.setText(UiUtils.abbreviateNumber(item.totalUsers));
|
||||||
|
lang.setText(item.language.toUpperCase());
|
||||||
|
radioButton.setChecked(chosenInstance==item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(){
|
||||||
|
if(chosenInstance==item)
|
||||||
|
return;
|
||||||
|
if(chosenInstance!=null){
|
||||||
|
int idx=filteredData.indexOf(chosenInstance);
|
||||||
|
if(idx!=-1){
|
||||||
|
RecyclerView.ViewHolder holder=list.findViewHolderForAdapterPosition(mergeAdapter.getPositionForAdapter(adapter)+idx);
|
||||||
|
if(holder instanceof InstanceCatalogSignupFragment.InstanceViewHolder ivh){
|
||||||
|
ivh.radioButton.setChecked(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
radioButton.setChecked(true);
|
||||||
|
if(chosenInstance==null)
|
||||||
|
nextButton.setEnabled(true);
|
||||||
|
chosenInstance=item;
|
||||||
|
loadInstanceInfo(chosenInstance.domain, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,259 @@
|
|||||||
|
package org.joinmastodon.android.fragments.onboarding;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Outline;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.TextWatcher;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.ViewOutlineProvider;
|
||||||
|
import android.widget.ImageButton;
|
||||||
|
import android.widget.RadioButton;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toolbar;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.R;
|
||||||
|
import org.joinmastodon.android.api.requests.catalog.GetCatalogInstances;
|
||||||
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
|
import org.joinmastodon.android.model.Instance;
|
||||||
|
import org.joinmastodon.android.model.catalog.CatalogInstance;
|
||||||
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
import me.grishka.appkit.api.Callback;
|
||||||
|
import me.grishka.appkit.api.ErrorResponse;
|
||||||
|
import me.grishka.appkit.utils.BindableViewHolder;
|
||||||
|
import me.grishka.appkit.utils.MergeRecyclerAdapter;
|
||||||
|
import me.grishka.appkit.utils.SingleViewRecyclerAdapter;
|
||||||
|
import me.grishka.appkit.utils.V;
|
||||||
|
import me.grishka.appkit.views.UsableRecyclerView;
|
||||||
|
|
||||||
|
public class InstanceChooserLoginFragment extends InstanceCatalogFragment{
|
||||||
|
private View headerView;
|
||||||
|
private boolean loadedAutocomplete;
|
||||||
|
private ImageButton clearBtn;
|
||||||
|
|
||||||
|
public InstanceChooserLoginFragment(){
|
||||||
|
super(R.layout.fragment_login, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState){
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
dataLoaded();
|
||||||
|
setTitle(R.string.login_title);
|
||||||
|
if(!loadedAutocomplete){
|
||||||
|
loadAutocompleteServers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void proceedWithAuthOrSignup(Instance instance){
|
||||||
|
AccountSessionManager.getInstance().authenticate(getActivity(), instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateFilteredList(){
|
||||||
|
ArrayList<CatalogInstance> prevData=new ArrayList<>(filteredData);
|
||||||
|
filteredData.clear();
|
||||||
|
if(currentSearchQuery.length()>0){
|
||||||
|
boolean foundExactMatch=false;
|
||||||
|
for(CatalogInstance inst:data){
|
||||||
|
if(inst.normalizedDomain.contains(currentSearchQuery)){
|
||||||
|
filteredData.add(inst);
|
||||||
|
if(inst.normalizedDomain.equals(currentSearchQuery))
|
||||||
|
foundExactMatch=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!foundExactMatch)
|
||||||
|
filteredData.add(0, fakeInstance);
|
||||||
|
}
|
||||||
|
UiUtils.updateList(prevData, filteredData, list, adapter, Objects::equals);
|
||||||
|
for(int i=0;i<list.getChildCount();i++){
|
||||||
|
list.getChildAt(i).invalidateOutline();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doLoadData(int offset, int count){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadAutocompleteServers(){
|
||||||
|
loadedAutocomplete=true;
|
||||||
|
new GetCatalogInstances(null, null)
|
||||||
|
.setCallback(new Callback<>(){
|
||||||
|
@Override
|
||||||
|
public void onSuccess(List<CatalogInstance> result){
|
||||||
|
data.clear();
|
||||||
|
data.addAll(sortInstances(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(ErrorResponse error){
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.execNoAuth("");
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// protected void onUpdateToolbar(){
|
||||||
|
// super.onUpdateToolbar();
|
||||||
|
// Toolbar toolbar=getToolbar();
|
||||||
|
// toolbar.setElevation(0);
|
||||||
|
// toolbar.setBackground(null);
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RecyclerView.Adapter getAdapter(){
|
||||||
|
headerView=getActivity().getLayoutInflater().inflate(R.layout.header_onboarding_login, list, false);
|
||||||
|
clearBtn=headerView.findViewById(R.id.search_clear);
|
||||||
|
searchEdit=headerView.findViewById(R.id.search_edit);
|
||||||
|
searchEdit.setOnEditorActionListener(this::onSearchEnterPressed);
|
||||||
|
searchEdit.addTextChangedListener(new TextWatcher(){
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count){
|
||||||
|
searchEdit.removeCallbacks(searchDebouncer);
|
||||||
|
searchEdit.postDelayed(searchDebouncer, 300);
|
||||||
|
|
||||||
|
if(s.length()>0){
|
||||||
|
fakeInstance.domain=fakeInstance.normalizedDomain=s.toString();
|
||||||
|
fakeInstance.description=getString(R.string.loading_instance);
|
||||||
|
if(filteredData.size()>0 && filteredData.get(0)==fakeInstance){
|
||||||
|
if(list.findViewHolderForAdapterPosition(1) instanceof InstanceViewHolder ivh){
|
||||||
|
ivh.rebind();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(filteredData.isEmpty()){
|
||||||
|
filteredData.add(fakeInstance);
|
||||||
|
adapter.notifyItemInserted(0);
|
||||||
|
}
|
||||||
|
clearBtn.setVisibility(View.VISIBLE);
|
||||||
|
}else{
|
||||||
|
clearBtn.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s){
|
||||||
|
}
|
||||||
|
});
|
||||||
|
clearBtn.setOnClickListener(v->searchEdit.setText(""));
|
||||||
|
|
||||||
|
mergeAdapter=new MergeRecyclerAdapter();
|
||||||
|
mergeAdapter.addAdapter(new SingleViewRecyclerAdapter(headerView));
|
||||||
|
mergeAdapter.addAdapter(adapter=new InstancesAdapter());
|
||||||
|
return mergeAdapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(View view, Bundle savedInstanceState){
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
setStatusBarColor(UiUtils.getThemeColor(getActivity(), R.attr.colorM3Background));
|
||||||
|
|
||||||
|
list.addItemDecoration(new RecyclerView.ItemDecoration(){
|
||||||
|
@Override
|
||||||
|
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state){
|
||||||
|
if(parent.getChildViewHolder(view) instanceof InstanceViewHolder){
|
||||||
|
outRect.left=outRect.right=V.dp(16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
((UsableRecyclerView)list).setDrawSelectorOnTop(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class InstancesAdapter extends UsableRecyclerView.Adapter<InstanceViewHolder>{
|
||||||
|
public InstancesAdapter(){
|
||||||
|
super(imgLoader);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public InstanceViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType){
|
||||||
|
return new InstanceViewHolder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(InstanceViewHolder holder, int position){
|
||||||
|
holder.bind(filteredData.get(position));
|
||||||
|
super.onBindViewHolder(holder, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount(){
|
||||||
|
return filteredData.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemViewType(int position){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class InstanceViewHolder extends BindableViewHolder<CatalogInstance> implements UsableRecyclerView.Clickable{
|
||||||
|
private final TextView title, description;
|
||||||
|
private final RadioButton radioButton;
|
||||||
|
|
||||||
|
public InstanceViewHolder(){
|
||||||
|
super(getActivity(), R.layout.item_instance_login, list);
|
||||||
|
title=findViewById(R.id.title);
|
||||||
|
description=findViewById(R.id.description);
|
||||||
|
radioButton=findViewById(R.id.radiobtn);
|
||||||
|
radioButton.setMinWidth(0);
|
||||||
|
radioButton.setMinHeight(0);
|
||||||
|
|
||||||
|
itemView.setOutlineProvider(new ViewOutlineProvider(){
|
||||||
|
@Override
|
||||||
|
public void getOutline(View view, Outline outline){
|
||||||
|
outline.setRoundRect(0, getAbsoluteAdapterPosition()==1 ? 0 : V.dp(-4), view.getWidth(), view.getHeight()+(getAbsoluteAdapterPosition()==filteredData.size() ? 0 : V.dp(4)), V.dp(4));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
itemView.setClipToOutline(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBind(CatalogInstance item){
|
||||||
|
title.setText(item.normalizedDomain);
|
||||||
|
description.setText(item.description);
|
||||||
|
radioButton.setChecked(chosenInstance==item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(){
|
||||||
|
if(chosenInstance==item)
|
||||||
|
return;
|
||||||
|
if(chosenInstance!=null){
|
||||||
|
int idx=filteredData.indexOf(chosenInstance);
|
||||||
|
if(idx!=-1){
|
||||||
|
for(int i=0;i<list.getChildCount();i++){
|
||||||
|
RecyclerView.ViewHolder holder=list.getChildViewHolder(list.getChildAt(i));
|
||||||
|
if(holder.getAbsoluteAdapterPosition()==mergeAdapter.getPositionForAdapter(adapter)+idx && holder instanceof InstanceViewHolder ivh){
|
||||||
|
ivh.radioButton.setChecked(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
radioButton.setChecked(true);
|
||||||
|
if(chosenInstance==null)
|
||||||
|
nextButton.setEnabled(true);
|
||||||
|
chosenInstance=item;
|
||||||
|
loadInstanceInfo(chosenInstance.domain, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,7 +43,9 @@ public class PushNotification extends BaseModel{
|
|||||||
@SerializedName("follow")
|
@SerializedName("follow")
|
||||||
FOLLOW(R.string.notification_type_follow),
|
FOLLOW(R.string.notification_type_follow),
|
||||||
@SerializedName("poll")
|
@SerializedName("poll")
|
||||||
POLL(R.string.notification_type_poll);
|
POLL(R.string.notification_type_poll),
|
||||||
|
@SerializedName("status")
|
||||||
|
STATUS(R.string.sk_notification_type_status);
|
||||||
|
|
||||||
@StringRes
|
@StringRes
|
||||||
public final int localizedName;
|
public final int localizedName;
|
||||||
|
|||||||
@@ -43,10 +43,11 @@ public class PushSubscription extends BaseModel implements Cloneable{
|
|||||||
public boolean reblog;
|
public boolean reblog;
|
||||||
public boolean mention;
|
public boolean mention;
|
||||||
public boolean poll;
|
public boolean poll;
|
||||||
|
public boolean status;
|
||||||
|
|
||||||
public static Alerts ofAll(){
|
public static Alerts ofAll(){
|
||||||
Alerts alerts=new Alerts();
|
Alerts alerts=new Alerts();
|
||||||
alerts.follow=alerts.favourite=alerts.reblog=alerts.mention=alerts.poll=true;
|
alerts.follow=alerts.favourite=alerts.reblog=alerts.mention=alerts.poll=alerts.status=true;
|
||||||
return alerts;
|
return alerts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,6 +59,7 @@ public class PushSubscription extends BaseModel implements Cloneable{
|
|||||||
", reblog="+reblog+
|
", reblog="+reblog+
|
||||||
", mention="+mention+
|
", mention="+mention+
|
||||||
", poll="+poll+
|
", poll="+poll+
|
||||||
|
", status="+status+
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ public class Status extends BaseModel implements DisplayItemsParent{
|
|||||||
public long favouritesCount;
|
public long favouritesCount;
|
||||||
public long repliesCount;
|
public long repliesCount;
|
||||||
public Instant editedAt;
|
public Instant editedAt;
|
||||||
|
public boolean wantsTranslation;
|
||||||
|
|
||||||
public String url;
|
public String url;
|
||||||
public String inReplyToId;
|
public String inReplyToId;
|
||||||
|
|||||||
@@ -0,0 +1,146 @@
|
|||||||
|
package org.joinmastodon.android.model;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.GlobalUserPreferences;
|
||||||
|
import org.joinmastodon.android.api.ObjectValidationException;
|
||||||
|
import org.joinmastodon.android.api.RequiredField;
|
||||||
|
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
|
||||||
|
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||||
|
import org.parceler.Parcel;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Parcel
|
||||||
|
public class StatusTranslation extends BaseModel implements DisplayItemsParent{
|
||||||
|
// @RequiredField
|
||||||
|
public String id;
|
||||||
|
// @RequiredField
|
||||||
|
public String uri;
|
||||||
|
// @RequiredField
|
||||||
|
public Instant createdAt;
|
||||||
|
// @RequiredField
|
||||||
|
public Account account;
|
||||||
|
// @RequiredField
|
||||||
|
public String content;
|
||||||
|
// @RequiredField
|
||||||
|
public StatusPrivacy visibility;
|
||||||
|
public boolean sensitive;
|
||||||
|
// @RequiredField
|
||||||
|
public String spoilerText;
|
||||||
|
// @RequiredField
|
||||||
|
public List<Attachment> mediaAttachments;
|
||||||
|
public Application application;
|
||||||
|
// @RequiredField
|
||||||
|
public List<Mention> mentions;
|
||||||
|
// @RequiredField
|
||||||
|
public List<Hashtag> tags;
|
||||||
|
// @RequiredField
|
||||||
|
public List<Emoji> emojis;
|
||||||
|
public long reblogsCount;
|
||||||
|
public long favouritesCount;
|
||||||
|
public long repliesCount;
|
||||||
|
public Instant editedAt;
|
||||||
|
|
||||||
|
public String url;
|
||||||
|
public String inReplyToId;
|
||||||
|
public String inReplyToAccountId;
|
||||||
|
public Status reblog;
|
||||||
|
public Poll poll;
|
||||||
|
public Card card;
|
||||||
|
public String language;
|
||||||
|
public String text;
|
||||||
|
|
||||||
|
public boolean favourited;
|
||||||
|
public boolean reblogged;
|
||||||
|
public boolean muted;
|
||||||
|
public boolean bookmarked;
|
||||||
|
public boolean pinned;
|
||||||
|
|
||||||
|
public transient boolean spoilerRevealed;
|
||||||
|
public transient boolean hasGapAfter;
|
||||||
|
private transient String strippedText;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postprocess() throws ObjectValidationException{
|
||||||
|
super.postprocess();
|
||||||
|
// if(application!=null)
|
||||||
|
// application.postprocess();
|
||||||
|
// for(Mention m:mentions)
|
||||||
|
// m.postprocess();
|
||||||
|
// for(Hashtag t:tags)
|
||||||
|
// t.postprocess();
|
||||||
|
// for(Emoji e:emojis)
|
||||||
|
// e.postprocess();
|
||||||
|
// for(Attachment a:mediaAttachments)
|
||||||
|
// a.postprocess();
|
||||||
|
// account.postprocess();
|
||||||
|
// if(poll!=null)
|
||||||
|
// poll.postprocess();
|
||||||
|
// if(card!=null)
|
||||||
|
// card.postprocess();
|
||||||
|
// if(reblog!=null)
|
||||||
|
// reblog.postprocess();
|
||||||
|
|
||||||
|
// spoilerRevealed=GlobalUserPreferences.alwaysExpandContentWarnings || !sensitive;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(){
|
||||||
|
return "Status{"+
|
||||||
|
"id='"+id+'\''+
|
||||||
|
", uri='"+uri+'\''+
|
||||||
|
", createdAt="+createdAt+
|
||||||
|
", account="+account+
|
||||||
|
", content='"+content+'\''+
|
||||||
|
", visibility="+visibility+
|
||||||
|
", sensitive="+sensitive+
|
||||||
|
", spoilerText='"+spoilerText+'\''+
|
||||||
|
", mediaAttachments="+mediaAttachments+
|
||||||
|
", application="+application+
|
||||||
|
", mentions="+mentions+
|
||||||
|
", tags="+tags+
|
||||||
|
", emojis="+emojis+
|
||||||
|
", reblogsCount="+reblogsCount+
|
||||||
|
", favouritesCount="+favouritesCount+
|
||||||
|
", repliesCount="+repliesCount+
|
||||||
|
", url='"+url+'\''+
|
||||||
|
", inReplyToId='"+inReplyToId+'\''+
|
||||||
|
", inReplyToAccountId='"+inReplyToAccountId+'\''+
|
||||||
|
", reblog="+reblog+
|
||||||
|
", poll="+poll+
|
||||||
|
", card="+card+
|
||||||
|
", language='"+language+'\''+
|
||||||
|
", text='"+text+'\''+
|
||||||
|
", favourited="+favourited+
|
||||||
|
", reblogged="+reblogged+
|
||||||
|
", muted="+muted+
|
||||||
|
", bookmarked="+bookmarked+
|
||||||
|
", pinned="+pinned+
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getID(){
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(StatusCountersUpdatedEvent ev){
|
||||||
|
favouritesCount=ev.favorites;
|
||||||
|
reblogsCount=ev.reblogs;
|
||||||
|
repliesCount=ev.replies;
|
||||||
|
favourited=ev.favorited;
|
||||||
|
reblogged=ev.reblogged;
|
||||||
|
bookmarked=ev.bookmarked;
|
||||||
|
pinned=ev.pinned;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatusTranslation getContentStatus(){
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStrippedText(){
|
||||||
|
if(strippedText==null)
|
||||||
|
strippedText=HtmlParser.strip(content);
|
||||||
|
return strippedText;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,6 +28,7 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
@@ -154,11 +155,16 @@ public class ComposeAutocompleteViewController{
|
|||||||
}else if(mode==Mode.EMOJIS){
|
}else if(mode==Mode.EMOJIS){
|
||||||
String _text=text.substring(1); // remove ':'
|
String _text=text.substring(1); // remove ':'
|
||||||
List<WrappedEmoji> oldList=emojis;
|
List<WrappedEmoji> oldList=emojis;
|
||||||
emojis=AccountSessionManager.getInstance()
|
List<Emoji> allEmojis = AccountSessionManager.getInstance()
|
||||||
.getCustomEmojis(AccountSessionManager.getInstance().getAccount(accountID).domain)
|
.getCustomEmojis(AccountSessionManager.getInstance().getAccount(accountID).domain)
|
||||||
.stream()
|
.stream()
|
||||||
.flatMap(ec->ec.emojis.stream())
|
.flatMap(ec->ec.emojis.stream())
|
||||||
.filter(e->e.visibleInPicker && e.shortcode.startsWith(_text))
|
.filter(e->e.visibleInPicker)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
List<Emoji> startsWithSearch = allEmojis.stream().filter(e -> e.shortcode.toLowerCase().startsWith(_text.toLowerCase())).collect(Collectors.toList());
|
||||||
|
emojis=Stream.concat(startsWithSearch.stream(), allEmojis.stream()
|
||||||
|
.filter(e -> !startsWithSearch.contains(e))
|
||||||
|
.filter(e -> e.shortcode.toLowerCase().contains(_text.toLowerCase())))
|
||||||
.map(WrappedEmoji::new)
|
.map(WrappedEmoji::new)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
UiUtils.updateList(oldList, emojis, list, emojisAdapter, (e1, e2)->e1.emoji.shortcode.equals(e2.emoji.shortcode));
|
UiUtils.updateList(oldList, emojis, list, emojisAdapter, (e1, e2)->e1.emoji.shortcode.equals(e2.emoji.shortcode));
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public class ImageDescriptionSheet extends BottomSheet{
|
|||||||
}
|
}
|
||||||
|
|
||||||
TextView heading=new TextView(activity);
|
TextView heading=new TextView(activity);
|
||||||
heading.setText(R.string.image_description);
|
heading.setText(R.string.sk_image_description);
|
||||||
heading.setAllCaps(true);
|
heading.setAllCaps(true);
|
||||||
heading.setTypeface(null, Typeface.BOLD);
|
heading.setTypeface(null, Typeface.BOLD);
|
||||||
heading.setPadding(0, V.dp(24), 0, V.dp(8));
|
heading.setPadding(0, V.dp(24), 0, V.dp(8));
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
|
|||||||
if(id==R.id.favorite_btn)
|
if(id==R.id.favorite_btn)
|
||||||
return R.string.button_favorite;
|
return R.string.button_favorite;
|
||||||
if(id==R.id.bookmark_btn)
|
if(id==R.id.bookmark_btn)
|
||||||
return R.string.button_bookmark;
|
return R.string.add_bookmark;
|
||||||
if(id==R.id.share_btn)
|
if(id==R.id.share_btn)
|
||||||
return R.string.button_share;
|
return R.string.button_share;
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import org.joinmastodon.android.GlobalUserPreferences;
|
|||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
import org.joinmastodon.android.api.requests.accounts.GetAccountRelationships;
|
import org.joinmastodon.android.api.requests.accounts.GetAccountRelationships;
|
||||||
import org.joinmastodon.android.api.requests.statuses.GetStatusSourceText;
|
import org.joinmastodon.android.api.requests.statuses.GetStatusSourceText;
|
||||||
|
import org.joinmastodon.android.api.requests.statuses.GetStatusTranslation;
|
||||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||||
import org.joinmastodon.android.fragments.ComposeFragment;
|
import org.joinmastodon.android.fragments.ComposeFragment;
|
||||||
@@ -33,6 +34,7 @@ import org.joinmastodon.android.model.Account;
|
|||||||
import org.joinmastodon.android.model.Attachment;
|
import org.joinmastodon.android.model.Attachment;
|
||||||
import org.joinmastodon.android.model.Relationship;
|
import org.joinmastodon.android.model.Relationship;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
|
import org.joinmastodon.android.model.StatusTranslation;
|
||||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||||
import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
|
import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
|
||||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
@@ -60,6 +62,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
|||||||
private SpannableStringBuilder parsedName;
|
private SpannableStringBuilder parsedName;
|
||||||
public final Status status;
|
public final Status status;
|
||||||
private boolean hasVisibilityToggle;
|
private boolean hasVisibilityToggle;
|
||||||
|
private boolean hasTranslateToggle;
|
||||||
boolean needBottomPadding;
|
boolean needBottomPadding;
|
||||||
private String extraText;
|
private String extraText;
|
||||||
|
|
||||||
@@ -74,6 +77,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
|||||||
HtmlParser.parseCustomEmoji(parsedName, user.emojis);
|
HtmlParser.parseCustomEmoji(parsedName, user.emojis);
|
||||||
emojiHelper.setText(parsedName);
|
emojiHelper.setText(parsedName);
|
||||||
if(status!=null){
|
if(status!=null){
|
||||||
|
hasTranslateToggle=true;
|
||||||
hasVisibilityToggle=status.sensitive || !TextUtils.isEmpty(status.spoilerText);
|
hasVisibilityToggle=status.sensitive || !TextUtils.isEmpty(status.spoilerText);
|
||||||
if(!hasVisibilityToggle && !status.mediaAttachments.isEmpty()){
|
if(!hasVisibilityToggle && !status.mediaAttachments.isEmpty()){
|
||||||
for(Attachment att:status.mediaAttachments){
|
for(Attachment att:status.mediaAttachments){
|
||||||
@@ -107,7 +111,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
|||||||
|
|
||||||
public static class Holder extends StatusDisplayItem.Holder<HeaderStatusDisplayItem> implements ImageLoaderViewHolder{
|
public static class Holder extends StatusDisplayItem.Holder<HeaderStatusDisplayItem> implements ImageLoaderViewHolder{
|
||||||
private final TextView name, username, timestamp, extraText;
|
private final TextView name, username, timestamp, extraText;
|
||||||
private final ImageView avatar, more, visibility;
|
private final ImageView avatar, more, visibility, translate;
|
||||||
private final PopupMenu optionsMenu;
|
private final PopupMenu optionsMenu;
|
||||||
private Relationship relationship;
|
private Relationship relationship;
|
||||||
private APIRequest<?> currentRelationshipRequest;
|
private APIRequest<?> currentRelationshipRequest;
|
||||||
@@ -121,6 +125,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
|||||||
|
|
||||||
public Holder(Activity activity, ViewGroup parent){
|
public Holder(Activity activity, ViewGroup parent){
|
||||||
super(activity, R.layout.display_item_header, parent);
|
super(activity, R.layout.display_item_header, parent);
|
||||||
|
translate=findViewById(R.id.translate);
|
||||||
name=findViewById(R.id.name);
|
name=findViewById(R.id.name);
|
||||||
username=findViewById(R.id.username);
|
username=findViewById(R.id.username);
|
||||||
timestamp=findViewById(R.id.timestamp);
|
timestamp=findViewById(R.id.timestamp);
|
||||||
@@ -133,6 +138,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
|||||||
avatar.setClipToOutline(true);
|
avatar.setClipToOutline(true);
|
||||||
more.setOnClickListener(this::onMoreClick);
|
more.setOnClickListener(this::onMoreClick);
|
||||||
visibility.setOnClickListener(v->item.parentFragment.onVisibilityIconClick(this));
|
visibility.setOnClickListener(v->item.parentFragment.onVisibilityIconClick(this));
|
||||||
|
translate.setOnClickListener(v->item.parentFragment.onRevealTranslationClick(this));
|
||||||
|
|
||||||
optionsMenu=new PopupMenu(activity, more);
|
optionsMenu=new PopupMenu(activity, more);
|
||||||
optionsMenu.inflate(R.menu.post);
|
optionsMenu.inflate(R.menu.post);
|
||||||
@@ -226,6 +232,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
|||||||
else
|
else
|
||||||
timestamp.setText(item.parentFragment.getString(R.string.edited_timestamp, UiUtils.formatRelativeTimestamp(itemView.getContext(), item.status.editedAt)));
|
timestamp.setText(item.parentFragment.getString(R.string.edited_timestamp, UiUtils.formatRelativeTimestamp(itemView.getContext(), item.status.editedAt)));
|
||||||
visibility.setVisibility(item.hasVisibilityToggle && !item.inset ? View.VISIBLE : View.GONE);
|
visibility.setVisibility(item.hasVisibilityToggle && !item.inset ? View.VISIBLE : View.GONE);
|
||||||
|
translate.setVisibility(item.hasTranslateToggle ? View.VISIBLE : View.GONE);
|
||||||
if(item.hasVisibilityToggle){
|
if(item.hasVisibilityToggle){
|
||||||
visibility.setImageResource(item.status.spoilerRevealed ? R.drawable.ic_visibility_off : R.drawable.ic_visibility);
|
visibility.setImageResource(item.status.spoilerRevealed ? R.drawable.ic_visibility_off : R.drawable.ic_visibility);
|
||||||
visibility.setContentDescription(item.parentFragment.getString(item.status.spoilerRevealed ? R.string.hide_content : R.string.reveal_content));
|
visibility.setContentDescription(item.parentFragment.getString(item.status.spoilerRevealed ? R.string.hide_content : R.string.reveal_content));
|
||||||
@@ -233,6 +240,9 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
|||||||
visibility.setTooltipText(visibility.getContentDescription());
|
visibility.setTooltipText(visibility.getContentDescription());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(item.hasTranslateToggle){
|
||||||
|
translate.setImageResource(item.status.wantsTranslation ? R.drawable.ic_translate_on : R.drawable.ic_translate_off);
|
||||||
|
}
|
||||||
itemView.setPadding(itemView.getPaddingLeft(), itemView.getPaddingTop(), itemView.getPaddingRight(), item.needBottomPadding ? V.dp(16) : 0);
|
itemView.setPadding(itemView.getPaddingLeft(), itemView.getPaddingTop(), itemView.getPaddingRight(), item.needBottomPadding ? V.dp(16) : 0);
|
||||||
if(TextUtils.isEmpty(item.extraText)){
|
if(TextUtils.isEmpty(item.extraText)){
|
||||||
extraText.setVisibility(View.GONE);
|
extraText.setVisibility(View.GONE);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import android.view.ViewGroup;
|
|||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.GlobalUserPreferences;
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||||
import org.joinmastodon.android.model.Poll;
|
import org.joinmastodon.android.model.Poll;
|
||||||
@@ -44,7 +45,7 @@ public class PollFooterStatusDisplayItem extends StatusDisplayItem{
|
|||||||
text+=" · "+item.parentFragment.getString(R.string.poll_closed);
|
text+=" · "+item.parentFragment.getString(R.string.poll_closed);
|
||||||
}
|
}
|
||||||
this.text.setText(text);
|
this.text.setText(text);
|
||||||
button.setVisibility(item.poll.isExpired() || item.poll.voted || !item.poll.multiple ? View.GONE : View.VISIBLE);
|
button.setVisibility(item.poll.isExpired() || item.poll.voted || (!item.poll.multiple && !GlobalUserPreferences.voteButtonForSingleChoice) ? View.GONE : View.VISIBLE);
|
||||||
button.setEnabled(item.poll.selectedOptions!=null && !item.poll.selectedOptions.isEmpty());
|
button.setEnabled(item.poll.selectedOptions!=null && !item.poll.selectedOptions.isEmpty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,10 +76,11 @@ public class PollOptionStatusDisplayItem extends StatusDisplayItem{
|
|||||||
@Override
|
@Override
|
||||||
public void onBind(PollOptionStatusDisplayItem item){
|
public void onBind(PollOptionStatusDisplayItem item){
|
||||||
text.setText(item.text);
|
text.setText(item.text);
|
||||||
icon.setVisibility(item.showResults ? View.GONE : View.VISIBLE);
|
// icon.setVisibility(item.showResults ? View.GONE : View.VISIBLE);
|
||||||
percent.setVisibility(item.showResults ? View.VISIBLE : View.GONE);
|
percent.setVisibility(item.showResults ? View.VISIBLE : View.GONE);
|
||||||
itemView.setClickable(!item.showResults);
|
itemView.setClickable(!item.showResults);
|
||||||
if(item.showResults){
|
if(item.showResults){
|
||||||
|
icon.setSelected(item.poll.ownVotes.contains(item.poll.options.indexOf(item.option)));
|
||||||
progressBg.setLevel(Math.round(10000f*item.votesFraction));
|
progressBg.setLevel(Math.round(10000f*item.votesFraction));
|
||||||
button.setBackground(progressBg);
|
button.setBackground(progressBg);
|
||||||
itemView.setSelected(item.isMostVoted);
|
itemView.setSelected(item.isMostVoted);
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
package org.joinmastodon.android.ui.displayitems;
|
package org.joinmastodon.android.ui.displayitems;
|
||||||
|
|
||||||
|
import static org.joinmastodon.android.MastodonApp.context;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
|
import android.util.TypedValue;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
@@ -38,6 +41,8 @@ public class ReblogOrReplyLineStatusDisplayItem extends StatusDisplayItem{
|
|||||||
emojiHelper.setText(ssb);
|
emojiHelper.setText(ssb);
|
||||||
this.icon=icon;
|
this.icon=icon;
|
||||||
this.handleClick=handleClick;
|
this.handleClick=handleClick;
|
||||||
|
TypedValue outValue = new TypedValue();
|
||||||
|
context.getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -67,6 +72,8 @@ public class ReblogOrReplyLineStatusDisplayItem extends StatusDisplayItem{
|
|||||||
text.setText(item.text);
|
text.setText(item.text);
|
||||||
text.setCompoundDrawablesRelativeWithIntrinsicBounds(item.icon, 0, 0, 0);
|
text.setCompoundDrawablesRelativeWithIntrinsicBounds(item.icon, 0, 0, 0);
|
||||||
if(item.handleClick!=null) text.setOnClickListener(item.handleClick);
|
if(item.handleClick!=null) text.setOnClickListener(item.handleClick);
|
||||||
|
text.setEnabled(!item.inset);
|
||||||
|
text.setClickable(!item.inset);
|
||||||
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.N)
|
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.N)
|
||||||
UiUtils.fixCompoundDrawableTintOnAndroid6(text);
|
UiUtils.fixCompoundDrawableTintOnAndroid6(text);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,17 +8,22 @@ import android.text.TextUtils;
|
|||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Button;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
|
import org.joinmastodon.android.api.requests.statuses.GetStatusTranslation;
|
||||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
|
import org.joinmastodon.android.model.StatusTranslation;
|
||||||
import org.joinmastodon.android.ui.drawables.SpoilerStripesDrawable;
|
import org.joinmastodon.android.ui.drawables.SpoilerStripesDrawable;
|
||||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||||
import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
|
import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
|
||||||
import org.joinmastodon.android.ui.views.LinkedTextView;
|
import org.joinmastodon.android.ui.views.LinkedTextView;
|
||||||
|
|
||||||
|
import me.grishka.appkit.api.Callback;
|
||||||
|
import me.grishka.appkit.api.ErrorResponse;
|
||||||
import me.grishka.appkit.imageloader.ImageLoaderViewHolder;
|
import me.grishka.appkit.imageloader.ImageLoaderViewHolder;
|
||||||
import me.grishka.appkit.imageloader.MovieDrawable;
|
import me.grishka.appkit.imageloader.MovieDrawable;
|
||||||
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
|
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
|
||||||
@@ -35,6 +40,7 @@ public class TextStatusDisplayItem extends StatusDisplayItem{
|
|||||||
super(parentID, parentFragment);
|
super(parentID, parentFragment);
|
||||||
this.text=text;
|
this.text=text;
|
||||||
this.status=status;
|
this.status=status;
|
||||||
|
// this.wantsTranslation=wantsTranslation;
|
||||||
emojiHelper.setText(text);
|
emojiHelper.setText(text);
|
||||||
if(!TextUtils.isEmpty(status.spoilerText)){
|
if(!TextUtils.isEmpty(status.spoilerText)){
|
||||||
parsedSpoilerText=HtmlParser.parseCustomEmoji(status.spoilerText, status.emojis);
|
parsedSpoilerText=HtmlParser.parseCustomEmoji(status.spoilerText, status.emojis);
|
||||||
@@ -91,7 +97,26 @@ public class TextStatusDisplayItem extends StatusDisplayItem{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBind(TextStatusDisplayItem item){
|
public void onBind(TextStatusDisplayItem item){
|
||||||
|
if(item.status.wantsTranslation){
|
||||||
|
new GetStatusTranslation(item.status.id)
|
||||||
|
.setCallback(new Callback<StatusTranslation>(){
|
||||||
|
@Override
|
||||||
|
public void onSuccess(StatusTranslation status){
|
||||||
|
text.setText(status.getStrippedText());
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onError(ErrorResponse error){
|
||||||
|
item.status.wantsTranslation=false;
|
||||||
text.setText(item.text);
|
text.setText(item.text);
|
||||||
|
error.showToast(item.parentFragment.getActivity());
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.wrapProgress(item.parentFragment.getActivity(), R.string.loading, true)
|
||||||
|
.exec(item.parentFragment.getAccountID());
|
||||||
|
}else{
|
||||||
|
text.setText(item.text);
|
||||||
|
}
|
||||||
text.setTextIsSelectable(item.textSelectable);
|
text.setTextIsSelectable(item.textSelectable);
|
||||||
spoilerTitleInline.setTextIsSelectable(item.textSelectable);
|
spoilerTitleInline.setTextIsSelectable(item.textSelectable);
|
||||||
text.setInvalidateOnEveryFrame(false);
|
text.setInvalidateOnEveryFrame(false);
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ public class PhotoViewer implements ZoomPanView.Listener{
|
|||||||
toolbar=uiOverlay.findViewById(R.id.toolbar);
|
toolbar=uiOverlay.findViewById(R.id.toolbar);
|
||||||
toolbar.setNavigationOnClickListener(v->onStartSwipeToDismissTransition(0));
|
toolbar.setNavigationOnClickListener(v->onStartSwipeToDismissTransition(0));
|
||||||
imageDescriptionButton = toolbar.getMenu()
|
imageDescriptionButton = toolbar.getMenu()
|
||||||
.add(R.string.image_description)
|
.add(R.string.sk_image_description)
|
||||||
.setIcon(R.drawable.ic_fluent_image_alt_text_24_regular)
|
.setIcon(R.drawable.ic_fluent_image_alt_text_24_regular)
|
||||||
.setVisible(attachments.get(pager.getCurrentItem()).description != null
|
.setVisible(attachments.get(pager.getCurrentItem()).description != null
|
||||||
&& !attachments.get(pager.getCurrentItem()).description.isEmpty())
|
&& !attachments.get(pager.getCurrentItem()).description.isEmpty())
|
||||||
|
|||||||
@@ -1,12 +1,29 @@
|
|||||||
package org.joinmastodon.android.ui.text;
|
package org.joinmastodon.android.ui.text;
|
||||||
|
|
||||||
|
import android.graphics.Typeface;
|
||||||
|
import android.graphics.fonts.FontFamily;
|
||||||
|
import android.graphics.fonts.FontStyle;
|
||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.text.style.BackgroundColorSpan;
|
||||||
|
import android.text.style.BulletSpan;
|
||||||
|
import android.text.style.ForegroundColorSpan;
|
||||||
|
import android.text.style.LeadingMarginSpan;
|
||||||
|
import android.text.style.RelativeSizeSpan;
|
||||||
|
import android.text.style.StrikethroughSpan;
|
||||||
|
import android.text.style.StyleSpan;
|
||||||
|
import android.text.style.SubscriptSpan;
|
||||||
|
import android.text.style.SuperscriptSpan;
|
||||||
|
import android.text.style.TypefaceSpan;
|
||||||
|
import android.text.style.UnderlineSpan;
|
||||||
|
import android.util.TypedValue;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.twitter.twittertext.Regex;
|
import com.twitter.twittertext.Regex;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.MastodonApp;
|
||||||
|
import org.joinmastodon.android.R;
|
||||||
import org.joinmastodon.android.model.Emoji;
|
import org.joinmastodon.android.model.Emoji;
|
||||||
import org.joinmastodon.android.model.Hashtag;
|
import org.joinmastodon.android.model.Hashtag;
|
||||||
import org.joinmastodon.android.model.Mention;
|
import org.joinmastodon.android.model.Mention;
|
||||||
@@ -15,11 +32,11 @@ import org.jsoup.Jsoup;
|
|||||||
import org.jsoup.nodes.Element;
|
import org.jsoup.nodes.Element;
|
||||||
import org.jsoup.nodes.Node;
|
import org.jsoup.nodes.Node;
|
||||||
import org.jsoup.nodes.TextNode;
|
import org.jsoup.nodes.TextNode;
|
||||||
import org.jsoup.safety.Cleaner;
|
|
||||||
import org.jsoup.safety.Safelist;
|
import org.jsoup.safety.Safelist;
|
||||||
import org.jsoup.select.NodeVisitor;
|
import org.jsoup.select.NodeVisitor;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
@@ -29,6 +46,8 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import me.grishka.appkit.utils.V;
|
||||||
|
|
||||||
public class HtmlParser{
|
public class HtmlParser{
|
||||||
private static final String TAG="HtmlParser";
|
private static final String TAG="HtmlParser";
|
||||||
private static final String VALID_URL_PATTERN_STRING =
|
private static final String VALID_URL_PATTERN_STRING =
|
||||||
@@ -67,11 +86,17 @@ public class HtmlParser{
|
|||||||
public Object span;
|
public Object span;
|
||||||
public int start;
|
public int start;
|
||||||
public Element element;
|
public Element element;
|
||||||
|
public boolean more;
|
||||||
|
|
||||||
public SpanInfo(Object span, int start, Element element){
|
public SpanInfo(Object span, int start, Element element){
|
||||||
|
this(span, start, element, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpanInfo(Object span, int start, Element element, boolean more){
|
||||||
this.span=span;
|
this.span=span;
|
||||||
this.start=start;
|
this.start=start;
|
||||||
this.element=element;
|
this.element=element;
|
||||||
|
this.more=more;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,24 +144,59 @@ public class HtmlParser{
|
|||||||
openSpans.add(new SpanInfo(new InvisibleSpan(), ssb.length(), el));
|
openSpans.add(new SpanInfo(new InvisibleSpan(), ssb.length(), el));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case "li" -> openSpans.add(new SpanInfo(new BulletSpan(V.dp(8)), ssb.length(), el));
|
||||||
|
case "em", "i" -> openSpans.add(new SpanInfo(new StyleSpan(Typeface.ITALIC), ssb.length(), el));
|
||||||
|
case "h1", "h2", "h3", "h4", "h5", "h6" -> {
|
||||||
|
// increase line height above heading (multiplying the margin)
|
||||||
|
if (node.previousSibling()!=null) ssb.setSpan(new RelativeSizeSpan(2), ssb.length() - 1, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
if (!node.nodeName().equals("h1")) {
|
||||||
|
openSpans.add(new SpanInfo(new StyleSpan(Typeface.BOLD), ssb.length(), el));
|
||||||
|
}
|
||||||
|
openSpans.add(new SpanInfo(new RelativeSizeSpan(switch(node.nodeName()) {
|
||||||
|
case "h1" -> 1.5f;
|
||||||
|
case "h2" -> 1.25f;
|
||||||
|
case "h3" -> 1.125f;
|
||||||
|
default -> 1;
|
||||||
|
}), ssb.length(), el, !node.nodeName().equals("h1")));
|
||||||
|
}
|
||||||
|
case "strong", "b" -> openSpans.add(new SpanInfo(new StyleSpan(Typeface.BOLD), ssb.length(), el));
|
||||||
|
case "u" -> openSpans.add(new SpanInfo(new UnderlineSpan(), ssb.length(), el));
|
||||||
|
case "s", "del" -> openSpans.add(new SpanInfo(new StrikethroughSpan(), ssb.length(), el));
|
||||||
|
case "sub", "sup" -> {
|
||||||
|
openSpans.add(new SpanInfo(node.nodeName().equals("sub") ? new SubscriptSpan() : new SuperscriptSpan(), ssb.length(), el));
|
||||||
|
openSpans.add(new SpanInfo(new RelativeSizeSpan(0.8f), ssb.length(), el, true));
|
||||||
|
}
|
||||||
|
case "code", "pre" -> openSpans.add(new SpanInfo(new TypefaceSpan("monospace"), ssb.length(), el));
|
||||||
|
case "blockquote" -> openSpans.add(new SpanInfo(new LeadingMarginSpan.Standard(V.dp(10)), ssb.length(), el));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final static List<String> blockElements = Arrays.asList("p", "ul", "ol", "blockquote", "h1", "h2", "h3", "h4", "h5", "h6");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tail(@NonNull Node node, int depth){
|
public void tail(@NonNull Node node, int depth){
|
||||||
if(node instanceof Element el){
|
if(node instanceof Element el){
|
||||||
|
processOpenSpan(el);
|
||||||
if("span".equals(el.nodeName()) && el.hasClass("ellipsis")){
|
if("span".equals(el.nodeName()) && el.hasClass("ellipsis")){
|
||||||
ssb.append("…", new DeleteWhenCopiedSpan(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
ssb.append("…", new DeleteWhenCopiedSpan(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
}else if("p".equals(el.nodeName())){
|
}else if(blockElements.contains(el.nodeName()) && node.nextSibling()!=null){
|
||||||
if(node.nextSibling()!=null)
|
ssb.append("\n"); // line end
|
||||||
ssb.append("\n\n");
|
ssb.append("\n", new RelativeSizeSpan(0.75f), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // margin after block
|
||||||
}else if(!openSpans.isEmpty()){
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processOpenSpan(Element el) {
|
||||||
|
if(!openSpans.isEmpty()){
|
||||||
SpanInfo si=openSpans.get(openSpans.size()-1);
|
SpanInfo si=openSpans.get(openSpans.size()-1);
|
||||||
if(si.element==el){
|
if(si.element==el){
|
||||||
ssb.setSpan(si.span, si.start, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
ssb.setSpan(si.span, si.start, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
openSpans.remove(openSpans.size()-1);
|
openSpans.remove(openSpans.size()-1);
|
||||||
|
if(si.more) processOpenSpan(el);
|
||||||
}
|
}
|
||||||
|
if("li".equals(el.nodeName()) && el.nextSibling()!=null) {
|
||||||
|
ssb.append('\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public class DiscoverInfoBannerHelper{
|
|||||||
case TRENDING_HASHTAGS -> R.string.trending_hashtags_info_banner;
|
case TRENDING_HASHTAGS -> R.string.trending_hashtags_info_banner;
|
||||||
case TRENDING_LINKS -> R.string.trending_links_info_banner;
|
case TRENDING_LINKS -> R.string.trending_links_info_banner;
|
||||||
case LOCAL_TIMELINE -> R.string.local_timeline_info_banner;
|
case LOCAL_TIMELINE -> R.string.local_timeline_info_banner;
|
||||||
case FEDERATED_TIMELINE -> R.string.federated_timeline_info_banner;
|
case FEDERATED_TIMELINE -> R.string.sk_federated_timeline_info_banner;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -411,7 +411,7 @@ public class UiUtils{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void confirmDeletePost(Activity activity, String accountID, Status status, Consumer<Status> resultCallback, boolean forRedraft){
|
public static void confirmDeletePost(Activity activity, String accountID, Status status, Consumer<Status> resultCallback, boolean forRedraft){
|
||||||
showConfirmationAlert(activity, forRedraft ? R.string.confirm_delete_and_redraft_title : R.string.confirm_delete_title, forRedraft ? R.string.confirm_delete_and_redraft : R.string.confirm_delete, forRedraft ? R.string.delete_and_redraft : R.string.delete, ()->{
|
showConfirmationAlert(activity, forRedraft ? R.string.sk_confirm_delete_and_redraft_title : R.string.confirm_delete_title, forRedraft ? R.string.sk_confirm_delete_and_redraft : R.string.confirm_delete, forRedraft ? R.string.sk_delete_and_redraft : R.string.delete, ()->{
|
||||||
new DeleteStatus(status.id)
|
new DeleteStatus(status.id)
|
||||||
.setCallback(new Callback<>(){
|
.setCallback(new Callback<>(){
|
||||||
@Override
|
@Override
|
||||||
@@ -433,9 +433,9 @@ public class UiUtils{
|
|||||||
|
|
||||||
public static void confirmPinPost(Activity activity, String accountID, Status status, boolean pinned, Consumer<Status> resultCallback){
|
public static void confirmPinPost(Activity activity, String accountID, Status status, boolean pinned, Consumer<Status> resultCallback){
|
||||||
showConfirmationAlert(activity,
|
showConfirmationAlert(activity,
|
||||||
pinned ? R.string.confirm_pin_post_title : R.string.confirm_unpin_post_title,
|
pinned ? R.string.sk_confirm_pin_post_title : R.string.sk_confirm_unpin_post_title,
|
||||||
pinned ? R.string.confirm_pin_post : R.string.confirm_unpin_post,
|
pinned ? R.string.sk_confirm_pin_post : R.string.sk_confirm_unpin_post,
|
||||||
pinned ? R.string.pin_post : R.string.unpin_post,
|
pinned ? R.string.sk_pin_post : R.string.sk_unpin_post,
|
||||||
()->{
|
()->{
|
||||||
new SetStatusPinned(status.id, pinned)
|
new SetStatusPinned(status.id, pinned)
|
||||||
.setCallback(new Callback<>() {
|
.setCallback(new Callback<>() {
|
||||||
@@ -452,7 +452,7 @@ public class UiUtils{
|
|||||||
error.showToast(activity);
|
error.showToast(activity);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.wrapProgress(activity, pinned ? R.string.pinning : R.string.unpinning, false)
|
.wrapProgress(activity, pinned ? R.string.sk_pinning : R.string.sk_unpinning, false)
|
||||||
.exec(accountID);
|
.exec(accountID);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -508,7 +508,7 @@ public class UiUtils{
|
|||||||
public void onSuccess(Relationship result) {
|
public void onSuccess(Relationship result) {
|
||||||
resultCallback.accept(result);
|
resultCallback.accept(result);
|
||||||
progressCallback.accept(false);
|
progressCallback.accept(false);
|
||||||
Toast.makeText(activity, activity.getString(result.notifying ? R.string.user_post_notifications_on : R.string.user_post_notifications_off, '@'+account.username), Toast.LENGTH_SHORT).show();
|
Toast.makeText(activity, activity.getString(result.notifying ? R.string.sk_user_post_notifications_on : R.string.sk_user_post_notifications_off, '@'+account.username), Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -718,6 +718,16 @@ public class UiUtils{
|
|||||||
GlobalUserPreferences.trueBlackTheme ? R.style.Theme_Mastodon_Dark_TrueBlack_Yellow : R.style.Theme_Mastodon_Dark_Yellow;
|
GlobalUserPreferences.trueBlackTheme ? R.style.Theme_Mastodon_Dark_TrueBlack_Yellow : R.style.Theme_Mastodon_Dark_Yellow;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case MATERIAL3:
|
||||||
|
context.setTheme(switch(GlobalUserPreferences.theme){
|
||||||
|
case AUTO ->
|
||||||
|
GlobalUserPreferences.trueBlackTheme ? R.style.Theme_Mastodon_AutoLightDark_TrueBlack_Material3 : R.style.Theme_Mastodon_AutoLightDark_Material3;
|
||||||
|
case LIGHT ->
|
||||||
|
R.style.Theme_Mastodon_Light_Material3;
|
||||||
|
case DARK ->
|
||||||
|
GlobalUserPreferences.trueBlackTheme ? R.style.Theme_Mastodon_Dark_TrueBlack_Material3 : R.style.Theme_Mastodon_Dark_Material3;
|
||||||
|
});
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,124 @@
|
|||||||
|
package org.joinmastodon.android.ui.views;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.AnimatorListenerAdapter;
|
||||||
|
import android.animation.AnimatorSet;
|
||||||
|
import android.animation.ObjectAnimator;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.R;
|
||||||
|
import org.joinmastodon.android.ui.utils.SimpleTextWatcher;
|
||||||
|
|
||||||
|
import me.grishka.appkit.utils.CubicBezierInterpolator;
|
||||||
|
import me.grishka.appkit.utils.V;
|
||||||
|
|
||||||
|
public class FloatingHintEditTextLayout extends FrameLayout{
|
||||||
|
private EditText edit;
|
||||||
|
private TextView label;
|
||||||
|
private int labelTextSize;
|
||||||
|
private int offsetY;
|
||||||
|
private boolean hintVisible;
|
||||||
|
private Animator currentAnim;
|
||||||
|
|
||||||
|
public FloatingHintEditTextLayout(Context context){
|
||||||
|
this(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FloatingHintEditTextLayout(Context context, AttributeSet attrs){
|
||||||
|
this(context, attrs, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FloatingHintEditTextLayout(Context context, AttributeSet attrs, int defStyle){
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
if(isInEditMode())
|
||||||
|
V.setApplicationContext(context);
|
||||||
|
TypedArray ta=context.obtainStyledAttributes(attrs, R.styleable.FloatingHintEditTextLayout);
|
||||||
|
labelTextSize=ta.getDimensionPixelSize(R.styleable.FloatingHintEditTextLayout_android_labelTextSize, V.dp(12));
|
||||||
|
offsetY=ta.getDimensionPixelOffset(R.styleable.FloatingHintEditTextLayout_editTextOffsetY, 0);
|
||||||
|
ta.recycle();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onFinishInflate(){
|
||||||
|
super.onFinishInflate();
|
||||||
|
if(getChildCount()>0 && getChildAt(0) instanceof EditText et){
|
||||||
|
edit=et;
|
||||||
|
}else{
|
||||||
|
throw new IllegalStateException("First child must be an EditText");
|
||||||
|
}
|
||||||
|
|
||||||
|
label=new TextView(getContext());
|
||||||
|
label.setTextSize(TypedValue.COMPLEX_UNIT_PX, labelTextSize);
|
||||||
|
label.setTextColor(edit.getHintTextColors());
|
||||||
|
label.setText(edit.getHint());
|
||||||
|
label.setSingleLine();
|
||||||
|
label.setPivotX(0f);
|
||||||
|
label.setPivotY(0f);
|
||||||
|
LayoutParams lp=new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.START | Gravity.TOP);
|
||||||
|
lp.setMarginStart(edit.getPaddingStart());
|
||||||
|
addView(label, lp);
|
||||||
|
|
||||||
|
hintVisible=edit.getText().length()==0;
|
||||||
|
if(hintVisible)
|
||||||
|
label.setAlpha(0f);
|
||||||
|
|
||||||
|
edit.addTextChangedListener(new SimpleTextWatcher(this::onTextChanged));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onTextChanged(Editable text){
|
||||||
|
boolean newHintVisible=text.length()==0;
|
||||||
|
if(newHintVisible==hintVisible)
|
||||||
|
return;
|
||||||
|
if(currentAnim!=null)
|
||||||
|
currentAnim.cancel();
|
||||||
|
hintVisible=newHintVisible;
|
||||||
|
|
||||||
|
label.setAlpha(1);
|
||||||
|
float scale=edit.getLineHeight()/(float)label.getLineHeight();
|
||||||
|
float transY=edit.getHeight()/2f-edit.getLineHeight()/2f+(edit.getTop()-label.getTop())-(label.getHeight()/2f-label.getLineHeight()/2f);
|
||||||
|
|
||||||
|
AnimatorSet anim=new AnimatorSet();
|
||||||
|
if(hintVisible){
|
||||||
|
anim.playTogether(
|
||||||
|
ObjectAnimator.ofFloat(edit, TRANSLATION_Y, 0),
|
||||||
|
ObjectAnimator.ofFloat(label, SCALE_X, scale),
|
||||||
|
ObjectAnimator.ofFloat(label, SCALE_Y, scale),
|
||||||
|
ObjectAnimator.ofFloat(label, TRANSLATION_Y, transY)
|
||||||
|
);
|
||||||
|
edit.setHintTextColor(0);
|
||||||
|
}else{
|
||||||
|
label.setScaleX(scale);
|
||||||
|
label.setScaleY(scale);
|
||||||
|
label.setTranslationY(transY);
|
||||||
|
anim.playTogether(
|
||||||
|
ObjectAnimator.ofFloat(edit, TRANSLATION_Y, offsetY),
|
||||||
|
ObjectAnimator.ofFloat(label, SCALE_X, 1f),
|
||||||
|
ObjectAnimator.ofFloat(label, SCALE_Y, 1f),
|
||||||
|
ObjectAnimator.ofFloat(label, TRANSLATION_Y, 0f)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
anim.setDuration(150);
|
||||||
|
anim.setInterpolator(CubicBezierInterpolator.DEFAULT);
|
||||||
|
anim.start();
|
||||||
|
anim.addListener(new AnimatorListenerAdapter(){
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animator animation){
|
||||||
|
currentAnim=null;
|
||||||
|
if(hintVisible){
|
||||||
|
label.setAlpha(0);
|
||||||
|
edit.setHintTextColor(label.getTextColors());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
currentAnim=anim;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<item android:color="@color/gray_25" android:state_enabled="true"/>
|
<item android:color="?colorBackgroundLightest" android:state_enabled="true"/>
|
||||||
<item android:color="@color/gray_100"/>
|
<item android:color="?android:colorBackground"/>
|
||||||
</selector>
|
</selector>
|
||||||
5
mastodon/src/main/res/color/button_text_m3_filled.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:color="?colorM3OnPrimary" android:state_enabled="true"/>
|
||||||
|
<item android:color="?colorM3OnSurface" android:alpha="0.38"/>
|
||||||
|
</selector>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<item android:color="?colorButtonText" android:state_enabled="true"/>
|
<item android:color="@color/black" android:state_enabled="true"/>
|
||||||
<item android:color="?colorTabInactive"/>
|
<item android:color="?colorTabInactive"/>
|
||||||
</selector>
|
</selector>
|
||||||
4
mastodon/src/main/res/color/m3_pressed_overlay.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:color="?colorM3PressedOverlay" android:alpha="0.12"/>
|
||||||
|
</selector>
|
||||||
5
mastodon/src/main/res/color/m3_radiobutton_tint.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:color="?colorM3Primary" android:state_checked="true"/>
|
||||||
|
<item android:color="?colorM3OnSurfaceVariant"/>
|
||||||
|
</selector>
|
||||||
22
mastodon/src/main/res/drawable-anydpi-v24/ic_ntf_logo.xml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:aapt="http://schemas.android.com/aapt"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="#FFFFFF">
|
||||||
|
<group android:scaleX="0.9699526"
|
||||||
|
android:scaleY="0.9699526"
|
||||||
|
android:translateX="0.96"
|
||||||
|
android:translateY="6.925208">
|
||||||
|
<path
|
||||||
|
android:pathData="m3.639,-0c-1.097,0 -1.983,0.387 -2.658,1.141 -0.655,0.754 -0.981,1.771 -0.981,3.053l0,6.27L2.482,10.464L2.482,4.378c0,-1.284 0.539,-1.935 1.618,-1.935 1.192,0 1.791,0.773 1.791,2.3l0,3.331l2.468,0l0,-3.331c0,-1.527 0.598,-2.3 1.791,-2.3 1.078,0 1.618,0.651 1.618,1.935l0,6.085l2.482,0l0,-6.27c0,-1.281 -0.326,-2.299 -0.981,-3.053 -0.676,-0.754 -1.56,-1.141 -2.658,-1.141 -1.27,0 -2.232,0.488 -2.868,1.466L7.125,2.504 6.506,1.466C5.87,0.488 4.909,-0 3.639,-0Z"
|
||||||
|
android:strokeWidth="0.796"
|
||||||
|
android:fillColor="#000000"/>
|
||||||
|
<path
|
||||||
|
android:pathData="m18.947,10.464q-1.113,0 -1.986,-0.493 -0.873,-0.507 -1.366,-1.366 -0.479,-0.873 -0.479,-1.958 0,-1.07 0.479,-1.944 0.493,-0.873 1.366,-1.366 0.873,-0.507 1.986,-0.507 1.099,0 1.972,0.507 0.873,0.493 1.352,1.366 0.493,0.873 0.493,1.944 0,1.085 -0.493,1.958 -0.479,0.859 -1.352,1.366 -0.873,0.493 -1.972,0.493zM18.947,8.759q0.535,0 0.986,-0.254 0.451,-0.254 0.718,-0.732 0.268,-0.479 0.268,-1.127 0,-0.634 -0.268,-1.113 -0.268,-0.479 -0.718,-0.732 -0.451,-0.254 -0.986,-0.254 -0.535,0 -0.986,0.254 -0.451,0.254 -0.732,0.732 -0.268,0.479 -0.268,1.113 0,0.634 0.268,1.127 0.282,0.479 0.732,0.732 0.451,0.254 0.986,0.254z"
|
||||||
|
android:strokeWidth="0.687"
|
||||||
|
android:fillColor="#000000"
|
||||||
|
android:strokeColor="#00000000"/>
|
||||||
|
</group>
|
||||||
|
</vector>
|
||||||
BIN
mastodon/src/main/res/drawable-hdpi/ic_ntf_logo.png
Normal file
|
After Width: | Height: | Size: 405 B |
BIN
mastodon/src/main/res/drawable-mdpi/ic_ntf_logo.png
Normal file
|
After Width: | Height: | Size: 295 B |
BIN
mastodon/src/main/res/drawable-xhdpi/ic_ntf_logo.png
Normal file
|
After Width: | Height: | Size: 567 B |
BIN
mastodon/src/main/res/drawable-xxhdpi/ic_ntf_logo.png
Normal file
|
After Width: | Height: | Size: 902 B |
19
mastodon/src/main/res/drawable/bg_button_m3_filled.xml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_enabled="true">
|
||||||
|
<ripple android:color="@color/m3_pressed_overlay">
|
||||||
|
<item>
|
||||||
|
<shape>
|
||||||
|
<solid android:color="?colorM3Primary"/>
|
||||||
|
<corners android:radius="20dp"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</ripple>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<shape>
|
||||||
|
<solid android:color="?colorM3DisabledBackground"/>
|
||||||
|
<corners android:radius="20dp"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</selector>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<solid android:color="@color/gray_800"/>
|
<solid android:color="?colorWindowBackground"/>
|
||||||
<corners android:radius="10dp"/>
|
<corners android:radius="10dp"/>
|
||||||
<padding android:top="16dp" android:left="16dp" android:right="16dp" android:bottom="16dp"/>
|
<padding android:top="16dp" android:left="16dp" android:right="16dp" android:bottom="16dp"/>
|
||||||
</shape>
|
</shape>
|
||||||
@@ -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="M3.839 5.858c2.94-3.916 9.03-5.055 13.364-2.36 4.28 2.66 5.854 7.777 4.1 12.577-1.655 4.533-6.016 6.328-9.159 4.048-1.177-0.854-1.634-1.925-1.854-3.664l-0.106-0.987-0.045-0.398c-0.123-0.934-0.311-1.352-0.705-1.572C8.9 13.204 8.542 13.197 7.84 13.47l-0.351 0.146-0.179 0.078c-1.014 0.44-1.688 0.595-2.541 0.416l-0.2-0.047-0.164-0.047c-2.79-0.865-3.203-4.648-0.565-8.158zm0.984 6.716l0.123 0.037 0.134 0.03c0.439 0.087 0.814 0.015 1.437-0.242l0.602-0.257c1.202-0.493 1.985-0.54 3.046 0.05 0.917 0.512 1.275 1.298 1.457 2.66l0.053 0.459 0.055 0.532 0.047 0.422c0.172 1.361 0.485 2.09 1.248 2.644 2.275 1.65 5.534 0.309 6.87-3.349 1.516-4.152 0.174-8.514-3.484-10.789-3.675-2.284-8.899-1.306-11.373 1.987-2.075 2.763-1.82 5.28-0.215 5.816zm11.225-1.994c-0.18-0.667 0.217-1.353 0.883-1.531 0.667-0.179 1.353 0.217 1.531 0.884 0.18 0.667-0.217 1.352-0.884 1.53-0.666 0.18-1.352-0.216-1.53-0.883zm0.494 3.488c-0.179-0.666 0.217-1.352 0.884-1.53 0.667-0.18 1.352 0.216 1.531 0.883 0.179 0.667-0.217 1.353-0.884 1.531-0.667 0.179-1.352-0.217-1.53-0.884zM14.07 7.577c-0.179-0.667 0.217-1.352 0.884-1.53 0.667-0.18 1.352 0.216 1.53 0.883 0.18 0.667-0.216 1.352-0.883 1.53-0.667 0.18-1.352-0.216-1.53-0.883zm-0.028 8.998c-0.18-0.666 0.217-1.352 0.883-1.53 0.667-0.18 1.353 0.216 1.531 0.883 0.18 0.667-0.217 1.353-0.883 1.531-0.667 0.179-1.353-0.217-1.531-0.884zm-3.497-9.97c-0.179-0.666 0.217-1.352 0.883-1.53 0.667-0.18 1.353 0.217 1.532 0.883 0.178 0.667-0.218 1.353-0.884 1.531-0.667 0.179-1.353-0.217-1.531-0.884z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||||
|
</vector>
|
||||||
9
mastodon/src/main/res/drawable/ic_m3_cancel.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<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="M12,2C6.47,2 2,6.47 2,12C2,17.53 6.47,22 12,22C17.53,22 22,17.53 22,12C22,6.47 17.53,2 12,2ZM12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20ZM12,10.59L15.59,7L17,8.41L13.41,12L17,15.59L15.59,17L12,13.41L8.41,17L7,15.59L10.59,12L7,8.41L8.41,7L12,10.59Z"
|
||||||
|
android:fillColor="#49454F"/>
|
||||||
|
</vector>
|
||||||
9
mastodon/src/main/res/drawable/ic_m3_search.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<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="M12.3,11.058L17.075,15.833L15.833,17.075L11.058,12.3C10.167,12.942 9.092,13.333 7.917,13.333C4.925,13.333 2.5,10.908 2.5,7.917C2.5,4.925 4.925,2.5 7.917,2.5C10.908,2.5 13.333,4.925 13.333,7.917C13.333,9.092 12.942,10.167 12.3,11.058ZM7.917,4.167C5.842,4.167 4.167,5.842 4.167,7.917C4.167,9.992 5.842,11.667 7.917,11.667C9.992,11.667 11.667,9.992 11.667,7.917C11.667,5.842 9.992,4.167 7.917,4.167Z"
|
||||||
|
android:fillColor="#49454F"/>
|
||||||
|
</vector>
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="17.62dp"
|
|
||||||
android:viewportWidth="17.732"
|
|
||||||
android:viewportHeight="13.02">
|
|
||||||
<path
|
|
||||||
android:pathData="m4.528,0c-1.366,0 -2.468,0.482 -3.307,1.42C0.405,2.357 0,3.624 0,5.218v7.802h3.089v-7.572c0,-1.597 0.671,-2.408 2.013,-2.408 1.483,0 2.228,0.962 2.228,2.862v4.145h3.071v-4.145c0,-1.9 0.744,-2.862 2.228,-2.862 1.342,0 2.013,0.811 2.013,2.408v7.572h3.089v-7.802c0,-1.594 -0.405,-2.861 -1.22,-3.799 -0.841,-0.938 -1.941,-1.42 -3.307,-1.42 -1.58,0 -2.777,0.608 -3.568,1.824l-0.77,1.292 -0.77,-1.292C7.305,0.608 6.108,0 4.528,0Z"
|
|
||||||
android:strokeWidth="0.990258"
|
|
||||||
android:fillColor="#fff">
|
|
||||||
</path>
|
|
||||||
</vector>
|
|
||||||
5
mastodon/src/main/res/drawable/ic_translate_off.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<vector android:height="24dp" android:tint="#000000"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="?colorSecondary" android:pathData="M12.87,15.07l-2.54,-2.51 0.03,-0.03c1.74,-1.94 2.98,-4.17 3.71,-6.53L17,6L17,4h-7L10,2L8,2v2L1,4v1.99h11.17C11.5,7.92 10.44,9.75 9,11.35 8.07,10.32 7.3,9.19 6.69,8h-2c0.73,1.63 1.73,3.17 2.98,4.56l-5.09,5.02L4,19l5,-5 3.11,3.11 0.76,-2.04zM18.5,10h-2L12,22h2l1.12,-3h4.75L21,22h2l-4.5,-12zM15.88,17l1.62,-4.33L19.12,17h-3.24z"/>
|
||||||
|
</vector>
|
||||||
5
mastodon/src/main/res/drawable/ic_translate_on.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<vector android:height="24dp" android:tint="#000000"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="?colorSecondary" android:pathData="M12.87,15.07l-2.54,-2.51 0.03,-0.03c1.74,-1.94 2.98,-4.17 3.71,-6.53L17,6L17,4h-7L10,2L8,2v2L1,4v1.99h11.17C11.5,7.92 10.44,9.75 9,11.35 8.07,10.32 7.3,9.19 6.69,8h-2c0.73,1.63 1.73,3.17 2.98,4.56l-5.09,5.02L4,19l5,-5 3.11,3.11 0.76,-2.04zM18.5,10h-2L12,22h2l1.12,-3h4.75L21,22h2l-4.5,-12zM15.88,17l1.62,-4.33L19.12,17h-3.24z"/>
|
||||||
|
</vector>
|
||||||
5
mastodon/src/main/res/drawable/rect_4dp.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="#000"/>
|
||||||
|
<corners android:radius="4dp"/>
|
||||||
|
</shape>
|
||||||
@@ -26,8 +26,20 @@
|
|||||||
android:layout_width="36dp"
|
android:layout_width="36dp"
|
||||||
android:layout_height="36dp"
|
android:layout_height="36dp"
|
||||||
android:layout_marginTop="-6dp"
|
android:layout_marginTop="-6dp"
|
||||||
android:layout_marginRight="6dp"
|
android:layout_marginEnd="6dp"
|
||||||
android:layout_toLeftOf="@id/more"
|
android:layout_toStartOf="@id/more"
|
||||||
|
android:background="?android:selectableItemBackgroundBorderless"
|
||||||
|
android:scaleType="center"
|
||||||
|
android:src="@drawable/ic_visibility"
|
||||||
|
android:tint="?android:textColorSecondary" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/translate"
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:layout_marginTop="-6dp"
|
||||||
|
android:layout_marginEnd="6dp"
|
||||||
|
android:layout_toStartOf="@id/visibility"
|
||||||
android:background="?android:selectableItemBackgroundBorderless"
|
android:background="?android:selectableItemBackgroundBorderless"
|
||||||
android:scaleType="center"
|
android:scaleType="center"
|
||||||
android:src="@drawable/ic_visibility"
|
android:src="@drawable/ic_visibility"
|
||||||
@@ -46,7 +58,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="24dp"
|
android:layout_height="24dp"
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
android:layout_toStartOf="@id/visibility"
|
android:layout_toStartOf="@id/translate"
|
||||||
android:layout_toEndOf="@id/avatar">
|
android:layout_toEndOf="@id/avatar">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@@ -78,7 +90,7 @@
|
|||||||
android:layout_height="20dp"
|
android:layout_height="20dp"
|
||||||
android:layout_below="@id/name_wrap"
|
android:layout_below="@id/name_wrap"
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
android:layout_toStartOf="@id/visibility"
|
android:layout_toStartOf="@id/translate"
|
||||||
android:layout_toEndOf="@id/avatar"
|
android:layout_toEndOf="@id/avatar"
|
||||||
android:layoutDirection="locale"
|
android:layoutDirection="locale"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/button"
|
android:id="@+id/button"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="48dp"
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingVertical="12dp"
|
||||||
android:outlineProvider="background"
|
android:outlineProvider="background"
|
||||||
android:elevation="2dp"
|
android:elevation="2dp"
|
||||||
android:background="@drawable/bg_poll_option_clickable"
|
android:background="@drawable/bg_poll_option_clickable"
|
||||||
@@ -48,9 +49,7 @@
|
|||||||
android:layout_marginLeft="16dp"
|
android:layout_marginLeft="16dp"
|
||||||
android:layout_marginRight="16dp"
|
android:layout_marginRight="16dp"
|
||||||
android:textAppearance="@style/m3_title_medium"
|
android:textAppearance="@style/m3_title_medium"
|
||||||
android:singleLine="true"
|
tools:text="scream into void. like this: aaaaaaaaaaaaaaaaaaaa"/>
|
||||||
android:ellipsize="end"
|
|
||||||
tools:text="scream into void"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -31,9 +31,10 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textAppearance="@style/m3_title_medium"
|
android:textAppearance="@style/m3_title_medium"
|
||||||
android:background="?colorBackgroundLight"
|
android:background="@color/error_900"
|
||||||
tools:text="CW title"/>
|
tools:text="CW title"/>
|
||||||
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/border_bottom"
|
android:id="@+id/border_bottom"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -49,6 +50,22 @@
|
|||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textAppearance="@style/m3_body_large"
|
android:textAppearance="@style/m3_body_large"
|
||||||
tools:text="setting up my mstdn"/>
|
tools:text="setting up my mstdn"/>
|
||||||
|
|
||||||
|
<!-- <Button-->
|
||||||
|
<!-- android:id="@+id/translate"-->
|
||||||
|
<!-- android:layout_width="wrap_content"-->
|
||||||
|
<!-- android:layout_height="32dp"-->
|
||||||
|
<!-- android:background="@drawable/bg_inline_button"-->
|
||||||
|
<!-- android:elevation="0dp"-->
|
||||||
|
<!-- android:ellipsize="middle"-->
|
||||||
|
<!-- android:fontFamily="sans-serif-medium"-->
|
||||||
|
<!-- android:singleLine="true"-->
|
||||||
|
<!-- android:stateListAnimator="@null"-->
|
||||||
|
<!-- android:textColor="?android:textColorPrimary"-->
|
||||||
|
<!-- android:textSize="16sp"-->
|
||||||
|
<!-- tools:text="@string/pink_color" />-->
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -187,7 +187,7 @@
|
|||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:text="@string/mark_media_as_sensitive" />
|
android:text="@string/sk_mark_media_as_sensitive" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|||||||
52
mastodon/src/main/res/layout/fragment_login.xml
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<me.grishka.appkit.views.FragmentRootLinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:id="@+id/appkit_loader_root"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:background="?colorM3Background">
|
||||||
|
|
||||||
|
<include layout="@layout/appkit_toolbar"/>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/appkit_loader_content"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0px"
|
||||||
|
android:layout_weight="1">
|
||||||
|
|
||||||
|
<include layout="@layout/loading"
|
||||||
|
android:id="@+id/loading"/>
|
||||||
|
|
||||||
|
<ViewStub android:layout="?errorViewLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:id="@+id/error"
|
||||||
|
android:visibility="gone"/>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:id="@+id/content_stub"/>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/button_bar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btn_next"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:minWidth="145dp"
|
||||||
|
style="@style/Widget.Mastodon.M3.Button.Filled"
|
||||||
|
android:text="@string/next" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</me.grishka.appkit.views.FragmentRootLinearLayout>
|
||||||
@@ -44,18 +44,19 @@
|
|||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/search_edit"
|
android:id="@+id/search_edit"
|
||||||
|
style="@android:style/Widget.EditText"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:inputType="textFilter|textNoSuggestions"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:imeOptions="actionGo"
|
|
||||||
android:layout_marginLeft="16dp"
|
android:layout_marginLeft="16dp"
|
||||||
android:layout_marginRight="16dp"
|
|
||||||
android:layout_marginTop="19dp"
|
android:layout_marginTop="19dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
android:layout_marginBottom="3dp"
|
android:layout_marginBottom="3dp"
|
||||||
android:drawableStart="@drawable/ic_fluent_search_20_regular"
|
android:drawableStart="@drawable/ic_fluent_search_20_regular"
|
||||||
android:drawablePadding="8dp"
|
android:drawablePadding="8dp"
|
||||||
android:drawableTint="?android:textColorSecondary"
|
android:drawableTint="?android:textColorSecondary"
|
||||||
android:hint="@string/search_communities"/>
|
android:hint="@string/search_communities"
|
||||||
|
android:imeOptions="actionGo"
|
||||||
|
android:inputType="textFilter|textNoSuggestions"
|
||||||
|
android:singleLine="true" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
71
mastodon/src/main/res/layout/header_onboarding_login.xml
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="@style/m3_body_large"
|
||||||
|
android:paddingStart="56dp"
|
||||||
|
android:paddingEnd="24dp"
|
||||||
|
android:text="@string/login_subtitle"/>
|
||||||
|
|
||||||
|
<org.joinmastodon.android.ui.views.FloatingHintEditTextLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="56dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:paddingBottom="8dp"
|
||||||
|
app:editTextOffsetY="8dp"
|
||||||
|
android:background="@drawable/rect_4dp"
|
||||||
|
android:backgroundTint="?colorM3SurfaceVariant">
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/search_edit"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@null"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
|
android:textColor="?colorM3OnSurfaceVariant"
|
||||||
|
android:textColorHint="?colorM3OnSurfaceVariant"
|
||||||
|
android:inputType="textUri"
|
||||||
|
android:importantForAutofill="no"
|
||||||
|
android:paddingStart="48dp"
|
||||||
|
android:layout_marginEnd="52dp"
|
||||||
|
android:drawablePadding="16dp"
|
||||||
|
android:textAppearance="@style/m3_body_large"
|
||||||
|
android:hint="@string/server_url"/>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="44dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:layout_gravity="start|center_vertical"
|
||||||
|
android:scaleType="center"
|
||||||
|
android:importantForAccessibility="no"
|
||||||
|
android:tint="?colorM3OnSurfaceVariant"
|
||||||
|
android:src="@drawable/ic_m3_search"/>
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/search_clear"
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:layout_marginEnd="6dp"
|
||||||
|
android:background="?android:selectableItemBackgroundBorderless"
|
||||||
|
android:layout_gravity="center_vertical|end"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible"
|
||||||
|
android:contentDescription="@string/clear"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:src="@drawable/ic_m3_cancel"/>
|
||||||
|
|
||||||
|
</org.joinmastodon.android.ui.views.FloatingHintEditTextLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -174,7 +174,7 @@
|
|||||||
style="?secondaryButtonStyle"
|
style="?secondaryButtonStyle"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:contentDescription="@string/reject_follow_request"
|
android:contentDescription="@string/sk_reject_follow_request"
|
||||||
android:drawableStart="@drawable/ic_fluent_dismiss_24_filled"
|
android:drawableStart="@drawable/ic_fluent_dismiss_24_filled"
|
||||||
android:singleLine="true" />
|
android:singleLine="true" />
|
||||||
|
|
||||||
@@ -204,7 +204,7 @@
|
|||||||
android:id="@+id/accept_btn"
|
android:id="@+id/accept_btn"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:contentDescription="@string/accept_follow_request"
|
android:contentDescription="@string/sk_accept_follow_request"
|
||||||
android:drawableStart="@drawable/ic_fluent_checkmark_24_filled"
|
android:drawableStart="@drawable/ic_fluent_checkmark_24_filled"
|
||||||
android:singleLine="true" />
|
android:singleLine="true" />
|
||||||
|
|
||||||
|
|||||||
53
mastodon/src/main/res/layout/item_instance_login.xml
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:paddingEnd="24dp"
|
||||||
|
android:paddingTop="12dp"
|
||||||
|
android:paddingBottom="12dp"
|
||||||
|
android:background="?colorM3SurfaceVariant">
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/radiobtn"
|
||||||
|
android:layout_width="28dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_marginEnd="23dp"
|
||||||
|
android:layout_marginStart="-3dp"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:buttonTint="@color/m3_radiobutton_tint"
|
||||||
|
android:background="@null"
|
||||||
|
android:focusable="false"
|
||||||
|
android:clickable="false"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_toEndOf="@id/radiobtn"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:textAppearance="@style/m3_body_large"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:minHeight="24dp"
|
||||||
|
android:textColor="?colorM3OnSurface"
|
||||||
|
tools:text="mastodon.social"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/description"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_toEndOf="@id/radiobtn"
|
||||||
|
android:layout_below="@id/title"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:textAppearance="@style/m3_body_medium"
|
||||||
|
android:textColor="?colorM3OnSurfaceVariant"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:lineSpacingExtra="4sp"
|
||||||
|
tools:text="General-purpose server run by the lead developer of Mastodon"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:text="@string/settings_color_picker"/>
|
android:text="@string/sk_settings_color_picker"/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/color_picker_button"
|
android:id="@+id/color_picker_button"
|
||||||
@@ -41,6 +41,6 @@
|
|||||||
android:stateListAnimator="@null"
|
android:stateListAnimator="@null"
|
||||||
android:textColor="?android:textColorPrimary"
|
android:textColor="?android:textColorPrimary"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
tools:text="@string/pink_color" />
|
tools:text="@string/sk_color_theme_pink" />
|
||||||
|
|
||||||
</org.joinmastodon.android.ui.views.AutoOrientationLinearLayout>
|
</org.joinmastodon.android.ui.views.AutoOrientationLinearLayout>
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
android:layout_marginBottom="16dp"
|
android:layout_marginBottom="16dp"
|
||||||
android:textAppearance="@style/m3_body_medium"
|
android:textAppearance="@style/m3_body_medium"
|
||||||
tools:text="@string/update_available"/>
|
tools:text="@string/sk_update_available"/>
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<item android:id="@+id/purple_color" android:title="@string/purple_color"/>
|
<item android:id="@+id/purple_color" android:title="@string/sk_color_theme_purple"/>
|
||||||
<item android:id="@+id/pink_color" android:title="@string/pink_color"/>
|
<item android:id="@+id/pink_color" android:title="@string/sk_color_theme_pink"/>
|
||||||
<item android:id="@+id/green_color" android:title="@string/green_color"/>
|
<item android:id="@+id/green_color" android:title="@string/sk_color_theme_green"/>
|
||||||
<item android:id="@+id/blue_color" android:title="@string/blue_color"/>
|
<item android:id="@+id/blue_color" android:title="@string/sk_color_theme_blue"/>
|
||||||
<item android:id="@+id/orange_color" android:title="@string/orange_color"/>
|
<item android:id="@+id/orange_color" android:title="@string/sk_color_theme_brown"/>
|
||||||
<item android:id="@+id/yellow_color" android:title="@string/yellow_color"/>
|
<item android:id="@+id/yellow_color" android:title="@string/sk_color_theme_yellow"/>
|
||||||
|
<item android:id="@+id/m3_color" android:title="@string/sk_color_theme_material_you"/>
|
||||||
</menu>
|
</menu>
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
android:title="@string/visibility_public"/>
|
android:title="@string/visibility_public"/>
|
||||||
<item android:id="@+id/vis_unlisted"
|
<item android:id="@+id/vis_unlisted"
|
||||||
android:icon="@drawable/ic_fluent_people_community_24_regular"
|
android:icon="@drawable/ic_fluent_people_community_24_regular"
|
||||||
android:title="@string/visibility_unlisted"/>
|
android:title="@string/sk_visibility_unlisted"/>
|
||||||
<item android:id="@+id/vis_followers"
|
<item android:id="@+id/vis_followers"
|
||||||
android:icon="@drawable/ic_fluent_people_checkmark_24_regular"
|
android:icon="@drawable/ic_fluent_people_checkmark_24_regular"
|
||||||
android:title="@string/visibility_followers_only"/>
|
android:title="@string/visibility_followers_only"/>
|
||||||
|
|||||||
@@ -4,5 +4,6 @@
|
|||||||
android:id="@+id/follow_requests"
|
android:id="@+id/follow_requests"
|
||||||
android:icon="@drawable/ic_follow_requests_24_badged"
|
android:icon="@drawable/ic_follow_requests_24_badged"
|
||||||
android:showAsAction="always"
|
android:showAsAction="always"
|
||||||
android:title="@string/follow_requests" />
|
android:visible="false"
|
||||||
|
android:title="@string/sk_follow_requests" />
|
||||||
</menu>
|
</menu>
|
||||||
@@ -2,9 +2,9 @@
|
|||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<item android:id="@+id/edit" android:title="@string/edit"/>
|
<item android:id="@+id/edit" android:title="@string/edit"/>
|
||||||
<item android:id="@+id/delete" android:title="@string/delete"/>
|
<item android:id="@+id/delete" android:title="@string/delete"/>
|
||||||
<item android:id="@+id/delete_and_redraft" android:title="@string/delete_and_redraft"/>
|
<item android:id="@+id/delete_and_redraft" android:title="@string/sk_delete_and_redraft"/>
|
||||||
<item android:id="@+id/pin" android:title="@string/pin_post"/>
|
<item android:id="@+id/pin" android:title="@string/sk_pin_post"/>
|
||||||
<item android:id="@+id/unpin" android:title="@string/unpin_post"/>
|
<item android:id="@+id/unpin" android:title="@string/sk_unpin_post"/>
|
||||||
<item android:id="@+id/mute" android:title="@string/mute_user"/>
|
<item android:id="@+id/mute" android:title="@string/mute_user"/>
|
||||||
<item android:id="@+id/block" android:title="@string/block_user"/>
|
<item android:id="@+id/block" android:title="@string/block_user"/>
|
||||||
<item android:id="@+id/block_domain" android:title="@string/block_domain"/>
|
<item android:id="@+id/block_domain" android:title="@string/block_domain"/>
|
||||||
|
|||||||
@@ -6,6 +6,6 @@
|
|||||||
<item android:id="@+id/report" android:title="@string/report_user"/>
|
<item android:id="@+id/report" android:title="@string/report_user"/>
|
||||||
<item android:id="@+id/block_domain" android:title="@string/block_domain"/>
|
<item android:id="@+id/block_domain" android:title="@string/block_domain"/>
|
||||||
<item android:id="@+id/hide_boosts" android:title="@string/hide_boosts_from_user"/>
|
<item android:id="@+id/hide_boosts" android:title="@string/hide_boosts_from_user"/>
|
||||||
<item android:id="@+id/manage_user_lists" android:title="@string/lists_with_user"/>
|
<item android:id="@+id/manage_user_lists" android:title="@string/sk_lists_with_user"/>
|
||||||
<item android:id="@+id/open_in_browser" android:title="@string/open_in_browser"/>
|
<item android:id="@+id/open_in_browser" android:title="@string/open_in_browser"/>
|
||||||
</menu>
|
</menu>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@drawable/ic_launcher_background"/>
|
<background android:drawable="@color/shortcut_icon_background"/>
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||||
</adaptive-icon>
|
</adaptive-icon>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@drawable/ic_launcher_background"/>
|
<background android:drawable="@color/shortcut_icon_background"/>
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||||
</adaptive-icon>
|
</adaptive-icon>
|
||||||
@@ -3,9 +3,7 @@
|
|||||||
<string name="get_started">الخطوات الأولى</string>
|
<string name="get_started">الخطوات الأولى</string>
|
||||||
<string name="log_in">تسجيلُ الدخول</string>
|
<string name="log_in">تسجيلُ الدخول</string>
|
||||||
<string name="next">التالي</string>
|
<string name="next">التالي</string>
|
||||||
<string name="loading_instance">يَجري الحُصُول على معلومات المَثيل…</string>
|
|
||||||
<string name="error">خطأ</string>
|
<string name="error">خطأ</string>
|
||||||
<string name="not_a_mastodon_instance">%s لا يبدو كمثيل ماستدون.</string>
|
|
||||||
<string name="ok">حسنًا</string>
|
<string name="ok">حسنًا</string>
|
||||||
<string name="preparing_auth">جَارٍ الإعدَادُ لِلمُصادَقَة…</string>
|
<string name="preparing_auth">جَارٍ الإعدَادُ لِلمُصادَقَة…</string>
|
||||||
<string name="finishing_auth">يُنهي المصادقة…</string>
|
<string name="finishing_auth">يُنهي المصادقة…</string>
|
||||||
|
|||||||
3
mastodon/src/main/res/values-ar-rSA/strings_sk.xml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
</resources>
|
||||||
@@ -1,5 +1,14 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
<string name="get_started">Пачаць</string>
|
||||||
|
<string name="log_in">Увайсці</string>
|
||||||
|
<string name="next">Далей</string>
|
||||||
|
<string name="error">Памылка</string>
|
||||||
|
<string name="ok">Добра</string>
|
||||||
|
<string name="notifications">Апавяшчэнні</string>
|
||||||
|
<string name="share_toot_title">Абагуліць</string>
|
||||||
|
<string name="settings">Налады</string>
|
||||||
|
<string name="cancel">Скасаваць</string>
|
||||||
<!-- translators: %,d is a valid placeholder, it formats the number with locale-dependent grouping separators -->
|
<!-- translators: %,d is a valid placeholder, it formats the number with locale-dependent grouping separators -->
|
||||||
<!-- %s is version like 1.2.3 -->
|
<!-- %s is version like 1.2.3 -->
|
||||||
<!-- %s is version like 1.2.3 -->
|
<!-- %s is version like 1.2.3 -->
|
||||||
|
|||||||
3
mastodon/src/main/res/values-be-rBY/strings_sk.xml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
</resources>
|
||||||
3
mastodon/src/main/res/values-bn-rBD/strings_sk.xml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
</resources>
|
||||||
@@ -3,9 +3,7 @@
|
|||||||
<string name="get_started">Kreni</string>
|
<string name="get_started">Kreni</string>
|
||||||
<string name="log_in">Loguj se</string>
|
<string name="log_in">Loguj se</string>
|
||||||
<string name="next">Dalje</string>
|
<string name="next">Dalje</string>
|
||||||
<string name="loading_instance">Čekamo potrebne informacije…</string>
|
|
||||||
<string name="error">Greška</string>
|
<string name="error">Greška</string>
|
||||||
<string name="not_a_mastodon_instance">%s ne izgleda kao Mastodon platforma.</string>
|
|
||||||
<string name="ok">OK</string>
|
<string name="ok">OK</string>
|
||||||
<string name="preparing_auth">Pripremamo autorizaciju…</string>
|
<string name="preparing_auth">Pripremamo autorizaciju…</string>
|
||||||
<string name="finishing_auth">Završavamo autorizaciju…</string>
|
<string name="finishing_auth">Završavamo autorizaciju…</string>
|
||||||
|
|||||||
3
mastodon/src/main/res/values-bs-rBA/strings_sk.xml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
</resources>
|
||||||
@@ -3,17 +3,15 @@
|
|||||||
<string name="get_started">Comença</string>
|
<string name="get_started">Comença</string>
|
||||||
<string name="log_in">Inicia sessió</string>
|
<string name="log_in">Inicia sessió</string>
|
||||||
<string name="next">Següent</string>
|
<string name="next">Següent</string>
|
||||||
<string name="loading_instance">Obtenint informació sobre la instància…</string>
|
|
||||||
<string name="error">Error</string>
|
<string name="error">Error</string>
|
||||||
<string name="not_a_mastodon_instance">Sembla que %s no és una instància Mastodon.</string>
|
|
||||||
<string name="ok">D\'acord</string>
|
<string name="ok">D\'acord</string>
|
||||||
<string name="preparing_auth">Preparant a l\'autenticació…</string>
|
<string name="preparing_auth">Preparant l\'autenticació…</string>
|
||||||
<string name="finishing_auth">Finalitzant autentificació…</string>
|
<string name="finishing_auth">Finalitzant l\'autenticació…</string>
|
||||||
<string name="user_boosted">%s ha impulsat</string>
|
<string name="user_boosted">%s ha impulsat</string>
|
||||||
<string name="in_reply_to">En resposta a %s</string>
|
<string name="in_reply_to">En resposta a %s</string>
|
||||||
<string name="notifications">Notificacions</string>
|
<string name="notifications">Notificacions</string>
|
||||||
<string name="user_followed_you">t\'ha seguit</string>
|
<string name="user_followed_you">t\'ha seguit</string>
|
||||||
<string name="user_sent_follow_request">t\'ha enviat una sol·licitud de seguiment</string>
|
<string name="user_sent_follow_request">ha sol·licitat seguir-te</string>
|
||||||
<string name="user_favorited">ha afavorit la teva publicació</string>
|
<string name="user_favorited">ha afavorit la teva publicació</string>
|
||||||
<string name="notification_boosted">ha impulsat la teva publicació</string>
|
<string name="notification_boosted">ha impulsat la teva publicació</string>
|
||||||
<string name="poll_ended">l\'enquesta ha finalitzat</string>
|
<string name="poll_ended">l\'enquesta ha finalitzat</string>
|
||||||
@@ -24,7 +22,7 @@
|
|||||||
<string name="share_toot_title">Comparteix</string>
|
<string name="share_toot_title">Comparteix</string>
|
||||||
<string name="settings">Configuració</string>
|
<string name="settings">Configuració</string>
|
||||||
<string name="publish">Publica</string>
|
<string name="publish">Publica</string>
|
||||||
<string name="discard_draft">Voleu descartar l\'esborrany?</string>
|
<string name="discard_draft">Vols descartar l\'esborrany?</string>
|
||||||
<string name="discard">Descarta</string>
|
<string name="discard">Descarta</string>
|
||||||
<string name="cancel">Cancel·la</string>
|
<string name="cancel">Cancel·la</string>
|
||||||
<plurals name="followers">
|
<plurals name="followers">
|
||||||
@@ -49,14 +47,14 @@
|
|||||||
<string name="mention_user">Menciona %s</string>
|
<string name="mention_user">Menciona %s</string>
|
||||||
<string name="share_user">Comparteix %s</string>
|
<string name="share_user">Comparteix %s</string>
|
||||||
<string name="mute_user">Silencia %s</string>
|
<string name="mute_user">Silencia %s</string>
|
||||||
<string name="unmute_user">Deixar de silenciar %s</string>
|
<string name="unmute_user">Deixa de silenciar %s</string>
|
||||||
<string name="block_user">Bloca %s</string>
|
<string name="block_user">Bloca %s</string>
|
||||||
<string name="unblock_user">Desbloca %s</string>
|
<string name="unblock_user">Desbloca %s</string>
|
||||||
<string name="report_user">Denuncia %s</string>
|
<string name="report_user">Denuncia %s</string>
|
||||||
<string name="block_domain">Bloca %s</string>
|
<string name="block_domain">Bloca %s</string>
|
||||||
<string name="unblock_domain">Desbloca %s</string>
|
<string name="unblock_domain">Desbloca %s</string>
|
||||||
<plurals name="x_posts">
|
<plurals name="x_posts">
|
||||||
<item quantity="one">%,d entrada</item>
|
<item quantity="one">%,d publicació</item>
|
||||||
<item quantity="other">%,d publicacions</item>
|
<item quantity="other">%,d publicacions</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="profile_joined">S\'ha unit</string>
|
<string name="profile_joined">S\'ha unit</string>
|
||||||
@@ -101,12 +99,12 @@
|
|||||||
<item quantity="other">%,d votants</item>
|
<item quantity="other">%,d votants</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="poll_closed">Finalitzada</string>
|
<string name="poll_closed">Finalitzada</string>
|
||||||
<string name="confirm_mute_title">Silenciar el compte</string>
|
<string name="confirm_mute_title">Silencia el compte</string>
|
||||||
<string name="confirm_mute">Confirma per silenciar %s</string>
|
<string name="confirm_mute">Confirma per a silenciar %s</string>
|
||||||
<string name="do_mute">Silenciar</string>
|
<string name="do_mute">Silencia</string>
|
||||||
<string name="confirm_unmute_title">Deixar de silenciar el compte</string>
|
<string name="confirm_unmute_title">Deixar de silenciar el compte</string>
|
||||||
<string name="confirm_unmute">Confirma per deixar de silenciar %s</string>
|
<string name="confirm_unmute">Confirma per deixar de silenciar %s</string>
|
||||||
<string name="do_unmute">Deixar de silenciar</string>
|
<string name="do_unmute">Deixa de silenciar</string>
|
||||||
<string name="confirm_block_title">Bloca el compte</string>
|
<string name="confirm_block_title">Bloca el compte</string>
|
||||||
<string name="confirm_block_domain_title">Bloca el domini</string>
|
<string name="confirm_block_domain_title">Bloca el domini</string>
|
||||||
<string name="confirm_block">Confirma per blocar %s</string>
|
<string name="confirm_block">Confirma per blocar %s</string>
|
||||||
@@ -135,12 +133,12 @@
|
|||||||
<string name="all_notifications">Totes</string>
|
<string name="all_notifications">Totes</string>
|
||||||
<string name="mentions">Mencions</string>
|
<string name="mentions">Mencions</string>
|
||||||
<plurals name="x_people_talking">
|
<plurals name="x_people_talking">
|
||||||
<item quantity="one">%d persona parla</item>
|
<item quantity="one">%d persona està parlant-ne</item>
|
||||||
<item quantity="other">%d persones estan parlant</item>
|
<item quantity="other">%d persones estan parlant-ne</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="discussed_x_times">
|
<plurals name="discussed_x_times">
|
||||||
<item quantity="one">S\'ha comentat %d cop</item>
|
<item quantity="one">S\'ha comentat %d vegada</item>
|
||||||
<item quantity="other">S\'ha comentat %d cops</item>
|
<item quantity="other">S\'ha comentat %d vegades</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="report_title">Denuncia %s</string>
|
<string name="report_title">Denuncia %s</string>
|
||||||
<string name="report_choose_reason">Quin és el problema amb aquesta publicació?</string>
|
<string name="report_choose_reason">Quin és el problema amb aquesta publicació?</string>
|
||||||
@@ -160,7 +158,7 @@
|
|||||||
<string name="report_choose_posts_subtitle">Selecciona tots els aplicables</string>
|
<string name="report_choose_posts_subtitle">Selecciona tots els aplicables</string>
|
||||||
<string name="report_comment_title">Hi ha res més que hauríem de saber?</string>
|
<string name="report_comment_title">Hi ha res més que hauríem de saber?</string>
|
||||||
<string name="report_comment_hint">Comentaris addicionals</string>
|
<string name="report_comment_hint">Comentaris addicionals</string>
|
||||||
<string name="sending_report">Enviant informe…</string>
|
<string name="sending_report">S\'està enviant l\'informe…</string>
|
||||||
<string name="report_sent_title">Gràcies per informar, ho investigarem.</string>
|
<string name="report_sent_title">Gràcies per informar, ho investigarem.</string>
|
||||||
<string name="report_sent_subtitle">Mentre ho revisem, pots prendre mesures contra %s.</string>
|
<string name="report_sent_subtitle">Mentre ho revisem, pots prendre mesures contra %s.</string>
|
||||||
<string name="unfollow_user">Deixar de seguir %s</string>
|
<string name="unfollow_user">Deixar de seguir %s</string>
|
||||||
@@ -176,7 +174,7 @@
|
|||||||
<string name="instance_rules_title">Algunes normes bàsiques</string>
|
<string name="instance_rules_title">Algunes normes bàsiques</string>
|
||||||
<string name="instance_rules_subtitle">Pren un minut per revisar les normes establertes i aplicades pels administradors de %s.</string>
|
<string name="instance_rules_subtitle">Pren un minut per revisar les normes establertes i aplicades pels administradors de %s.</string>
|
||||||
<string name="signup_title">Deixa que et posem en marxa a %s</string>
|
<string name="signup_title">Deixa que et posem en marxa a %s</string>
|
||||||
<string name="edit_photo">editar</string>
|
<string name="edit_photo">edita</string>
|
||||||
<string name="display_name">nom visible</string>
|
<string name="display_name">nom visible</string>
|
||||||
<string name="username">nom d\'usuari</string>
|
<string name="username">nom d\'usuari</string>
|
||||||
<string name="email">correu electrònic</string>
|
<string name="email">correu electrònic</string>
|
||||||
@@ -223,9 +221,9 @@
|
|||||||
<string name="notification_type_mention">Mencions</string>
|
<string name="notification_type_mention">Mencions</string>
|
||||||
<string name="notification_type_poll">Enquestes</string>
|
<string name="notification_type_poll">Enquestes</string>
|
||||||
<string name="choose_account">Selecciona un compte</string>
|
<string name="choose_account">Selecciona un compte</string>
|
||||||
<string name="err_not_logged_in">Si us plau, inicia sessió primer a Mastodon</string>
|
<string name="err_not_logged_in">Primer inicia sessió a Mastodon</string>
|
||||||
<plurals name="cant_add_more_than_x_attachments">
|
<plurals name="cant_add_more_than_x_attachments">
|
||||||
<item quantity="one">No pots afegir més de %d fitxer multimèdia</item>
|
<item quantity="one">No pots afegir més d\'%d fitxer multimèdia</item>
|
||||||
<item quantity="other">No pots afegir més de %d fitxers multimèdia</item>
|
<item quantity="other">No pots afegir més de %d fitxers multimèdia</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="media_attachment_unsupported_type">El tipus de fitxer %s no és compatible</string>
|
<string name="media_attachment_unsupported_type">El tipus de fitxer %s no és compatible</string>
|
||||||
@@ -236,8 +234,8 @@
|
|||||||
<string name="theme_dark">Fosc</string>
|
<string name="theme_dark">Fosc</string>
|
||||||
<string name="theme_true_black">Mode negre pur</string>
|
<string name="theme_true_black">Mode negre pur</string>
|
||||||
<string name="settings_behavior">Comportament</string>
|
<string name="settings_behavior">Comportament</string>
|
||||||
<string name="settings_gif">Reproduir emojis i avatar animats</string>
|
<string name="settings_gif">Reprodueix emojis i avatar animats</string>
|
||||||
<string name="settings_custom_tabs">Utilitzar el navegador intern</string>
|
<string name="settings_custom_tabs">Utilitza el navegador intern</string>
|
||||||
<string name="settings_notifications">Notificacions</string>
|
<string name="settings_notifications">Notificacions</string>
|
||||||
<string name="notify_me_when">Notifica\'m quan</string>
|
<string name="notify_me_when">Notifica\'m quan</string>
|
||||||
<string name="notify_anyone">qualsevol</string>
|
<string name="notify_anyone">qualsevol</string>
|
||||||
@@ -259,7 +257,7 @@
|
|||||||
<string name="media_cache_cleared">S\'ha esborrat la memòria cau multimèdia</string>
|
<string name="media_cache_cleared">S\'ha esborrat la memòria cau multimèdia</string>
|
||||||
<string name="confirm_log_out">Segur que vols tancar la sessió?</string>
|
<string name="confirm_log_out">Segur que vols tancar la sessió?</string>
|
||||||
<string name="sensitive_content">Contingut sensible</string>
|
<string name="sensitive_content">Contingut sensible</string>
|
||||||
<string name="sensitive_content_explain">L\'autor va marcar aquest mitjà com a sensible. Toca per a mostrar-lo.</string>
|
<string name="sensitive_content_explain">L\'autor ha marcat aquest mitjà com a sensible. Toca per a mostrar-lo.</string>
|
||||||
<string name="media_hidden">Toca per a mostrar</string>
|
<string name="media_hidden">Toca per a mostrar</string>
|
||||||
<string name="avatar_description">Vés al perfil de: %s</string>
|
<string name="avatar_description">Vés al perfil de: %s</string>
|
||||||
<string name="more_options">Més opcions</string>
|
<string name="more_options">Més opcions</string>
|
||||||
@@ -368,7 +366,7 @@
|
|||||||
<string name="file_size_gb">%.2f GB</string>
|
<string name="file_size_gb">%.2f GB</string>
|
||||||
<string name="file_upload_progress">%1$s de %2$s</string>
|
<string name="file_upload_progress">%1$s de %2$s</string>
|
||||||
<string name="file_upload_time_remaining">%s restants</string>
|
<string name="file_upload_time_remaining">%s restants</string>
|
||||||
<string name="upload_error_connection_lost">El teu dispositiu ha perdut la connexió a internet</string>
|
<string name="upload_error_connection_lost">El dispositiu ha perdut la connexió a Internet</string>
|
||||||
<string name="upload_processing">S\'està processant…</string>
|
<string name="upload_processing">S\'està processant…</string>
|
||||||
<!-- %s is version like 1.2.3 -->
|
<!-- %s is version like 1.2.3 -->
|
||||||
<string name="update_available">Mastodon per a Android %s està preparat per a baixar-se.</string>
|
<string name="update_available">Mastodon per a Android %s està preparat per a baixar-se.</string>
|
||||||
@@ -380,9 +378,10 @@
|
|||||||
<string name="privacy_policy_title">Mastodon i la teva privacitat</string>
|
<string name="privacy_policy_title">Mastodon i la teva privacitat</string>
|
||||||
<string name="privacy_policy_subtitle">Tot i que l\'aplicació Mastodon no recull cap dada, el servidor mitjançant el qual et registres pot tenir una política diferent. Pren un minut per revisar i acceptar la política de privadesa de l\'aplicació Mastodon i la política de privadesa del teu servidor.</string>
|
<string name="privacy_policy_subtitle">Tot i que l\'aplicació Mastodon no recull cap dada, el servidor mitjançant el qual et registres pot tenir una política diferent. Pren un minut per revisar i acceptar la política de privadesa de l\'aplicació Mastodon i la política de privadesa del teu servidor.</string>
|
||||||
<string name="i_agree">D’acord</string>
|
<string name="i_agree">D’acord</string>
|
||||||
<!-- Missing strings -->
|
|
||||||
<string name="bookmarks">Marcadors</string>
|
|
||||||
<string name="pinned_posts">Fixat</string>
|
|
||||||
<string name="empty_list">Aquesta llista està buida</string>
|
<string name="empty_list">Aquesta llista està buida</string>
|
||||||
<string name="instance_signup_closed">Aquest servidor no accepta nous registres.</string>
|
<string name="instance_signup_closed">Aquest servidor no accepta nous registres.</string>
|
||||||
|
<string name="text_copied">Copiat al porta-retalls</string>
|
||||||
|
<string name="add_bookmark">Marca</string>
|
||||||
|
<string name="remove_bookmark">Elimina el marcador</string>
|
||||||
|
<string name="bookmarks">Marcadors</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
41
mastodon/src/main/res/values-ca-rES/strings_sk.xml
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="sk_pinned_posts">Fixat</string>
|
||||||
|
<string name="sk_delete_and_redraft">Elimina i torna a escriure</string>
|
||||||
|
<string name="sk_confirm_delete_and_redraft_title">Eliminar i tornar a escriure</string>
|
||||||
|
<string name="sk_confirm_pin_post">Vols fixar aquesta publicació al teu perfil\?</string>
|
||||||
|
<string name="sk_pinning">S\'està fixant…</string>
|
||||||
|
<string name="sk_unpin_post">Deixa de fixar</string>
|
||||||
|
<string name="sk_confirm_unpin_post_title">Deixar de fixar al perfil</string>
|
||||||
|
<string name="sk_settings_show_replies">Mostra les respostes</string>
|
||||||
|
<string name="sk_settings_load_new_posts">Carrega automàticament les publicacions noves</string>
|
||||||
|
<string name="sk_federated_timeline">Federació</string>
|
||||||
|
<string name="sk_federated_timeline_info_banner">Aquestes són les publicacions més recents de gent de la teua federació.</string>
|
||||||
|
<string name="sk_update_ready">Megalodon %s s\'ha baixat i està preparat per a instal·lar-se.</string>
|
||||||
|
<string name="sk_accept_follow_request">Accepta la sol·licitud</string>
|
||||||
|
<string name="sk_disable_marquee">Desactiva el desplaçament de text a les barres de títol</string>
|
||||||
|
<string name="sk_user_post_notifications_on">Notificacions activades per a publicacions de: %s</string>
|
||||||
|
<string name="sk_app_name">Megalodon</string>
|
||||||
|
<string name="sk_pin_post">Fixa al perfil</string>
|
||||||
|
<string name="sk_confirm_pin_post_title">Fixar al perfil</string>
|
||||||
|
<string name="sk_confirm_delete_and_redraft">Segur que vols eliminar i tornar a escriure aquesta publicació\?</string>
|
||||||
|
<string name="sk_confirm_unpin_post">Segur que vols deixar de fixar aquesta publicació\?</string>
|
||||||
|
<string name="sk_unpinning">S\'està deixant de fixar…</string>
|
||||||
|
<string name="sk_image_description">Descripció de la imatge</string>
|
||||||
|
<string name="sk_visibility_unlisted">No llistat</string>
|
||||||
|
<string name="sk_settings_show_boosts">Mostra els impulsos</string>
|
||||||
|
<string name="sk_settings_show_interaction_counts">Mostra el recompte d\'interaccions</string>
|
||||||
|
<string name="sk_settings_app_version">Megalodon v. %1$s (%2$d)</string>
|
||||||
|
<string name="sk_user_post_notifications_off">Notificacions desactivades per a publicacions de: %s</string>
|
||||||
|
<string name="sk_mark_media_as_sensitive">Marca el contingut com a sensible</string>
|
||||||
|
<string name="sk_update_available">Megalodon %s està preparat per a baixar-se.</string>
|
||||||
|
<string name="sk_check_for_update">Comprova actualitzacions</string>
|
||||||
|
<string name="sk_no_update_available">No hi ha cap actualització disponible</string>
|
||||||
|
<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">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>
|
||||||
|
</resources>
|
||||||
@@ -1,18 +1,16 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="get_started">Začít</string>
|
<string name="get_started">Začínáme</string>
|
||||||
<string name="log_in">Přihlásit se</string>
|
<string name="log_in">Přihlásit se</string>
|
||||||
<string name="next">Další</string>
|
<string name="next">Další</string>
|
||||||
<string name="loading_instance">Získávání informací o instanci…</string>
|
|
||||||
<string name="error">Chyba</string>
|
<string name="error">Chyba</string>
|
||||||
<string name="not_a_mastodon_instance">Zdá se, že %s není instancí Mastodonu.</string>
|
|
||||||
<string name="ok">OK</string>
|
<string name="ok">OK</string>
|
||||||
<string name="preparing_auth">Příprava na ověřování…</string>
|
<string name="preparing_auth">Příprava na autentizaci…</string>
|
||||||
<string name="finishing_auth">Dokončení ověřování…</string>
|
<string name="finishing_auth">Dokončení autentizace…</string>
|
||||||
<string name="user_boosted">Uživatel %s boostnul</string>
|
<string name="user_boosted">Uživatel %s boostnul</string>
|
||||||
<string name="in_reply_to">V odpovědi na %s</string>
|
<string name="in_reply_to">V odpovědi na %s</string>
|
||||||
<string name="notifications">Upozornění</string>
|
<string name="notifications">Upozornění</string>
|
||||||
<string name="user_followed_you">vás sleduje</string>
|
<string name="user_followed_you">vás začal(a) sledovat</string>
|
||||||
<string name="user_sent_follow_request">vám poslal(a) žádost o sledování</string>
|
<string name="user_sent_follow_request">vám poslal(a) žádost o sledování</string>
|
||||||
<string name="user_favorited">si oblíbil(a) váš příspěvek</string>
|
<string name="user_favorited">si oblíbil(a) váš příspěvek</string>
|
||||||
<string name="notification_boosted">boostnul(a) váš příspěvek</string>
|
<string name="notification_boosted">boostnul(a) váš příspěvek</string>
|
||||||
@@ -34,9 +32,9 @@
|
|||||||
<item quantity="other">sledujících</item>
|
<item quantity="other">sledujících</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="following">
|
<plurals name="following">
|
||||||
<item quantity="one">sledovaní</item>
|
<item quantity="one">sledovaný</item>
|
||||||
<item quantity="few">sledování</item>
|
<item quantity="few">sledovaní</item>
|
||||||
<item quantity="many">sledování</item>
|
<item quantity="many">sledovaných</item>
|
||||||
<item quantity="other">sledovaných</item>
|
<item quantity="other">sledovaných</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="posts">
|
<plurals name="posts">
|
||||||
@@ -52,10 +50,10 @@
|
|||||||
<string name="button_follow">Sledovat</string>
|
<string name="button_follow">Sledovat</string>
|
||||||
<string name="button_following">Sleduji</string>
|
<string name="button_following">Sleduji</string>
|
||||||
<string name="edit_profile">Upravit profil</string>
|
<string name="edit_profile">Upravit profil</string>
|
||||||
<string name="mention_user">Zmínit @%s</string>
|
<string name="mention_user">Zmínit %s</string>
|
||||||
<string name="share_user">Sdílet %s</string>
|
<string name="share_user">Sdílet %s</string>
|
||||||
<string name="mute_user">Skrýt %s</string>
|
<string name="mute_user">Skrýt %s</string>
|
||||||
<string name="unmute_user">Odkrýt @%s</string>
|
<string name="unmute_user">Zrušit skrytí @%s</string>
|
||||||
<string name="block_user">Blokovat %s</string>
|
<string name="block_user">Blokovat %s</string>
|
||||||
<string name="unblock_user">Odblokovat %s</string>
|
<string name="unblock_user">Odblokovat %s</string>
|
||||||
<string name="report_user">Nahlásit %s</string>
|
<string name="report_user">Nahlásit %s</string>
|
||||||
@@ -67,14 +65,14 @@
|
|||||||
<item quantity="many">%,d příspěvků</item>
|
<item quantity="many">%,d příspěvků</item>
|
||||||
<item quantity="other">%,d příspěvků</item>
|
<item quantity="other">%,d příspěvků</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="profile_joined">Účet vytvořen</string>
|
<string name="profile_joined">Připojen/a</string>
|
||||||
<string name="done">Hotovo</string>
|
<string name="done">Hotovo</string>
|
||||||
<string name="loading">Načítání…</string>
|
<string name="loading">Načítání…</string>
|
||||||
<string name="field_label">Označení</string>
|
<string name="field_label">Označení</string>
|
||||||
<string name="field_content">Obsah</string>
|
<string name="field_content">Obsah</string>
|
||||||
<string name="saving">Ukládání…</string>
|
<string name="saving">Ukládání…</string>
|
||||||
<string name="post_from_user">Příspěvek od %s</string>
|
<string name="post_from_user">Příspěvek od %s</string>
|
||||||
<string name="poll_option_hint">Možnost %d</string>
|
<string name="poll_option_hint">Volba %d</string>
|
||||||
<plurals name="x_minutes">
|
<plurals name="x_minutes">
|
||||||
<item quantity="one">%d minuta</item>
|
<item quantity="one">%d minuta</item>
|
||||||
<item quantity="few">%d minuty</item>
|
<item quantity="few">%d minuty</item>
|
||||||
@@ -108,7 +106,7 @@
|
|||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="x_hours_left">
|
<plurals name="x_hours_left">
|
||||||
<item quantity="one">Zbývá %d hodina</item>
|
<item quantity="one">Zbývá %d hodina</item>
|
||||||
<item quantity="few">Zbývá %d hodiny</item>
|
<item quantity="few">Zbývají %d hodiny</item>
|
||||||
<item quantity="many">Zbývá %d hodin</item>
|
<item quantity="many">Zbývá %d hodin</item>
|
||||||
<item quantity="other">Zbývá %d hodin</item>
|
<item quantity="other">Zbývá %d hodin</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
@@ -129,20 +127,20 @@
|
|||||||
<string name="confirm_mute">Potvrdit skrytí %s</string>
|
<string name="confirm_mute">Potvrdit skrytí %s</string>
|
||||||
<string name="do_mute">Skrýt</string>
|
<string name="do_mute">Skrýt</string>
|
||||||
<string name="confirm_unmute_title">Zrušit skrytí účtu</string>
|
<string name="confirm_unmute_title">Zrušit skrytí účtu</string>
|
||||||
<string name="confirm_unmute">Potvrďte zrušení skrytí %s</string>
|
<string name="confirm_unmute">Potvrdit zrušení skrytí %s</string>
|
||||||
<string name="do_unmute">Odkrýt</string>
|
<string name="do_unmute">Zrušit skrytí</string>
|
||||||
<string name="confirm_block_title">Blokovat účet</string>
|
<string name="confirm_block_title">Blokovat účet</string>
|
||||||
<string name="confirm_block_domain_title">Blokovat doménu</string>
|
<string name="confirm_block_domain_title">Blokovat doménu</string>
|
||||||
<string name="confirm_block">Potvrďte blokování %s</string>
|
<string name="confirm_block">Potvrdit blokování %s</string>
|
||||||
<string name="do_block">Blokovat</string>
|
<string name="do_block">Blokovat</string>
|
||||||
<string name="confirm_unblock_title">Odblokovat účet</string>
|
<string name="confirm_unblock_title">Odblokovat účet</string>
|
||||||
<string name="confirm_unblock_domain_title">Odblokovat doménu</string>
|
<string name="confirm_unblock_domain_title">Odblokovat doménu</string>
|
||||||
<string name="confirm_unblock">Potvrďte odblokování %s</string>
|
<string name="confirm_unblock">Potvrdit odblokování %s</string>
|
||||||
<string name="do_unblock">Odblokovat</string>
|
<string name="do_unblock">Odblokovat</string>
|
||||||
<string name="button_muted">Skrytý</string>
|
<string name="button_muted">Skrytý</string>
|
||||||
<string name="button_blocked">Blokovaný</string>
|
<string name="button_blocked">Blokovaný</string>
|
||||||
<string name="action_vote">Hlasovat</string>
|
<string name="action_vote">Hlasovat</string>
|
||||||
<string name="tap_to_reveal">Klepnutím zobraz</string>
|
<string name="tap_to_reveal">Klepněte pro zobrazení</string>
|
||||||
<string name="delete">Smazat</string>
|
<string name="delete">Smazat</string>
|
||||||
<string name="confirm_delete_title">Smazat příspěvek</string>
|
<string name="confirm_delete_title">Smazat příspěvek</string>
|
||||||
<string name="confirm_delete">Opravdu chcete smazat tento příspěvek?</string>
|
<string name="confirm_delete">Opravdu chcete smazat tento příspěvek?</string>
|
||||||
@@ -174,33 +172,33 @@
|
|||||||
<string name="report_choose_reason">Co je na tomto příspěvku špatně?</string>
|
<string name="report_choose_reason">Co je na tomto příspěvku špatně?</string>
|
||||||
<string name="report_choose_reason_account">Co je špatně na %s?</string>
|
<string name="report_choose_reason_account">Co je špatně na %s?</string>
|
||||||
<string name="report_choose_reason_subtitle">Vyberte nejbližší možnost</string>
|
<string name="report_choose_reason_subtitle">Vyberte nejbližší možnost</string>
|
||||||
<string name="report_reason_personal">Nelíbí se mi</string>
|
<string name="report_reason_personal">Nelíbí se mi to</string>
|
||||||
<string name="report_reason_personal_subtitle">Není to něco, co chcete vidět</string>
|
<string name="report_reason_personal_subtitle">Není to něco, co chcete vidět</string>
|
||||||
<string name="report_reason_spam">Je to spam</string>
|
<string name="report_reason_spam">Je to spam</string>
|
||||||
<string name="report_reason_spam_subtitle">Škodlivé odkazy, falešné interakce nebo opakované odpovědi</string>
|
<string name="report_reason_spam_subtitle">Škodlivé odkazy, falešné interakce nebo opakované odpovědi</string>
|
||||||
<string name="report_reason_violation">Porušuje pravidla serveru</string>
|
<string name="report_reason_violation">Porušuje to pravidla serveru</string>
|
||||||
<string name="report_reason_violation_subtitle">Máte za to, že porušuje konkrétní pravidla</string>
|
<string name="report_reason_violation_subtitle">Máte za to, že to porušuje konkrétní pravidla</string>
|
||||||
<string name="report_reason_other">Jde o něco jiného</string>
|
<string name="report_reason_other">It\'s something else</string>
|
||||||
<string name="report_reason_other_subtitle">Problém neodpovídá ostatním kategoriím</string>
|
<string name="report_reason_other_subtitle">Problém neodpovídá ostatním kategoriím</string>
|
||||||
<string name="report_choose_rule">Která pravidla porušuje?</string>
|
<string name="report_choose_rule">Která pravidla to porušuje?</string>
|
||||||
<string name="report_choose_rule_subtitle">Vyberte všechna relevantní</string>
|
<string name="report_choose_rule_subtitle">Vyberte všechna relevantní</string>
|
||||||
<string name="report_choose_posts">Existují příspěvky dokládající toto hlášení?</string>
|
<string name="report_choose_posts">Existují příspěvky dokládající toto hlášení?</string>
|
||||||
<string name="report_choose_posts_subtitle">Vyberte všechna relevantní</string>
|
<string name="report_choose_posts_subtitle">Vyberte všechny relevantní</string>
|
||||||
<string name="report_comment_title">Je ještě něco jiného, co bychom měli vědět?</string>
|
<string name="report_comment_title">Je ještě něco jiného, co bychom měli vědět?</string>
|
||||||
<string name="report_comment_hint">Dodatečné komentáře</string>
|
<string name="report_comment_hint">Další komentáře</string>
|
||||||
<string name="sending_report">Odesílání hlášení…</string>
|
<string name="sending_report">Odesílání hlášení…</string>
|
||||||
<string name="report_sent_title">Děkujeme za nahlášení, podíváme se na to.</string>
|
<string name="report_sent_title">Děkujeme za nahlášení, podíváme se na to.</string>
|
||||||
<string name="report_sent_subtitle">Zatímco to posuzujeme, můžete podniknout kroky proti %s.</string>
|
<string name="report_sent_subtitle">Zatímco to posuzujeme, můžete podniknout akce proti %s.</string>
|
||||||
<string name="unfollow_user">Přestat sledovat %s</string>
|
<string name="unfollow_user">Přestat sledovat %s</string>
|
||||||
<string name="unfollow">Přestat sledovat</string>
|
<string name="unfollow">Přestat sledovat</string>
|
||||||
<string name="mute_user_explain">Neuvidíte jejich příspěvky nebo boostnutí v domovském kanálu. Nebudou vědět, že jsou skrytí.</string>
|
<string name="mute_user_explain">Neuvidíte příspěvky nebo boosty tohoto uživatele ve svém domovském kanálu. Nebude vědět, že je skryt.</string>
|
||||||
<string name="block_user_explain">Už nebudou moci sledovat nebo vidět vaše příspěvky, ale mohou vidět, že byli blokováni.</string>
|
<string name="block_user_explain">Tento uživatel vás již nebude moci sledovat ani vidět vaše příspěvky, ale může zjistit, že je blokován.</string>
|
||||||
<string name="report_personal_title">Nechcete tohle vidět?</string>
|
<string name="report_personal_title">Nechcete tohle vidět?</string>
|
||||||
<string name="report_personal_subtitle">Když uvidíte něco, co se vám nelíbí na Mastodonu, můžete odstranit tuto osobu ze svého zážitku.</string>
|
<string name="report_personal_subtitle">Když uvidíte něco, co se vám nelíbí na Mastodonu, můžete odstranit tuto osobu ze svého zážitku.</string>
|
||||||
<string name="back">Zpět</string>
|
<string name="back">Zpět</string>
|
||||||
<string name="instance_catalog_title">Mastodon tvoří uživatelé z různých serverů.</string>
|
<string name="instance_catalog_title">Mastodon tvoří uživatelé z různých serverů.</string>
|
||||||
<string name="instance_catalog_subtitle">Vyberte si server podle na svých zájmů, regionu nebo obecného účelu. Stále se můžete spojit se všemi bez ohledu na server.</string>
|
<string name="instance_catalog_subtitle">Vyberte si server podle na svých zájmů, regionu nebo obecného účelu. Stále se můžete spojit se všemi bez ohledu na server.</string>
|
||||||
<string name="search_communities">Hledat nebo zadat URL</string>
|
<string name="search_communities">Hledat server nebo zadat URL</string>
|
||||||
<string name="instance_rules_title">Některá základní pravidla</string>
|
<string name="instance_rules_title">Některá základní pravidla</string>
|
||||||
<string name="instance_rules_subtitle">Udělejte si chvíli čas a zkontrolujte pravidla, která admini %s nastavili a vynucují.</string>
|
<string name="instance_rules_subtitle">Udělejte si chvíli čas a zkontrolujte pravidla, která admini %s nastavili a vynucují.</string>
|
||||||
<string name="signup_title">Pojďme si nastavit %s</string>
|
<string name="signup_title">Pojďme si nastavit %s</string>
|
||||||
@@ -227,19 +225,19 @@
|
|||||||
<string name="confirm_email_subtitle">Klepněte na odkaz, který jsme vám poslali e-mailem, abyste účet ověřili.</string>
|
<string name="confirm_email_subtitle">Klepněte na odkaz, který jsme vám poslali e-mailem, abyste účet ověřili.</string>
|
||||||
<string name="resend">Poslat znovu</string>
|
<string name="resend">Poslat znovu</string>
|
||||||
<string name="open_email_app">Otevřít e-mailovou aplikaci</string>
|
<string name="open_email_app">Otevřít e-mailovou aplikaci</string>
|
||||||
<string name="resent_email">Potvrzující e-mail odeslán</string>
|
<string name="resent_email">Potvrzující e-mail byl odeslán</string>
|
||||||
<string name="compose_hint">Napište nebo vložte, co máte na mysli</string>
|
<string name="compose_hint">Napište nebo vložte, co máte na mysli</string>
|
||||||
<string name="content_warning">Varování o obsahu</string>
|
<string name="content_warning">Varování o obsahu</string>
|
||||||
<string name="add_image_description">Přidat popis obrázku…</string>
|
<string name="add_image_description">Přidat popis obrázku…</string>
|
||||||
<string name="retry_upload">Opakovat nahrání</string>
|
<string name="retry_upload">Opakovat nahrání</string>
|
||||||
<string name="edit_image">Upravit obrázek</string>
|
<string name="edit_image">Upravit obrázek</string>
|
||||||
<string name="save">Uložit</string>
|
<string name="save">Uložit</string>
|
||||||
<string name="add_alt_text">Přidat alt text</string>
|
<string name="add_alt_text">Přidat alternativní text</string>
|
||||||
<string name="alt_text_subtitle">Alt text popisuje obrázky pro lidi se špatným nebo žádným zrakem. Pokuste se zahrnout jen tolik obsahu, kolik je potřeba pro pochopení kontextu.</string>
|
<string name="alt_text_subtitle">Alternativní text popisuje obrázky pro lidi se špatným zrakem nebo bez zraku. Pokuste se zahrnout jen tolik obsahu, kolik je potřeba pro pochopení kontextu.</string>
|
||||||
<string name="alt_text_hint">Např. podezřívavě rozhlížející se pes se zúženýma očima namířenýma na kameru.</string>
|
<string name="alt_text_hint">např. Podezřívavě rozhlížející se pes se zúženýma očima namířenýma na kameru.</string>
|
||||||
<string name="visibility_public">Veřejný</string>
|
<string name="visibility_public">Veřejné</string>
|
||||||
<string name="visibility_followers_only">Pouze sledující</string>
|
<string name="visibility_followers_only">Pouze sledující</string>
|
||||||
<string name="visibility_private">Pouze lidé, které zmíním</string>
|
<string name="visibility_private">Pouze zmínění lidé</string>
|
||||||
<string name="search_all">Vše</string>
|
<string name="search_all">Vše</string>
|
||||||
<string name="search_people">Lidé</string>
|
<string name="search_people">Lidé</string>
|
||||||
<string name="recent_searches">Nedávná hledání</string>
|
<string name="recent_searches">Nedávná hledání</string>
|
||||||
@@ -247,53 +245,53 @@
|
|||||||
<string name="skip">Přeskočit</string>
|
<string name="skip">Přeskočit</string>
|
||||||
<string name="notification_type_follow">Noví sledující</string>
|
<string name="notification_type_follow">Noví sledující</string>
|
||||||
<string name="notification_type_favorite">Oblíbené</string>
|
<string name="notification_type_favorite">Oblíbené</string>
|
||||||
<string name="notification_type_reblog">Boostnutí</string>
|
<string name="notification_type_reblog">Boosty</string>
|
||||||
<string name="notification_type_mention">Zmínky</string>
|
<string name="notification_type_mention">Zmínky</string>
|
||||||
<string name="notification_type_poll">Ankety</string>
|
<string name="notification_type_poll">Ankety</string>
|
||||||
<string name="choose_account">Vybrat účet</string>
|
<string name="choose_account">Vybrat účet</string>
|
||||||
<string name="err_not_logged_in">Nejprve se přihlaste do Mastodonu</string>
|
<string name="err_not_logged_in">Nejprve se přihlaste do Mastodonu</string>
|
||||||
<plurals name="cant_add_more_than_x_attachments">
|
<plurals name="cant_add_more_than_x_attachments">
|
||||||
<item quantity="one">Nelze přidat více než %d multimediálních příloh</item>
|
<item quantity="one">Nelze přidat více než %d multimediální přílohu</item>
|
||||||
<item quantity="few">Nelze přidat více než %d multimediální přílohy</item>
|
<item quantity="few">Nelze přidat více než %d multimediální přílohy</item>
|
||||||
<item quantity="many">Nelze přidat více než %d multimediálních příloh</item>
|
<item quantity="many">Nelze přidat více než %d multimediálních příloh</item>
|
||||||
<item quantity="other">Nelze přidat více než %d multimediálních příloh</item>
|
<item quantity="other">Nelze přidat více než %d multimediálních příloh</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="media_attachment_unsupported_type">Soubor %s nepatří mezi podporované typy</string>
|
<string name="media_attachment_unsupported_type">Soubor %s nepatří mezi podporované typy</string>
|
||||||
<string name="media_attachment_too_big">Soubor %1$s překračuje limit velikosti %2$s MB</string>
|
<string name="media_attachment_too_big">Soubor %1$s překračuje limit velikosti %2$s MB</string>
|
||||||
<string name="settings_theme">Vizuální podoba</string>
|
<string name="settings_theme">Vizuální vzhled</string>
|
||||||
<string name="theme_auto">Automatická</string>
|
<string name="theme_auto">Automatická</string>
|
||||||
<string name="theme_light">Světlá</string>
|
<string name="theme_light">Světlý</string>
|
||||||
<string name="theme_dark">Tmavá</string>
|
<string name="theme_dark">Tmavý</string>
|
||||||
<string name="theme_true_black">Režim skutečně černé</string>
|
<string name="theme_true_black">Režim skutečně černé</string>
|
||||||
<string name="settings_behavior">Chování</string>
|
<string name="settings_behavior">Chování</string>
|
||||||
<string name="settings_gif">Přehrávat animované avatary a emoji</string>
|
<string name="settings_gif">Přehrávat animované avatary a emoji</string>
|
||||||
<string name="settings_custom_tabs">Používat interní prohlížeč</string>
|
<string name="settings_custom_tabs">Používat prohlížeč v aplikaci</string>
|
||||||
<string name="settings_notifications">Upozornění</string>
|
<string name="settings_notifications">Oznámení</string>
|
||||||
<string name="notify_me_when">Upozornit mě, když</string>
|
<string name="notify_me_when">Upozornit mě, když</string>
|
||||||
<string name="notify_anyone">kdokoliv</string>
|
<string name="notify_anyone">kdokoliv</string>
|
||||||
<string name="notify_follower">sledující</string>
|
<string name="notify_follower">sledující</string>
|
||||||
<string name="notify_followed">někdo, koho sleduji</string>
|
<string name="notify_followed">někdo, koho sleduji</string>
|
||||||
<string name="notify_none">nikoho</string>
|
<string name="notify_none">nikoho</string>
|
||||||
<string name="notify_favorites">Oblíbil si můj příspěvek</string>
|
<string name="notify_favorites">Oblíbí si můj příspěvek</string>
|
||||||
<string name="notify_follow">Sleduje mě</string>
|
<string name="notify_follow">Začne mě sledovat</string>
|
||||||
<string name="notify_reblog">Boostnul můj příspěvek</string>
|
<string name="notify_reblog">Boostne můj příspěvek</string>
|
||||||
<string name="notify_mention">Zmiňuje mě</string>
|
<string name="notify_mention">Zmíní mě</string>
|
||||||
<string name="settings_boring">Nudná část</string>
|
<string name="settings_boring">Nudná část</string>
|
||||||
<string name="settings_account">Nastavení účtu</string>
|
<string name="settings_account">Nastavení účtu</string>
|
||||||
<string name="settings_contribute">Přispějte do Mastodonu</string>
|
<string name="settings_contribute">Přispějte do Mastodonu</string>
|
||||||
<string name="settings_tos">Podmínky používání</string>
|
<string name="settings_tos">Podmínky užití</string>
|
||||||
<string name="settings_privacy_policy">Zásady ochrany osobních údajů</string>
|
<string name="settings_privacy_policy">Zásady ochrany osobních údajů</string>
|
||||||
<string name="settings_spicy">Ostrá část</string>
|
<string name="settings_spicy">Ostrá část</string>
|
||||||
<string name="settings_clear_cache">Vymazat mezipaměť médií</string>
|
<string name="settings_clear_cache">Vymazat mezipaměť médií</string>
|
||||||
<string name="settings_app_version">Mastodon pro Android v%1$s (%2$d)</string>
|
<string name="settings_app_version">Mastodon for Android v%1$s (%2$d)</string>
|
||||||
<string name="media_cache_cleared">Mezipaměť médií vymazána</string>
|
<string name="media_cache_cleared">Mezipaměť médií byla vymazána</string>
|
||||||
<string name="confirm_log_out">Opravdu se chcete odhlásit?</string>
|
<string name="confirm_log_out">Opravdu se chcete odhlásit?</string>
|
||||||
<string name="sensitive_content">Citlivý obsah</string>
|
<string name="sensitive_content">Citlivý obsah</string>
|
||||||
<string name="sensitive_content_explain">Autor označil toto médium za citlivé. Klepnutím zobrazíte.</string>
|
<string name="sensitive_content_explain">Autor označil toto médium jako citlivé. Klepnutím ho zobrazíte.</string>
|
||||||
<string name="media_hidden">Klepnutím zobrazit</string>
|
<string name="media_hidden">Klepněte pro zobrazení</string>
|
||||||
<string name="avatar_description">Jít na profil %s</string>
|
<string name="avatar_description">Přejít na profil uživatele %s</string>
|
||||||
<string name="more_options">Více možností</string>
|
<string name="more_options">Více možností</string>
|
||||||
<string name="reveal_content">Zobrazit obsah</string>
|
<string name="reveal_content">Odhalit obsah</string>
|
||||||
<string name="hide_content">Skrýt obsah</string>
|
<string name="hide_content">Skrýt obsah</string>
|
||||||
<string name="new_post">Nový příspěvek</string>
|
<string name="new_post">Nový příspěvek</string>
|
||||||
<string name="button_reply">Odpovědět</string>
|
<string name="button_reply">Odpovědět</string>
|
||||||
@@ -309,34 +307,34 @@
|
|||||||
<string name="my_profile">Můj profil</string>
|
<string name="my_profile">Můj profil</string>
|
||||||
<string name="media_viewer">Prohlížeč médií</string>
|
<string name="media_viewer">Prohlížeč médií</string>
|
||||||
<string name="follow_user">Sledovat %s</string>
|
<string name="follow_user">Sledovat %s</string>
|
||||||
<string name="unfollowed_user">Sledování %s ukončeno</string>
|
<string name="unfollowed_user">Sledování %s bylo zrušeno</string>
|
||||||
<string name="followed_user">Nyní sledujete %s</string>
|
<string name="followed_user">Nyní sledujete %s</string>
|
||||||
<string name="open_in_browser">Otevřít v prohlížeči</string>
|
<string name="open_in_browser">Otevřít v prohlížeči</string>
|
||||||
<string name="hide_boosts_from_user">Skrýt boosty od %s</string>
|
<string name="hide_boosts_from_user">Skrýt boosty od %s</string>
|
||||||
<string name="show_boosts_from_user">Zobrazit boosty od %s</string>
|
<string name="show_boosts_from_user">Zobrazit boosty od %s</string>
|
||||||
<string name="signup_reason">proč se chcete připojit?</string>
|
<string name="signup_reason">proč se chcete zaregistrovat?</string>
|
||||||
<string name="signup_reason_note">Toto nám pomůže posoudit vaši žádost.</string>
|
<string name="signup_reason_note">Toto nám pomůže posoudit vaši žádost.</string>
|
||||||
<string name="clear">Vyčistit</string>
|
<string name="clear">Vyčistit</string>
|
||||||
<string name="profile_header">Obrázek v záhlaví</string>
|
<string name="profile_header">Obrázek v záhlaví</string>
|
||||||
<string name="profile_picture">Profilová fotografie</string>
|
<string name="profile_picture">Profilový obrázek</string>
|
||||||
<string name="reorder">Změnit pořadí</string>
|
<string name="reorder">Změnit pořadí</string>
|
||||||
<string name="download">Stáhnout</string>
|
<string name="download">Stáhnout</string>
|
||||||
<string name="permission_required">Vyžadováno oprávnění</string>
|
<string name="permission_required">Je vyžadováno oprávnění</string>
|
||||||
<string name="storage_permission_to_download">Aplikace potřebuje přístup k vašemu úložišti, aby mohla uložit tento soubor.</string>
|
<string name="storage_permission_to_download">Aplikace potřebuje přístup k vašemu úložišti, aby mohla uložit tento soubor.</string>
|
||||||
<string name="open_settings">Otevřít nastavení</string>
|
<string name="open_settings">Otevřít nastavení</string>
|
||||||
<string name="error_saving_file">Chyba při ukládání souboru</string>
|
<string name="error_saving_file">Nastala chyba při ukládání souboru</string>
|
||||||
<string name="file_saved">Soubor uložen</string>
|
<string name="file_saved">Soubor byl uložen</string>
|
||||||
<string name="downloading">Stahování…</string>
|
<string name="downloading">Stahování…</string>
|
||||||
<string name="no_app_to_handle_action">Nebyly nalezeny žádné aplikace pro tuto úlohu</string>
|
<string name="no_app_to_handle_action">Nebyly nalezeny žádné aplikace pro tuto úlohu</string>
|
||||||
<string name="local_timeline">Komunita</string>
|
<string name="local_timeline">Komunita</string>
|
||||||
<string name="trending_posts_info_banner">Toto jsou příspěvky, které získávají pozornost ve vašem koutu Mastodonu.</string>
|
<string name="trending_posts_info_banner">Tyto příspěvky získávají na popularitě ve vašem koutu Mastodonu.</string>
|
||||||
<string name="trending_hashtags_info_banner">Toto jsou hashtagy, které získávají pozornost ve vašem koutu Mastodonu.</string>
|
<string name="trending_hashtags_info_banner">Tyto hashtagy získávají na popularitě ve vašem koutu Mastodonu.</string>
|
||||||
<string name="trending_links_info_banner">Toto jsou zprávy, které jsou nejvíce sdíleny ve vašem koutu Mastodonu.</string>
|
<string name="trending_links_info_banner">Tyto zprávy jsou nejvíce sdíleny ve vašem koutu Mastodonu.</string>
|
||||||
<string name="local_timeline_info_banner">Toto jsou nejnovější příspěvky od lidí, kteří používají stejný server Mastodonu jako vy.</string>
|
<string name="local_timeline_info_banner">Toto jsou nejnovější příspěvky od lidí, kteří používají stejný server Mastodonu jako vy.</string>
|
||||||
<string name="dismiss">Zavřít</string>
|
<string name="dismiss">Zavřít</string>
|
||||||
<string name="see_new_posts">Zobrazit nové příspěvky</string>
|
<string name="see_new_posts">Zobrazit nové příspěvky</string>
|
||||||
<string name="load_missing_posts">Načíst chybějící příspěvky</string>
|
<string name="load_missing_posts">Načíst chybějící příspěvky</string>
|
||||||
<string name="follow_back">Sledovat zpátky</string>
|
<string name="follow_back">Sledovat nazpět</string>
|
||||||
<string name="button_follow_pending">Čekající</string>
|
<string name="button_follow_pending">Čekající</string>
|
||||||
<string name="follows_you">Sleduje vás</string>
|
<string name="follows_you">Sleduje vás</string>
|
||||||
<string name="manually_approves_followers">Ručně schvaluje sledující</string>
|
<string name="manually_approves_followers">Ručně schvaluje sledující</string>
|
||||||
@@ -351,34 +349,34 @@
|
|||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="x_following">
|
<plurals name="x_following">
|
||||||
<item quantity="one">%,d sledující</item>
|
<item quantity="one">%,d sledující</item>
|
||||||
<item quantity="few">%,d sledování</item>
|
<item quantity="few">%,d sledovaní</item>
|
||||||
<item quantity="many">%,d sledování</item>
|
<item quantity="many">%,d sledovaných</item>
|
||||||
<item quantity="other">%,d sledování</item>
|
<item quantity="other">%,d sledovaných</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="x_favorites">
|
<plurals name="x_favorites">
|
||||||
<item quantity="one">%,d oblíbený</item>
|
<item quantity="one">%,d oblíbení</item>
|
||||||
<item quantity="few">%,d oblíbené</item>
|
<item quantity="few">%,d oblíbení</item>
|
||||||
<item quantity="many">%,d oblíbených</item>
|
<item quantity="many">%,d oblíbení</item>
|
||||||
<item quantity="other">%,d oblíbených</item>
|
<item quantity="other">%,d oblíbení</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="x_reblogs">
|
<plurals name="x_reblogs">
|
||||||
<item quantity="one">%,d boostnul</item>
|
<item quantity="one">%,d boostnul</item>
|
||||||
<item quantity="few">%,d boostnuli</item>
|
<item quantity="few">%,d boosty</item>
|
||||||
<item quantity="many">%,d boostnulo</item>
|
<item quantity="many">%,d boostů</item>
|
||||||
<item quantity="other">%,d boostnulo</item>
|
<item quantity="other">%,d boostů</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="timestamp_via_app">%1$s přes %2$s</string>
|
<string name="timestamp_via_app">%1$s přes %2$s</string>
|
||||||
<string name="time_now">teď</string>
|
<string name="time_now">teď</string>
|
||||||
<string name="post_info_reblogs">Reblogy</string>
|
<string name="post_info_reblogs">Boosty</string>
|
||||||
<string name="post_info_favorites">Oblíbené</string>
|
<string name="post_info_favorites">Oblíbení</string>
|
||||||
<string name="edit_history">Historie změn</string>
|
<string name="edit_history">Historie úprav</string>
|
||||||
<string name="last_edit_at_x">Poslední úprava %s</string>
|
<string name="last_edit_at_x">Poslední úprava %s</string>
|
||||||
<string name="time_just_now">právě teď</string>
|
<string name="time_just_now">právě teď</string>
|
||||||
<plurals name="x_seconds_ago">
|
<plurals name="x_seconds_ago">
|
||||||
<item quantity="one">Před 1 vteřinou</item>
|
<item quantity="one">před %d sekundou</item>
|
||||||
<item quantity="few">Před %d vteřinami</item>
|
<item quantity="few">před %d sekundami</item>
|
||||||
<item quantity="many">Před %d vteřinami</item>
|
<item quantity="many">před %d sekundami</item>
|
||||||
<item quantity="other">Před %d vteřinami</item>
|
<item quantity="other">před %d sekundami</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="x_minutes_ago">
|
<plurals name="x_minutes_ago">
|
||||||
<item quantity="one">před %d minutou</item>
|
<item quantity="one">před %d minutou</item>
|
||||||
@@ -388,21 +386,21 @@
|
|||||||
</plurals>
|
</plurals>
|
||||||
<string name="edited_timestamp">upraveno %s</string>
|
<string name="edited_timestamp">upraveno %s</string>
|
||||||
<string name="edit_original_post">Původní příspěvek</string>
|
<string name="edit_original_post">Původní příspěvek</string>
|
||||||
<string name="edit_text_edited">Text upraven</string>
|
<string name="edit_text_edited">Text byl upraven</string>
|
||||||
<string name="edit_spoiler_added">Upozornění na obsah bylo přidáno</string>
|
<string name="edit_spoiler_added">Varování o obsahu bylo přidáno</string>
|
||||||
<string name="edit_spoiler_edited">Upozornění na obsah upraveno</string>
|
<string name="edit_spoiler_edited">Varování o obsahu bylo upraveno</string>
|
||||||
<string name="edit_spoiler_removed">Upozornění na obsah odstraněno</string>
|
<string name="edit_spoiler_removed">Varování o obsahu bylo odebráno</string>
|
||||||
<string name="edit_poll_added">Anketa přidána</string>
|
<string name="edit_poll_added">Anketa byla přidána</string>
|
||||||
<string name="edit_poll_edited">Anketa upravena</string>
|
<string name="edit_poll_edited">Anketa byla upravena</string>
|
||||||
<string name="edit_poll_removed">Anketa odstraněna</string>
|
<string name="edit_poll_removed">Anketa byla odebrána</string>
|
||||||
<string name="edit_media_added">Média přidána</string>
|
<string name="edit_media_added">Média přidána</string>
|
||||||
<string name="edit_media_removed">Média odstraněna</string>
|
<string name="edit_media_removed">Média odstraněna</string>
|
||||||
<string name="edit_media_reordered">Média přeřazena</string>
|
<string name="edit_media_reordered">Pořadí médií bylo změněno</string>
|
||||||
<string name="edit_marked_sensitive">Označeno jako citlivé</string>
|
<string name="edit_marked_sensitive">Označeno jako citlivé</string>
|
||||||
<string name="edit_marked_not_sensitive">Označeno, že není citlivé</string>
|
<string name="edit_marked_not_sensitive">Označeno, že není citlivé</string>
|
||||||
<string name="edit_multiple_changed">Příspěvek upraven</string>
|
<string name="edit_multiple_changed">Příspěvek byl upraven</string>
|
||||||
<string name="edit">Upravit</string>
|
<string name="edit">Upravit</string>
|
||||||
<string name="discard_changes">Zrušit změny?</string>
|
<string name="discard_changes">Zahodit změny?</string>
|
||||||
<string name="upload_failed">Nahrávání se nezdařilo</string>
|
<string name="upload_failed">Nahrávání se nezdařilo</string>
|
||||||
<string name="file_size_bytes">%d bajtů</string>
|
<string name="file_size_bytes">%d bajtů</string>
|
||||||
<string name="file_size_kb">%.2f KB</string>
|
<string name="file_size_kb">%.2f KB</string>
|
||||||
@@ -413,7 +411,7 @@
|
|||||||
<string name="upload_error_connection_lost">Vaše zařízení ztratilo připojení k internetu</string>
|
<string name="upload_error_connection_lost">Vaše zařízení ztratilo připojení k internetu</string>
|
||||||
<string name="upload_processing">Zpracovávání…</string>
|
<string name="upload_processing">Zpracovávání…</string>
|
||||||
<!-- %s is version like 1.2.3 -->
|
<!-- %s is version like 1.2.3 -->
|
||||||
<string name="update_available">Mastodon pro Android %s je připravený ke stažení.</string>
|
<string name="update_available">Mastodon pro Android %s je připraven ke stažení.</string>
|
||||||
<!-- %s is version like 1.2.3 -->
|
<!-- %s is version like 1.2.3 -->
|
||||||
<string name="update_ready">Mastodon pro Android %s je stažený a připravený k instalaci.</string>
|
<string name="update_ready">Mastodon pro Android %s je stažený a připravený k instalaci.</string>
|
||||||
<!-- %s is file size -->
|
<!-- %s is file size -->
|
||||||
@@ -423,4 +421,10 @@
|
|||||||
<string name="privacy_policy_subtitle">Ačkoliv aplikace Mastodon neshromažďuje žádná data, server, na kterém se registrujete, může mít jiné zásady. Věnujte minutu kontrole a odsouhlasení zásad soukromí aplikace Mastodon a vašeho serveru.</string>
|
<string name="privacy_policy_subtitle">Ačkoliv aplikace Mastodon neshromažďuje žádná data, server, na kterém se registrujete, může mít jiné zásady. Věnujte minutu kontrole a odsouhlasení zásad soukromí aplikace Mastodon a vašeho serveru.</string>
|
||||||
<string name="i_agree">Souhlasím</string>
|
<string name="i_agree">Souhlasím</string>
|
||||||
<string name="empty_list">Tento seznam je prázdný</string>
|
<string name="empty_list">Tento seznam je prázdný</string>
|
||||||
|
<string name="instance_signup_closed">Tento server nepřijímá nové registrace.</string>
|
||||||
|
<string name="text_copied">Zkopírováno do schránky</string>
|
||||||
|
<string name="add_bookmark">Přidat do záložek</string>
|
||||||
|
<string name="remove_bookmark">Odstranit ze záložek</string>
|
||||||
|
<string name="bookmarks">Záložky</string>
|
||||||
|
<string name="your_favorites">Vaše oblíbení</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
3
mastodon/src/main/res/values-cs-rCZ/strings_sk.xml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
</resources>
|
||||||