Compare commits
119 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a41a2d6fb | ||
|
|
2cd98a6620 | ||
|
|
283b56be5b | ||
|
|
6d56771aba | ||
|
|
1724d8a532 | ||
|
|
b4cdf35d36 | ||
|
|
cad0ad7a59 | ||
|
|
ca60003c39 | ||
|
|
0f030e0bac | ||
|
|
6d4f212a18 | ||
|
|
183b39bc24 | ||
|
|
27ad0c6fcf | ||
|
|
b5f661f1af | ||
|
|
0015f3f0bf | ||
|
|
c5d0fdd645 | ||
|
|
2d09ad44fb | ||
|
|
667fffd124 | ||
|
|
699233d8c7 | ||
|
|
56aabdc4a6 | ||
|
|
443e2c7a6f | ||
|
|
985b0f6e63 | ||
|
|
cc86edf276 | ||
|
|
4071b9342d | ||
|
|
f71d1bc5d3 | ||
|
|
6bcdbaba34 | ||
|
|
a2beead3a5 | ||
|
|
e7a25e353d | ||
|
|
af04a01130 | ||
|
|
fe1cfa1d7b | ||
|
|
b248797bb0 | ||
|
|
f24eba08d3 | ||
|
|
0e89559a47 | ||
|
|
d02a72e079 | ||
|
|
3be57d1b0b | ||
|
|
bed550e97c | ||
|
|
7e2619ea75 | ||
|
|
4b22f1d3a7 | ||
|
|
9dcc7e293f | ||
|
|
6a68cf5e41 | ||
|
|
29297be4a3 | ||
|
|
90b87529e0 | ||
|
|
39af05524d | ||
|
|
e3fb2cd03c | ||
|
|
90f84d628a | ||
|
|
b89e0b5c5a | ||
|
|
aac89c354c | ||
|
|
a032f9af10 | ||
|
|
642aaec6da | ||
|
|
ff667d6aed | ||
|
|
5e98496ea6 | ||
|
|
972fe1d15b | ||
|
|
26eaa36faa | ||
|
|
c517f41595 | ||
|
|
56a6d7243f | ||
|
|
18e43dfc22 | ||
|
|
816f6370ef | ||
|
|
ebc2b2e59d | ||
|
|
c9a796dbfe | ||
|
|
1ba185ea9c | ||
|
|
a78be8bc1d | ||
|
|
abfb497577 | ||
|
|
a10b184508 | ||
|
|
f0ea6660e6 | ||
|
|
a829f25d56 | ||
|
|
deff3dd8e0 | ||
|
|
6c5fb5ea09 | ||
|
|
afe0c9e0db | ||
|
|
1f2213042f | ||
|
|
5edd2466f9 | ||
|
|
f3b3a1a577 | ||
|
|
068619b815 | ||
|
|
f121e94979 | ||
|
|
b5b52529d4 | ||
|
|
876bf73454 | ||
|
|
522dbf6e4a | ||
|
|
ae685095ba | ||
|
|
30d5fe2f12 | ||
|
|
2bf27c561c | ||
|
|
bbdc72323d | ||
|
|
6e335930f3 | ||
|
|
9b309939da | ||
|
|
faf2e5115d | ||
|
|
dc5d9412c8 | ||
|
|
fc0680d66f | ||
|
|
56c9a5433f | ||
|
|
60e473ee55 | ||
|
|
ae34ecd5c3 | ||
|
|
fd1caa8729 | ||
|
|
1182e5c60c | ||
|
|
d99d515dfa | ||
|
|
70a15e7d9c | ||
|
|
1691382369 | ||
|
|
b7da9c6d51 | ||
|
|
3426538dca | ||
|
|
63de2b200b | ||
|
|
ff1ee766dc | ||
|
|
f033411adf | ||
|
|
a738eaf8c0 | ||
|
|
5074aadd6e | ||
|
|
0854961470 | ||
|
|
227b077935 | ||
|
|
1e4358290a | ||
|
|
925169eb31 | ||
|
|
e1abeb9252 | ||
|
|
cbe0add211 | ||
|
|
299b524d62 | ||
|
|
31c094e696 | ||
|
|
a8038a2863 | ||
|
|
29933bb916 | ||
|
|
5ec0c078d8 | ||
|
|
e6287f1ff2 | ||
|
|
be9caf8905 | ||
|
|
f375142084 | ||
|
|
fd3668d520 | ||
|
|
d5e03e9d9e | ||
|
|
d62f094919 | ||
|
|
6d84f28600 | ||
|
|
209e603f2c | ||
|
|
1b4dc01c74 |
@@ -1,6 +1,6 @@
|
||||
Mastodon on internetin suurin hajautettu sosiaalinen verkosto. Yhden verkkopalvelun sijaan, se on miljoonien itsenäisissä yhteisöissä olevien käyttäjien verkosto, jotka voivat olla vuorovaikutuksessa toistensa kanssa saumattomasti. Riippumatta siitä, mistä olet kiinnostunut, voit tavata intohimoisia ihmisiä, jotka julkaisevat aiheesta Mastodonissa!
|
||||
Mastodon on internetin suurin hajautettu sosiaalinen verkosto. Yhden verkkopalvelun sijaan, se on miljoonien itsenäisissä yhteisöissä olevien käyttäjien verkosto, jotka voivat olla vuorovaikutuksessa toistensa kanssa saumattomasti. Riippumatta siitä, mistä olet kiinnostunut, voit tavata samanmielisiä ihmisiä, jotka julkaisevat aiheesta Mastodonissa!
|
||||
|
||||
Liity yhteisöön ja luo itsellesi tili. Find and follow fascinating folks and read their posts in an ad-free, chronological timeline. Ilmaise itseäsi mukautetuilla emojeilla, kuvilla, videoilla ja audiolla 500 merkin pituisissa julkaisuissa. Vastaa viestiketjuihin ja edelleen jaa julkaisuja keneltä tahansa, jakaaksesi hienoja juttuja. Löydä uusia tilejä seurattavaksi ja trendaavia hashtageja laajentaaksesi verkostoasi.
|
||||
Liity yhteisöön ja luo itsellesi tili. Löydä ja seuraa kiehtovia ihmisiä ja lue heidän julkaisunsa ilman mainoksia, kronologisella aikajanalla. Ilmaise itseäsi mukautetuilla emojeilla, kuvilla, videoilla ja audiolla 500 merkin pituisissa julkaisuissa. Vastaa viestiketjuihin ja edelleen jaa julkaisuja keneltä tahansa, jakaaksesi hienoja juttuja. Löydä uusia tilejä seurattavaksi ja suosittuja aihetunnisteita laajentaaksesi verkostoasi.
|
||||
|
||||
Mastodon on rakennettu keskittyen yksityisyyteen ja turvallisuuteen. Päätä, jaetaanko julkaisusi seuraajille, vain mainitsemillesi ihmisille vai koko maailmalle. Sisältövaroitusten avulla, voit piilottaa julkaisut, jotka sisältävät arkaluontoista tai laukaisevaa materiaalia, kunnes olet valmis käsittelemään niitä. Jokaisella yhteisöllä on omat ohjeistonsa ja valvojansa, jotka pitävät jäsenensä turvassa, ja tehokkaat esto- ja ilmiantotyökalut auttavat torjumaan väärinkäytöksiä.
|
||||
|
||||
@@ -8,8 +8,8 @@ Lisää ominaisuuksia:
|
||||
|
||||
• Tumma tila: Lue julkaisut vaaleassa, tummassa tai mustan tummassa tilassa
|
||||
• Kyselyt: Kysy seuraajilta heidän mielipidettään ja laske äänet
|
||||
• Tutustu: Trendaavat hashtagit ja tilit ovat vain napsautuksen päässä
|
||||
• Ilmoitukset: Saat ilmoituksen uusista seuraajista, vastauksista ja edelleen jaoista
|
||||
• Tutustu: Suositut aihetunnisteet ja tilit ovat vain napsautuksen päässä
|
||||
• Ilmoitukset: Saat ilmoituksen uusista seuraajista, vastauksista ja tehostuksista
|
||||
• Jakaminen: Julkaise suoraan Mastodoniin minkä tahansa sovelluksen jakovalikon kautta
|
||||
• Suloisuus: Maskottimme on ihastuttava mastodontti ja näet sen ajoittain
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Mastodon เป็นเครือข่ายสังคมแบบกระจายศูนย์ที่ใหญ่ที่สุดบนอินเทอร์เน็ต ซึ่งไม่ได้เป็นเว็บไซต์เดียว แต่เป็นเครือข่ายของผู้ใช้หลายล้านคนในชุมชนอิสระที่ทุกคนสามารถโต้ตอบซึ่งกันและกันได้แบบไร้รอยต่อ ไม่ว่าคุณจะชอบอะไร คุณก็พบคนที่ชื่นชอบเหมือนกันโพสต์เกี่ยวกับสิ่งที่คุณชอบได้บน Mastodon! ซึ่งไม่ได้เป็นเว็บไซต์เดียว แต่เป็นเครือข่ายของผู้ใช้หลายล้านคนในชุมชนอิสระที่ทุกคนสามารถโต้ตอบซึ่งกันและกันได้แบบไร้รอยต่อ ไม่ว่าคุณจะชอบอะไร คุณก็พบคนที่ชื่นชอบเหมือนกันโพสต์เกี่ยวกับสิ่งที่คุณชอบได้บน Mastodon!
|
||||
Mastodon เป็นเครือข่ายสังคมแบบกระจายศูนย์ที่ใหญ่ที่สุดบนอินเทอร์เน็ต ซึ่งไม่ได้เป็นเว็บไซต์เดียว แต่เป็นเครือข่ายของผู้ใช้หลายล้านคนในชุมชนอิสระที่ทุกคนสามารถโต้ตอบซึ่งกันและกันได้แบบไร้รอยต่อ ไม่ว่าคุณจะชอบอะไร คุณก็พบคนที่ชื่นชอบเหมือนกันโพสต์เกี่ยวกับสิ่งที่คุณชอบได้บน Mastodon!
|
||||
|
||||
เข้าร่วมชุมชนและสร้างโปรไฟล์ ค้นหาและติดตามผู้คนที่น่าสนใจและอ่านโพสต์ของเขาในเส้นเวลาที่ไม่มีโฆษณาและเรียงตามลำดับเวลา แสดงความรู้สึกของตัวคุณเองด้วยอีโมจิที่กำหนดเอง รูปภาพ GIF วิดีโอ และเสียงในโพสต์ 500 ตัวอักษร ตอบกลับและดันโพสต์จากคนอื่น ๆ เพื่อแชร์สิ่งดี ๆ และค้นหาบัญชีใหม่ ๆ ที่จะติดตามและแฮชแท็กที่เป็นที่นิยมเพื่อขยายเครือข่ายของคุณ
|
||||
|
||||
@@ -13,4 +13,4 @@ Mastodon สร้างขึ้นโดยเน้นความเป็
|
||||
• การแชร์: โพสต์ลง Mastodon ได้โดยตรงจากแอปอื่น ๆ ที่อยู่ในเครื่อง
|
||||
• ความน่ารัก: มาสคอตของเราเป็นช้างน่ารัก และคุณจะเห็นมันโผล่ออกมาเป็นระยะ ๆ
|
||||
|
||||
Mastodon เป็นองค์กรไม่แสวงหาผลกำไรที่จดทะเบียนแล้ว และการพัฒนาได้รับการสนับสนุนจากเงินบริจาคของคุณโดยตรง ดังนั้นจึงไม่มีโฆษณา ไม่มีการทำกำไร และไม่มีการร่วมลงทุน และเรามีแผนจะทำให้เป็นอย่างนี้ต่อไป ดังนั้นจึงไม่มีโฆษณา ไม่มีการทำกำไร และไม่มีการร่วมลงทุน และเรามีแผนจะทำให้เป็นอย่างนี้ต่อไป
|
||||
Mastodon เป็นองค์กรไม่แสวงหาผลกำไรที่จดทะเบียนแล้ว และการพัฒนาได้รับการสนับสนุนจากเงินบริจาคของคุณโดยตรง ดังนั้นจึงไม่มีโฆษณา ไม่มีการทำกำไร และไม่มีการร่วมลงทุน และเรามีแผนจะทำให้เป็นอย่างนี้ต่อไป
|
||||
|
||||
@@ -9,8 +9,8 @@ android {
|
||||
applicationId "org.joinmastodon.android"
|
||||
minSdk 23
|
||||
targetSdk 33
|
||||
versionCode 64
|
||||
versionName "2.0.4"
|
||||
versionCode 69
|
||||
versionName "2.1.3"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
resConfigs "ar-rSA", "be-rBY", "bn-rBD", "bs-rBA", "ca-rES", "cs-rCZ", "da-rDK", "de-rDE", "el-rGR", "es-rES", "eu-rES", "fa-rIR", "fi-rFI", "fil-rPH", "fr-rFR", "ga-rIE", "gd-rGB", "gl-rES", "hi-rIN", "hr-rHR", "hu-rHU", "hy-rAM", "ig-rNG", "in-rID", "is-rIS", "it-rIT", "iw-rIL", "ja-rJP", "kab", "ko-rKR", "my-rMM", "nl-rNL", "no-rNO", "oc-rFR", "pl-rPL", "pt-rBR", "pt-rPT", "ro-rRO", "ru-rRU", "si-rLK", "sl-rSI", "sv-rSE", "th-rTH", "tr-rTR", "uk-rUA", "ur-rIN", "vi-rVN", "zh-rCN", "zh-rTW"
|
||||
}
|
||||
@@ -76,7 +76,7 @@ dependencies {
|
||||
implementation 'me.grishka.litex:viewpager:1.0.0'
|
||||
implementation 'me.grishka.litex:viewpager2:1.0.0'
|
||||
implementation 'me.grishka.litex:palette:1.0.0'
|
||||
implementation 'me.grishka.appkit:appkit:1.2.9'
|
||||
implementation 'me.grishka.appkit:appkit:1.2.13'
|
||||
implementation 'com.google.code.gson:gson:2.8.9'
|
||||
implementation 'org.jsoup:jsoup:1.14.3'
|
||||
implementation 'com.squareup:otto:1.3.8'
|
||||
|
||||
@@ -136,7 +136,7 @@ public class MainActivity extends FragmentStackActivity{
|
||||
}
|
||||
|
||||
public void openSearchQuery(String q, String accountID, int progressText, boolean fromSearch){
|
||||
new GetSearchResults(q, null, true)
|
||||
new GetSearchResults(q, null, true, null, 0, 0)
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(SearchResults result){
|
||||
|
||||
@@ -118,6 +118,8 @@ public class PushNotificationReceiver extends BroadcastReceiver{
|
||||
List<NotificationChannel> channels=Arrays.stream(PushNotification.Type.values())
|
||||
.map(type->{
|
||||
NotificationChannel channel=new NotificationChannel(accountID+"_"+type, context.getString(type.localizedName), NotificationManager.IMPORTANCE_DEFAULT);
|
||||
channel.setLightColor(context.getColor(R.color.primary_700));
|
||||
channel.enableLights(true);
|
||||
channel.setGroup(accountID);
|
||||
return channel;
|
||||
})
|
||||
@@ -147,6 +149,7 @@ public class PushNotificationReceiver extends BroadcastReceiver{
|
||||
.setShowWhen(true)
|
||||
.setCategory(Notification.CATEGORY_SOCIAL)
|
||||
.setAutoCancel(true)
|
||||
.setLights(context.getColor(R.color.primary_700), 500, 1000)
|
||||
.setColor(context.getColor(R.color.primary_700));
|
||||
if(avatar!=null){
|
||||
builder.setLargeIcon(UiUtils.getBitmapFromDrawable(avatar));
|
||||
|
||||
@@ -6,18 +6,19 @@ import org.joinmastodon.android.model.Preferences;
|
||||
import org.joinmastodon.android.model.StatusPrivacy;
|
||||
|
||||
public class UpdateAccountCredentialsPreferences extends MastodonAPIRequest<Account>{
|
||||
public UpdateAccountCredentialsPreferences(Preferences preferences, Boolean locked, Boolean discoverable){
|
||||
public UpdateAccountCredentialsPreferences(Preferences preferences, Boolean locked, Boolean discoverable, Boolean indexable){
|
||||
super(HttpMethod.PATCH, "/accounts/update_credentials", Account.class);
|
||||
setRequestBody(new Request(locked, discoverable, new RequestSource(preferences.postingDefaultVisibility, preferences.postingDefaultLanguage)));
|
||||
setRequestBody(new Request(locked, discoverable, indexable, new RequestSource(preferences.postingDefaultVisibility, preferences.postingDefaultLanguage)));
|
||||
}
|
||||
|
||||
private static class Request{
|
||||
public Boolean locked, discoverable;
|
||||
public Boolean locked, discoverable, indexable;
|
||||
public RequestSource source;
|
||||
|
||||
public Request(Boolean locked, Boolean discoverable, RequestSource source){
|
||||
public Request(Boolean locked, Boolean discoverable, Boolean indexable, RequestSource source){
|
||||
this.locked=locked;
|
||||
this.discoverable=discoverable;
|
||||
this.indexable=indexable;
|
||||
this.source=source;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,13 +4,19 @@ import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.model.SearchResults;
|
||||
|
||||
public class GetSearchResults extends MastodonAPIRequest<SearchResults>{
|
||||
public GetSearchResults(String query, Type type, boolean resolve){
|
||||
public GetSearchResults(String query, Type type, boolean resolve, String maxID, int offset, int count){
|
||||
super(HttpMethod.GET, "/search", SearchResults.class);
|
||||
addQueryParameter("q", query);
|
||||
if(type!=null)
|
||||
addQueryParameter("type", type.name().toLowerCase());
|
||||
if(resolve)
|
||||
addQueryParameter("resolve", "true");
|
||||
if(maxID!=null)
|
||||
addQueryParameter("max_id", maxID);
|
||||
if(offset>0)
|
||||
addQueryParameter("offset", String.valueOf(offset));
|
||||
if(count>0)
|
||||
addQueryParameter("limit", String.valueOf(count));
|
||||
}
|
||||
|
||||
public GetSearchResults limit(int limit){
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.joinmastodon.android.api.requests.statuses;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.model.Translation;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class TranslateStatus extends MastodonAPIRequest<Translation>{
|
||||
public TranslateStatus(String id, String lang){
|
||||
super(HttpMethod.POST, "/statuses/"+id+"/translate", Translation.class);
|
||||
setRequestBody(Map.of("lang", lang));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.joinmastodon.android.api.requests.tags;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.model.Hashtag;
|
||||
|
||||
public class GetTag extends MastodonAPIRequest<Hashtag>{
|
||||
public GetTag(String tag){
|
||||
super(HttpMethod.GET, "/tags/"+tag, Hashtag.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.joinmastodon.android.api.requests.tags;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.model.Hashtag;
|
||||
|
||||
public class SetTagFollowed extends MastodonAPIRequest<Hashtag>{
|
||||
public SetTagFollowed(String tag, boolean followed){
|
||||
super(HttpMethod.POST, "/tags/"+tag+(followed ? "/follow" : "/unfollow"), Hashtag.class);
|
||||
setRequestBody(new Object());
|
||||
}
|
||||
}
|
||||
@@ -195,7 +195,7 @@ public class AccountSession{
|
||||
|
||||
public void savePreferencesIfPending(){
|
||||
if(preferencesNeedSaving){
|
||||
new UpdateAccountCredentialsPreferences(preferences, null, null)
|
||||
new UpdateAccountCredentialsPreferences(preferences, null, self.discoverable, self.source.indexable)
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(Account result){
|
||||
@@ -261,4 +261,8 @@ public class AccountSession{
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
public void updateAccountInfo(){
|
||||
AccountSessionManager.getInstance().updateSessionLocalInfo(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,7 +279,7 @@ public class AccountSessionManager{
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSessionLocalInfo(AccountSession session){
|
||||
/*package*/ void updateSessionLocalInfo(AccountSession session){
|
||||
new GetOwnAccount()
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
|
||||
@@ -17,13 +17,16 @@ import org.joinmastodon.android.E;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.accounts.GetAccountRelationships;
|
||||
import org.joinmastodon.android.api.requests.polls.SubmitPollVote;
|
||||
import org.joinmastodon.android.api.requests.statuses.TranslateStatus;
|
||||
import org.joinmastodon.android.events.PollUpdatedEvent;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.DisplayItemsParent;
|
||||
import org.joinmastodon.android.model.Poll;
|
||||
import org.joinmastodon.android.model.Relationship;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.model.Translation;
|
||||
import org.joinmastodon.android.ui.BetterItemAnimator;
|
||||
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||
import org.joinmastodon.android.ui.displayitems.AccountStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.ExtendedFooterStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.GapStatusDisplayItem;
|
||||
@@ -33,6 +36,7 @@ import org.joinmastodon.android.ui.displayitems.PollFooterStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.PollOptionStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.SpoilerStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.TextStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.photoviewer.PhotoViewer;
|
||||
import org.joinmastodon.android.ui.photoviewer.PhotoViewerHost;
|
||||
import org.joinmastodon.android.ui.utils.MediaAttachmentViewController;
|
||||
@@ -43,6 +47,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -560,6 +565,61 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
||||
return attachmentViewsPool;
|
||||
}
|
||||
|
||||
public void togglePostTranslation(Status status, String itemID){
|
||||
switch(status.translationState){
|
||||
case LOADING -> {
|
||||
return;
|
||||
}
|
||||
case SHOWN -> {
|
||||
status.translationState=Status.TranslationState.HIDDEN;
|
||||
}
|
||||
case HIDDEN -> {
|
||||
if(status.translation!=null){
|
||||
status.translationState=Status.TranslationState.SHOWN;
|
||||
}else{
|
||||
status.translationState=Status.TranslationState.LOADING;
|
||||
new TranslateStatus(status.getContentStatus().id, Locale.getDefault().getLanguage())
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(Translation result){
|
||||
if(getActivity()==null)
|
||||
return;
|
||||
status.translation=result;
|
||||
status.translationState=Status.TranslationState.SHOWN;
|
||||
TextStatusDisplayItem.Holder text=findHolderOfType(itemID, TextStatusDisplayItem.Holder.class);
|
||||
if(text!=null){
|
||||
text.updateTranslation(true);
|
||||
imgLoader.bindViewHolder((ImageLoaderRecyclerAdapter) list.getAdapter(), text, text.getAbsoluteAdapterPosition());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse error){
|
||||
if(getActivity()==null)
|
||||
return;
|
||||
status.translationState=Status.TranslationState.HIDDEN;
|
||||
TextStatusDisplayItem.Holder text=findHolderOfType(itemID, TextStatusDisplayItem.Holder.class);
|
||||
if(text!=null){
|
||||
text.updateTranslation(true);
|
||||
}
|
||||
new M3AlertDialogBuilder(getActivity())
|
||||
.setTitle(R.string.error)
|
||||
.setMessage(R.string.translation_failed)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show();
|
||||
}
|
||||
})
|
||||
.exec(accountID);
|
||||
}
|
||||
}
|
||||
}
|
||||
TextStatusDisplayItem.Holder text=findHolderOfType(itemID, TextStatusDisplayItem.Holder.class);
|
||||
if(text!=null){
|
||||
text.updateTranslation(true);
|
||||
imgLoader.bindViewHolder((ImageLoaderRecyclerAdapter) list.getAdapter(), text, text.getAbsoluteAdapterPosition());
|
||||
}
|
||||
}
|
||||
|
||||
public void rebuildAllDisplayItems(){
|
||||
displayItems.clear();
|
||||
for(T item:data){
|
||||
|
||||
@@ -839,7 +839,8 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
boolean usePhotoPicker=UiUtils.isPhotoPickerAvailable();
|
||||
if(usePhotoPicker){
|
||||
intent=new Intent(MediaStore.ACTION_PICK_IMAGES);
|
||||
intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, mediaViewController.getMaxAttachments()-mediaViewController.getMediaAttachmentsCount());
|
||||
if(mediaViewController.getMaxAttachments()-mediaViewController.getMediaAttachmentsCount()>1)
|
||||
intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, mediaViewController.getMaxAttachments()-mediaViewController.getMediaAttachmentsCount());
|
||||
}else{
|
||||
intent=new Intent(Intent.ACTION_GET_CONTENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.parceler.Parcels;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
@@ -44,7 +45,7 @@ public class FeaturedHashtagsListFragment extends BaseStatusListFragment<Hashtag
|
||||
|
||||
@Override
|
||||
public void onItemClick(String id){
|
||||
UiUtils.openHashtagTimeline(getActivity(), accountID, id);
|
||||
UiUtils.openHashtagTimeline(getActivity(), accountID, Objects.requireNonNull(findItemOfType(id, HashtagStatusDisplayItem.class)).tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,24 +1,52 @@
|
||||
package org.joinmastodon.android.fragments;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.res.TypedArray;
|
||||
import android.os.Bundle;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.MastodonErrorResponse;
|
||||
import org.joinmastodon.android.api.requests.tags.GetTag;
|
||||
import org.joinmastodon.android.api.requests.tags.SetTagFollowed;
|
||||
import org.joinmastodon.android.api.requests.timelines.GetHashtagTimeline;
|
||||
import org.joinmastodon.android.model.Hashtag;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.ui.text.SpacerSpan;
|
||||
import org.joinmastodon.android.ui.views.ProgressBarButton;
|
||||
import org.parceler.Parcels;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
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.api.SimpleCallback;
|
||||
import me.grishka.appkit.utils.CubicBezierInterpolator;
|
||||
import me.grishka.appkit.utils.MergeRecyclerAdapter;
|
||||
import me.grishka.appkit.utils.SingleViewRecyclerAdapter;
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
public class HashtagTimelineFragment extends StatusListFragment{
|
||||
private String hashtag;
|
||||
private Hashtag hashtag;
|
||||
private String hashtagName;
|
||||
private ImageButton fab;
|
||||
private TextView headerTitle, headerSubtitle;
|
||||
private ProgressBarButton followButton;
|
||||
private ProgressBar followProgress;
|
||||
private MenuItem followMenuItem;
|
||||
private boolean followRequestRunning;
|
||||
private boolean toolbarContentVisible;
|
||||
|
||||
public HashtagTimelineFragment(){
|
||||
setListLayoutId(R.layout.recycler_fragment_with_fab);
|
||||
@@ -27,13 +55,19 @@ public class HashtagTimelineFragment extends StatusListFragment{
|
||||
@Override
|
||||
public void onAttach(Activity activity){
|
||||
super.onAttach(activity);
|
||||
hashtag=getArguments().getString("hashtag");
|
||||
setTitle('#'+hashtag);
|
||||
if(getArguments().containsKey("hashtag")){
|
||||
hashtag=Parcels.unwrap(getArguments().getParcelable("hashtag"));
|
||||
hashtagName=hashtag.name;
|
||||
}else{
|
||||
hashtagName=getArguments().getString("hashtagName");
|
||||
}
|
||||
setTitle('#'+hashtagName);
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLoadData(int offset, int count){
|
||||
currentRequest=new GetHashtagTimeline(hashtag, offset==0 ? null : getMaxID(), null, count)
|
||||
currentRequest=new GetHashtagTimeline(hashtagName, offset==0 ? null : getMaxID(), null, count)
|
||||
.setCallback(new SimpleCallback<>(this){
|
||||
@Override
|
||||
public void onSuccess(List<Status> result){
|
||||
@@ -50,17 +84,39 @@ public class HashtagTimelineFragment extends StatusListFragment{
|
||||
loadData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadData(){
|
||||
reloadTag();
|
||||
super.loadData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState){
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
fab=view.findViewById(R.id.fab);
|
||||
fab.setOnClickListener(this::onFabClick);
|
||||
|
||||
list.addOnScrollListener(new RecyclerView.OnScrollListener(){
|
||||
@Override
|
||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy){
|
||||
View topChild=recyclerView.getChildAt(0);
|
||||
int firstChildPos=recyclerView.getChildAdapterPosition(topChild);
|
||||
float newAlpha=firstChildPos>0 ? 1f : Math.min(1f, -topChild.getTop()/(float)headerTitle.getHeight());
|
||||
toolbarTitleView.setAlpha(newAlpha);
|
||||
boolean newToolbarVisibility=newAlpha>0.5f;
|
||||
if(newToolbarVisibility!=toolbarContentVisible){
|
||||
toolbarContentVisible=newToolbarVisibility;
|
||||
if(followMenuItem!=null)
|
||||
followMenuItem.setVisible(toolbarContentVisible);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void onFabClick(View v){
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
args.putString("prefilledText", '#'+hashtag+' ');
|
||||
args.putString("prefilledText", '#'+hashtagName+' ');
|
||||
Nav.go(getActivity(), ComposeFragment.class, args);
|
||||
}
|
||||
|
||||
@@ -68,4 +124,150 @@ public class HashtagTimelineFragment extends StatusListFragment{
|
||||
protected void onSetFabBottomInset(int inset){
|
||||
((ViewGroup.MarginLayoutParams) fab.getLayoutParams()).bottomMargin=V.dp(16)+inset;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RecyclerView.Adapter getAdapter(){
|
||||
View header=getActivity().getLayoutInflater().inflate(R.layout.header_hashtag_timeline, list, false);
|
||||
headerTitle=header.findViewById(R.id.title);
|
||||
headerSubtitle=header.findViewById(R.id.subtitle);
|
||||
followButton=header.findViewById(R.id.profile_action_btn);
|
||||
followProgress=header.findViewById(R.id.action_progress);
|
||||
|
||||
headerTitle.setText("#"+hashtagName);
|
||||
followButton.setVisibility(View.GONE);
|
||||
followButton.setOnClickListener(v->{
|
||||
if(hashtag==null)
|
||||
return;
|
||||
setFollowed(!hashtag.following);
|
||||
});
|
||||
updateHeader();
|
||||
|
||||
MergeRecyclerAdapter mergeAdapter=new MergeRecyclerAdapter();
|
||||
mergeAdapter.addAdapter(new SingleViewRecyclerAdapter(header));
|
||||
mergeAdapter.addAdapter(super.getAdapter());
|
||||
return mergeAdapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMainAdapterOffset(){
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
|
||||
followMenuItem=menu.add(getString(hashtag!=null && hashtag.following ? R.string.unfollow_user : R.string.follow_user, "#"+hashtagName));
|
||||
followMenuItem.setVisible(toolbarContentVisible);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item){
|
||||
if(hashtag!=null){
|
||||
setFollowed(!hashtag.following);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onUpdateToolbar(){
|
||||
super.onUpdateToolbar();
|
||||
toolbarTitleView.setAlpha(toolbarContentVisible ? 1f : 0f);
|
||||
if(followMenuItem!=null)
|
||||
followMenuItem.setVisible(toolbarContentVisible);
|
||||
}
|
||||
|
||||
private void updateHeader(){
|
||||
if(hashtag==null)
|
||||
return;
|
||||
|
||||
if(hashtag.history!=null && !hashtag.history.isEmpty()){
|
||||
int weekPosts=hashtag.history.stream().mapToInt(h->h.uses).sum();
|
||||
int todayPosts=hashtag.history.get(0).uses;
|
||||
int numAccounts=hashtag.history.stream().mapToInt(h->h.accounts).sum();
|
||||
int hSpace=V.dp(8);
|
||||
SpannableStringBuilder ssb=new SpannableStringBuilder();
|
||||
ssb.append(getResources().getQuantityString(R.plurals.x_posts, weekPosts, weekPosts));
|
||||
ssb.append(" ", new SpacerSpan(hSpace, 0), 0);
|
||||
ssb.append('·');
|
||||
ssb.append(" ", new SpacerSpan(hSpace, 0), 0);
|
||||
ssb.append(getResources().getQuantityString(R.plurals.x_participants, numAccounts, numAccounts));
|
||||
ssb.append(" ", new SpacerSpan(hSpace, 0), 0);
|
||||
ssb.append('·');
|
||||
ssb.append(" ", new SpacerSpan(hSpace, 0), 0);
|
||||
ssb.append(getResources().getQuantityString(R.plurals.x_posts_today, todayPosts, todayPosts));
|
||||
headerSubtitle.setText(ssb);
|
||||
}
|
||||
|
||||
int styleRes;
|
||||
followButton.setVisibility(View.VISIBLE);
|
||||
if(hashtag.following){
|
||||
followButton.setText(R.string.button_following);
|
||||
styleRes=R.style.Widget_Mastodon_M3_Button_Tonal;
|
||||
}else{
|
||||
followButton.setText(R.string.button_follow);
|
||||
styleRes=R.style.Widget_Mastodon_M3_Button_Filled;
|
||||
}
|
||||
TypedArray ta=followButton.getContext().obtainStyledAttributes(styleRes, new int[]{android.R.attr.background});
|
||||
followButton.setBackground(ta.getDrawable(0));
|
||||
ta.recycle();
|
||||
ta=followButton.getContext().obtainStyledAttributes(styleRes, new int[]{android.R.attr.textColor});
|
||||
followButton.setTextColor(ta.getColorStateList(0));
|
||||
followProgress.setIndeterminateTintList(ta.getColorStateList(0));
|
||||
ta.recycle();
|
||||
|
||||
followButton.setTextVisible(true);
|
||||
followProgress.setVisibility(View.GONE);
|
||||
if(followMenuItem!=null){
|
||||
followMenuItem.setTitle(getString(hashtag.following ? R.string.unfollow_user : R.string.follow_user, "#"+hashtagName));
|
||||
}
|
||||
}
|
||||
|
||||
private void reloadTag(){
|
||||
new GetTag(hashtagName)
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(Hashtag result){
|
||||
hashtag=result;
|
||||
updateHeader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse error){
|
||||
|
||||
}
|
||||
})
|
||||
.exec(accountID);
|
||||
}
|
||||
|
||||
private void setFollowed(boolean followed){
|
||||
if(followRequestRunning)
|
||||
return;
|
||||
followButton.setTextVisible(false);
|
||||
followProgress.setVisibility(View.VISIBLE);
|
||||
followRequestRunning=true;
|
||||
new SetTagFollowed(hashtagName, followed)
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(Hashtag result){
|
||||
if(getActivity()==null)
|
||||
return;
|
||||
hashtag=result;
|
||||
updateHeader();
|
||||
followRequestRunning=false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse error){
|
||||
if(getActivity()==null)
|
||||
return;
|
||||
if(error instanceof MastodonErrorResponse er && "Duplicate record".equals(er.error)){
|
||||
hashtag.following=true;
|
||||
}else{
|
||||
error.showToast(getActivity());
|
||||
}
|
||||
updateHeader();
|
||||
followRequestRunning=false;
|
||||
}
|
||||
})
|
||||
.exec(accountID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,6 +150,7 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
|
||||
});
|
||||
}
|
||||
}
|
||||
tabBar.selectTab(currentTab);
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ public class ProfileFeaturedFragment extends BaseStatusListFragment<SearchResult
|
||||
args.putParcelable("profileAccount", Parcels.wrap(res.account));
|
||||
Nav.go(getActivity(), ProfileFragment.class, args);
|
||||
}
|
||||
case HASHTAG -> UiUtils.openHashtagTimeline(getActivity(), accountID, res.hashtag.name);
|
||||
case HASHTAG -> UiUtils.openHashtagTimeline(getActivity(), accountID, res.hashtag);
|
||||
case STATUS -> {
|
||||
Status status=res.status.getContentStatus();
|
||||
Bundle args=new Bundle();
|
||||
|
||||
@@ -245,15 +245,23 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
|
||||
tabbar.setTabTextColors(UiUtils.getThemeColor(getActivity(), R.attr.colorM3OnSurfaceVariant), UiUtils.getThemeColor(getActivity(), R.attr.colorM3Primary));
|
||||
tabbar.setTabTextSize(V.dp(14));
|
||||
tabLayoutMediator=new TabLayoutMediator(tabbar, pager, new TabLayoutMediator.TabConfigurationStrategy(){
|
||||
tabLayoutMediator=new TabLayoutMediator(tabbar, pager, (tab, position)->tab.setText(switch(position){
|
||||
case 0 -> R.string.profile_featured;
|
||||
case 1 -> R.string.profile_timeline;
|
||||
case 2 -> R.string.profile_about;
|
||||
default -> throw new IllegalStateException();
|
||||
}));
|
||||
tabbar.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener(){
|
||||
@Override
|
||||
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position){
|
||||
tab.setText(switch(position){
|
||||
case 0 -> R.string.profile_featured;
|
||||
case 1 -> R.string.profile_timeline;
|
||||
case 2 -> R.string.profile_about;
|
||||
default -> throw new IllegalStateException();
|
||||
});
|
||||
public void onTabSelected(TabLayout.Tab tab){}
|
||||
|
||||
@Override
|
||||
public void onTabUnselected(TabLayout.Tab tab){}
|
||||
|
||||
@Override
|
||||
public void onTabReselected(TabLayout.Tab tab){
|
||||
if(getFragmentForPage(tab.getPosition()) instanceof ScrollableToTop stt)
|
||||
stt.scrollToTop();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1036,9 +1044,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
@NonNull
|
||||
@Override
|
||||
public SimpleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType){
|
||||
FrameLayout view=tabViews[viewType];
|
||||
((ViewGroup)view.getParent()).removeView(view);
|
||||
view.setVisibility(View.VISIBLE);
|
||||
FrameLayout view=new FrameLayout(parent.getContext());
|
||||
view.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
return new SimpleViewHolder(view);
|
||||
}
|
||||
@@ -1046,8 +1052,13 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull SimpleViewHolder holder, int position){
|
||||
Fragment fragment=getFragmentForPage(position);
|
||||
FrameLayout fragmentView=tabViews[position];
|
||||
fragmentView.setVisibility(View.VISIBLE);
|
||||
if(fragmentView.getParent() instanceof ViewGroup parent)
|
||||
parent.removeView(fragmentView);
|
||||
((FrameLayout)holder.itemView).addView(fragmentView);
|
||||
if(!fragment.isAdded()){
|
||||
getChildFragmentManager().beginTransaction().add(holder.itemView.getId(), fragment).commit();
|
||||
getChildFragmentManager().beginTransaction().add(fragmentView.getId(), fragment).commit();
|
||||
holder.itemView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener(){
|
||||
@Override
|
||||
public boolean onPreDraw(){
|
||||
|
||||
@@ -17,6 +17,7 @@ import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.model.StatusContext;
|
||||
import org.joinmastodon.android.ui.displayitems.ExtendedFooterStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.FooterStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.SpoilerStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.TextStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
@@ -61,6 +62,12 @@ public class ThreadFragment extends StatusListFragment{
|
||||
text.textSelectable=true;
|
||||
else if(item instanceof FooterStatusDisplayItem footer)
|
||||
footer.hideCounts=true;
|
||||
else if(item instanceof SpoilerStatusDisplayItem spoiler){
|
||||
for(StatusDisplayItem subItem:spoiler.contentItems){
|
||||
if(subItem instanceof TextStatusDisplayItem text)
|
||||
text.textSelectable=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
items.add(new ExtendedFooterStatusDisplayItem(s.id, this, s.getContentStatus()));
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public class ComposeAccountSearchFragment extends BaseAccountListFragment{
|
||||
@Override
|
||||
protected void doLoadData(int offset, int count){
|
||||
refreshing=true;
|
||||
currentRequest=new GetSearchResults(currentQuery, GetSearchResults.Type.ACCOUNTS, false)
|
||||
currentRequest=new GetSearchResults(currentQuery, GetSearchResults.Type.ACCOUNTS, false, null, 0, 0)
|
||||
.setCallback(new SimpleCallback<>(this){
|
||||
@Override
|
||||
public void onSuccess(SearchResults result){
|
||||
|
||||
@@ -3,7 +3,6 @@ package org.joinmastodon.android.fragments.discover;
|
||||
import android.app.Activity;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
@@ -20,7 +19,6 @@ import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.ui.displayitems.AccountStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.HashtagStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.tabs.TabLayout;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.parceler.Parcels;
|
||||
|
||||
@@ -28,13 +26,12 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import me.grishka.appkit.Nav;
|
||||
import me.grishka.appkit.api.Callback;
|
||||
import me.grishka.appkit.api.ErrorResponse;
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
public class SearchFragment extends BaseStatusListFragment<SearchResult>{
|
||||
private String currentQuery;
|
||||
@@ -94,7 +91,7 @@ public class SearchFragment extends BaseStatusListFragment<SearchResult>{
|
||||
args.putParcelable("profileAccount", Parcels.wrap(res.account));
|
||||
Nav.go(getActivity(), ProfileFragment.class, args);
|
||||
}
|
||||
case HASHTAG -> UiUtils.openHashtagTimeline(getActivity(), accountID, res.hashtag.name);
|
||||
case HASHTAG -> UiUtils.openHashtagTimeline(getActivity(), accountID, res.hashtag);
|
||||
case STATUS -> {
|
||||
Status status=res.status.getContentStatus();
|
||||
Bundle args=new Bundle();
|
||||
@@ -110,7 +107,7 @@ public class SearchFragment extends BaseStatusListFragment<SearchResult>{
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLoadData(int offset, int count){
|
||||
protected void doLoadData(int _offset, int count){
|
||||
GetSearchResults.Type type;
|
||||
if(currentFilter.size()==1){
|
||||
type=switch(currentFilter.iterator().next()){
|
||||
@@ -125,7 +122,21 @@ public class SearchFragment extends BaseStatusListFragment<SearchResult>{
|
||||
dataLoaded();
|
||||
return;
|
||||
}
|
||||
currentRequest=new GetSearchResults(currentQuery, type, true)
|
||||
String maxID=null;
|
||||
// TODO server-side bug
|
||||
/*int offset=0;
|
||||
if(_offset>0){
|
||||
if(type==GetSearchResults.Type.STATUSES){
|
||||
if(!preloadedData.isEmpty())
|
||||
maxID=preloadedData.get(preloadedData.size()-1).status.id;
|
||||
else if(!data.isEmpty())
|
||||
maxID=data.get(data.size()-1).status.id;
|
||||
}else{
|
||||
offset=_offset;
|
||||
}
|
||||
}*/
|
||||
int offset=_offset;
|
||||
currentRequest=new GetSearchResults(currentQuery, type, type==null, maxID, offset, type==null ? 0 : count)
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(SearchResults result){
|
||||
@@ -139,12 +150,15 @@ public class SearchFragment extends BaseStatusListFragment<SearchResult>{
|
||||
results.add(new SearchResult(tag));
|
||||
}
|
||||
if(result.statuses!=null){
|
||||
for(Status status:result.statuses)
|
||||
results.add(new SearchResult(status));
|
||||
Set<String> alreadyLoadedStatuses=data.stream().filter(r->r.type==SearchResult.Type.STATUS).map(r->r.status.id).collect(Collectors.toSet());
|
||||
for(Status status:result.statuses){
|
||||
if(!alreadyLoadedStatuses.contains(status.id))
|
||||
results.add(new SearchResult(status));
|
||||
}
|
||||
}
|
||||
prevDisplayItems=new ArrayList<>(displayItems);
|
||||
unfilteredResults=results;
|
||||
onDataLoaded(filterSearchResults(results), false);
|
||||
onDataLoaded(filterSearchResults(results), type!=null && !results.isEmpty());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -43,9 +43,7 @@ import org.joinmastodon.android.ui.viewholders.AccountViewHolder;
|
||||
import org.joinmastodon.android.ui.viewholders.SimpleListItemViewHolder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -121,7 +119,7 @@ public class SearchQueryFragment extends MastodonRecyclerFragment<SearchResultVi
|
||||
recentsHeader.setVisible(!data.isEmpty());
|
||||
});
|
||||
}else{
|
||||
currentRequest=new GetSearchResults(currentQuery, null, false)
|
||||
currentRequest=new GetSearchResults(currentQuery, null, false, null, 0, 0)
|
||||
.limit(2)
|
||||
.setCallback(new SimpleCallback<>(this){
|
||||
@Override
|
||||
@@ -377,7 +375,7 @@ public class SearchQueryFragment extends MastodonRecyclerFragment<SearchResultVi
|
||||
}
|
||||
|
||||
private void openHashtag(SearchResult res){
|
||||
UiUtils.openHashtagTimeline(getActivity(), accountID, res.hashtag.name);
|
||||
UiUtils.openHashtagTimeline(getActivity(), accountID, res.hashtag);
|
||||
AccountSessionManager.getInstance().getAccount(accountID).getCacheController().putRecentSearch(res);
|
||||
}
|
||||
|
||||
@@ -386,6 +384,8 @@ public class SearchQueryFragment extends MastodonRecyclerFragment<SearchResultVi
|
||||
}
|
||||
|
||||
private void onSearchViewEnter(){
|
||||
if(TextUtils.isEmpty(currentQuery) || currentQuery.trim().isEmpty())
|
||||
return;
|
||||
deliverResult(currentQuery, null);
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ public class TrendingHashtagsFragment extends BaseRecyclerFragment<Hashtag> impl
|
||||
|
||||
@Override
|
||||
public void onClick(){
|
||||
UiUtils.openHashtagTimeline(getActivity(), accountID, item.name);
|
||||
UiUtils.openHashtagTimeline(getActivity(), accountID, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,7 +271,7 @@ public class SignupFragment extends ToolbarFragment{
|
||||
@Override
|
||||
public void tail(Node node, int depth){
|
||||
if(node instanceof Element){
|
||||
ssb.setSpan(new LinkSpan("", SignupFragment.this::onGoBackLinkClick, LinkSpan.Type.CUSTOM, null), spanStart, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
ssb.setSpan(new LinkSpan("", SignupFragment.this::onGoBackLinkClick, LinkSpan.Type.CUSTOM, null, null), spanStart, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
ssb.setSpan(new TypefaceSpan("sans-serif-medium"), spanStart, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ public class SettingsMainFragment extends BaseSettingsFragment<Void>{
|
||||
onDataLoaded(List.of(
|
||||
new ListItem<>(R.string.settings_behavior, 0, R.drawable.ic_settings_24px, this::onBehaviorClick),
|
||||
new ListItem<>(R.string.settings_display, 0, R.drawable.ic_style_24px, this::onDisplayClick),
|
||||
new ListItem<>(R.string.settings_privacy, 0, R.drawable.ic_privacy_tip_24px, this::onPrivacyClick),
|
||||
new ListItem<>(R.string.settings_filters, 0, R.drawable.ic_filter_alt_24px, this::onFiltersClick),
|
||||
new ListItem<>(R.string.settings_notifications, 0, R.drawable.ic_notifications_24px, this::onNotificationsClick),
|
||||
new ListItem<>(AccountSessionManager.get(accountID).domain, getString(R.string.settings_server_explanation), R.drawable.ic_dns_24px, this::onServerClick),
|
||||
@@ -63,7 +64,9 @@ public class SettingsMainFragment extends BaseSettingsFragment<Void>{
|
||||
data.add(0, new ListItem<>("Debug settings", null, R.drawable.ic_settings_24px, ()->Nav.go(getActivity(), SettingsDebugFragment.class, makeFragmentArgs()), null, 0, true));
|
||||
}
|
||||
|
||||
AccountSessionManager.get(accountID).reloadPreferences(null);
|
||||
AccountSession session=AccountSessionManager.get(accountID);
|
||||
session.reloadPreferences(null);
|
||||
session.updateAccountInfo();
|
||||
E.register(this);
|
||||
}
|
||||
|
||||
@@ -127,6 +130,10 @@ public class SettingsMainFragment extends BaseSettingsFragment<Void>{
|
||||
Nav.go(getActivity(), SettingsDisplayFragment.class, makeFragmentArgs());
|
||||
}
|
||||
|
||||
private void onPrivacyClick(){
|
||||
Nav.go(getActivity(), SettingsPrivacyFragment.class, makeFragmentArgs());
|
||||
}
|
||||
|
||||
private void onFiltersClick(){
|
||||
Nav.go(getActivity(), SettingsFiltersFragment.class, makeFragmentArgs());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package org.joinmastodon.android.fragments.settings;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.viewmodel.CheckableListItem;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SettingsPrivacyFragment extends BaseSettingsFragment<Void>{
|
||||
private CheckableListItem<Void> discoverableItem, indexableItem;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState){
|
||||
super.onCreate(savedInstanceState);
|
||||
setTitle(R.string.settings_privacy);
|
||||
Account self=AccountSessionManager.get(accountID).self;
|
||||
onDataLoaded(List.of(
|
||||
discoverableItem=new CheckableListItem<>(R.string.settings_discoverable, 0, CheckableListItem.Style.SWITCH, self.discoverable, R.drawable.ic_thumbs_up_down_24px, ()->toggleCheckableItem(discoverableItem)),
|
||||
indexableItem=new CheckableListItem<>(R.string.settings_indexable, 0, CheckableListItem.Style.SWITCH, self.source.indexable!=null ? self.source.indexable : true, R.drawable.ic_search_24px, ()->toggleCheckableItem(indexableItem))
|
||||
));
|
||||
if(self.source.indexable==null)
|
||||
indexableItem.isEnabled=false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLoadData(int offset, int count){}
|
||||
|
||||
@Override
|
||||
public void onPause(){
|
||||
super.onPause();
|
||||
Account self=AccountSessionManager.get(accountID).self;
|
||||
if(self.discoverable!=discoverableItem.checked || (self.source.indexable!=null && self.source.indexable!=indexableItem.checked)){
|
||||
self.discoverable=discoverableItem.checked;
|
||||
self.source.indexable=indexableItem.checked;
|
||||
AccountSessionManager.get(accountID).savePreferencesLater();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,6 +132,7 @@ public class Account extends BaseModel{
|
||||
* When a timed mute will expire, if applicable.
|
||||
*/
|
||||
public Instant muteExpiresAt;
|
||||
public boolean noindex;
|
||||
|
||||
|
||||
@Override
|
||||
@@ -191,6 +192,7 @@ public class Account extends BaseModel{
|
||||
", source="+source+
|
||||
", suspended="+suspended+
|
||||
", muteExpiresAt="+muteExpiresAt+
|
||||
", noindex="+noindex+
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ public class Hashtag extends BaseModel implements DisplayItemsParent{
|
||||
public String url;
|
||||
public List<History> history;
|
||||
public int statusesCount;
|
||||
public boolean following;
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
@@ -21,6 +22,7 @@ public class Hashtag extends BaseModel implements DisplayItemsParent{
|
||||
", url='"+url+'\''+
|
||||
", history="+history+
|
||||
", statusesCount="+statusesCount+
|
||||
", following="+following+
|
||||
'}';
|
||||
}
|
||||
|
||||
@@ -28,4 +30,19 @@ public class Hashtag extends BaseModel implements DisplayItemsParent{
|
||||
public String getID(){
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o){
|
||||
if(this==o) return true;
|
||||
if(o==null || getClass()!=o.getClass()) return false;
|
||||
|
||||
Hashtag hashtag=(Hashtag) o;
|
||||
|
||||
return name.equals(hashtag.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode(){
|
||||
return name.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,4 +20,22 @@ public class Mention extends BaseModel{
|
||||
", url='"+url+'\''+
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o){
|
||||
if(this==o) return true;
|
||||
if(o==null || getClass()!=o.getClass()) return false;
|
||||
|
||||
Mention mention=(Mention) o;
|
||||
|
||||
if(!id.equals(mention.id)) return false;
|
||||
return url.equals(mention.url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode(){
|
||||
int result=id.hashCode();
|
||||
result=31*result+url.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,8 @@ public class Source extends BaseModel{
|
||||
* The number of pending follow requests.
|
||||
*/
|
||||
public int followRequestCount;
|
||||
public Boolean indexable;
|
||||
public boolean hideCollections;
|
||||
|
||||
@Override
|
||||
public void postprocess() throws ObjectValidationException{
|
||||
@@ -54,6 +56,8 @@ public class Source extends BaseModel{
|
||||
", sensitive="+sensitive+
|
||||
", language='"+language+'\''+
|
||||
", followRequestCount="+followRequestCount+
|
||||
", indexable="+indexable+
|
||||
", hideCollections="+hideCollections+
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.joinmastodon.android.api.ObjectValidationException;
|
||||
import org.joinmastodon.android.api.RequiredField;
|
||||
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
|
||||
@@ -8,6 +10,8 @@ import org.parceler.Parcel;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
@@ -61,6 +65,8 @@ public class Status extends BaseModel implements DisplayItemsParent{
|
||||
public transient boolean spoilerRevealed;
|
||||
public transient boolean hasGapAfter;
|
||||
private transient String strippedText;
|
||||
public transient TranslationState translationState=TranslationState.HIDDEN;
|
||||
public transient Translation translation;
|
||||
|
||||
public Status(){}
|
||||
|
||||
@@ -161,6 +167,18 @@ public class Status extends BaseModel implements DisplayItemsParent{
|
||||
public Status clone(){
|
||||
Status copy=(Status) super.clone();
|
||||
copy.spoilerRevealed=false;
|
||||
copy.translationState=TranslationState.HIDDEN;
|
||||
return copy;
|
||||
}
|
||||
|
||||
public boolean isEligibleForTranslation(){
|
||||
return !TextUtils.isEmpty(content) && !TextUtils.isEmpty(language) && !Objects.equals(Locale.getDefault().getLanguage(), language)
|
||||
&& (visibility==StatusPrivacy.PUBLIC || visibility==StatusPrivacy.UNLISTED);
|
||||
}
|
||||
|
||||
public enum TranslationState{
|
||||
HIDDEN,
|
||||
SHOWN,
|
||||
LOADING
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import org.joinmastodon.android.api.AllFieldsAreRequired;
|
||||
|
||||
@AllFieldsAreRequired
|
||||
public class Translation extends BaseModel{
|
||||
public String content;
|
||||
public String detectedSourceLanguage;
|
||||
public String provider;
|
||||
}
|
||||
@@ -41,6 +41,7 @@ import org.parceler.Parcels;
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import androidx.annotation.LayoutRes;
|
||||
import me.grishka.appkit.Nav;
|
||||
@@ -195,6 +196,8 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||
AccountSessionManager.getInstance().getAccount(item.accountID).getStatusInteractionController().setBookmarked(item.status, !item.status.bookmarked);
|
||||
}else if(id==R.id.share){
|
||||
UiUtils.openSystemShareSheet(activity, item.status.url);
|
||||
}else if(id==R.id.translate){
|
||||
item.parentFragment.togglePostTranslation(item.status, item.parentID);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
@@ -285,6 +288,15 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||
Account account=item.user;
|
||||
Menu menu=optionsMenu.getMenu();
|
||||
boolean isOwnPost=AccountSessionManager.getInstance().isSelf(item.parentFragment.getAccountID(), account);
|
||||
boolean canTranslate=item.status!=null && item.status.getContentStatus().isEligibleForTranslation();
|
||||
MenuItem translate=menu.findItem(R.id.translate);
|
||||
translate.setVisible(canTranslate);
|
||||
if(canTranslate){
|
||||
if(item.status.translationState==Status.TranslationState.SHOWN)
|
||||
translate.setTitle(R.string.translation_show_original);
|
||||
else
|
||||
translate.setTitle(item.parentFragment.getString(R.string.translate_post, Locale.forLanguageTag(item.status.getContentStatus().language).getDisplayLanguage()));
|
||||
}
|
||||
menu.findItem(R.id.edit).setVisible(item.status!=null && isOwnPost);
|
||||
menu.findItem(R.id.delete).setVisible(item.status!=null && isOwnPost);
|
||||
menu.findItem(R.id.open_in_browser).setVisible(item.status!=null);
|
||||
|
||||
@@ -8,6 +8,7 @@ import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
import org.joinmastodon.android.model.Emoji;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
@@ -29,7 +30,8 @@ public class ReblogOrReplyLineStatusDisplayItem extends StatusDisplayItem{
|
||||
public ReblogOrReplyLineStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, CharSequence text, List<Emoji> emojis, @DrawableRes int icon){
|
||||
super(parentID, parentFragment);
|
||||
SpannableStringBuilder ssb=new SpannableStringBuilder(text);
|
||||
HtmlParser.parseCustomEmoji(ssb, emojis);
|
||||
if(AccountSessionManager.get(parentFragment.getAccountID()).getLocalPreferences().customEmojiInNames)
|
||||
HtmlParser.parseCustomEmoji(ssb, emojis);
|
||||
this.text=ssb;
|
||||
emojiHelper.setText(ssb);
|
||||
this.icon=icon;
|
||||
|
||||
@@ -3,15 +3,24 @@ package org.joinmastodon.android.ui.displayitems;
|
||||
import android.app.Activity;
|
||||
import android.graphics.drawable.Animatable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewStub;
|
||||
import android.widget.Button;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.joinmastodon.android.ui.views.LinkedTextView;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import me.grishka.appkit.imageloader.ImageLoaderViewHolder;
|
||||
import me.grishka.appkit.imageloader.MovieDrawable;
|
||||
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
|
||||
@@ -20,6 +29,8 @@ import me.grishka.appkit.utils.V;
|
||||
public class TextStatusDisplayItem extends StatusDisplayItem{
|
||||
private CharSequence text;
|
||||
private CustomEmojiHelper emojiHelper=new CustomEmojiHelper();
|
||||
private CharSequence translatedText;
|
||||
private CustomEmojiHelper translationEmojiHelper=new CustomEmojiHelper();
|
||||
public boolean textSelectable;
|
||||
public boolean reduceTopPadding;
|
||||
public final Status status;
|
||||
@@ -38,30 +49,54 @@ public class TextStatusDisplayItem extends StatusDisplayItem{
|
||||
|
||||
@Override
|
||||
public int getImageCount(){
|
||||
return emojiHelper.getImageCount();
|
||||
return getCurrentEmojiHelper().getImageCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageLoaderRequest getImageRequest(int index){
|
||||
return emojiHelper.getImageRequest(index);
|
||||
return getCurrentEmojiHelper().getImageRequest(index);
|
||||
}
|
||||
|
||||
public void setTranslatedText(String text){
|
||||
Status statusForContent=status.getContentStatus();
|
||||
translatedText=HtmlParser.parse(text, statusForContent.emojis, statusForContent.mentions, statusForContent.tags, parentFragment.getAccountID());
|
||||
translationEmojiHelper.setText(translatedText);
|
||||
}
|
||||
|
||||
private CustomEmojiHelper getCurrentEmojiHelper(){
|
||||
return status.translationState==Status.TranslationState.SHOWN ? translationEmojiHelper : emojiHelper;
|
||||
}
|
||||
|
||||
public static class Holder extends StatusDisplayItem.Holder<TextStatusDisplayItem> implements ImageLoaderViewHolder{
|
||||
private final LinkedTextView text;
|
||||
private final ViewStub translationFooterStub;
|
||||
private View translationFooter;
|
||||
private TextView translationInfo;
|
||||
private Button translationShowOriginal;
|
||||
private ProgressBar translationProgress;
|
||||
|
||||
public Holder(Activity activity, ViewGroup parent){
|
||||
super(activity, R.layout.display_item_text, parent);
|
||||
text=findViewById(R.id.text);
|
||||
translationFooterStub=findViewById(R.id.translation_info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(TextStatusDisplayItem item){
|
||||
text.setText(item.text);
|
||||
if(item.status.translationState==Status.TranslationState.SHOWN){
|
||||
if(item.translatedText==null){
|
||||
item.setTranslatedText(item.status.translation.content);
|
||||
}
|
||||
text.setText(item.translatedText);
|
||||
}else{
|
||||
text.setText(item.text);
|
||||
}
|
||||
text.setTextIsSelectable(item.textSelectable);
|
||||
text.setInvalidateOnEveryFrame(false);
|
||||
itemView.setClickable(false);
|
||||
text.setPadding(text.getPaddingLeft(), item.reduceTopPadding ? V.dp(8) : V.dp(16), text.getPaddingRight(), text.getPaddingBottom());
|
||||
text.setTextColor(UiUtils.getThemeColor(text.getContext(), item.inset ? R.attr.colorM3OnSurfaceVariant : R.attr.colorM3OnSurface));
|
||||
updateTranslation(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -84,5 +119,43 @@ public class TextStatusDisplayItem extends StatusDisplayItem{
|
||||
private CustomEmojiHelper getEmojiHelper(){
|
||||
return item.emojiHelper;
|
||||
}
|
||||
|
||||
public void updateTranslation(boolean updateText){
|
||||
if(item.status==null)
|
||||
return;
|
||||
if(item.status.translationState==Status.TranslationState.HIDDEN){
|
||||
if(translationFooter!=null)
|
||||
translationFooter.setVisibility(View.GONE);
|
||||
if(updateText){
|
||||
text.setText(item.text);
|
||||
}
|
||||
}else{
|
||||
if(translationFooter==null){
|
||||
translationFooter=translationFooterStub.inflate();
|
||||
translationInfo=findViewById(R.id.translation_info_text);
|
||||
translationShowOriginal=findViewById(R.id.translation_show_original);
|
||||
translationProgress=findViewById(R.id.translation_progress);
|
||||
translationShowOriginal.setOnClickListener(v->item.parentFragment.togglePostTranslation(item.status, item.parentID));
|
||||
}else{
|
||||
translationFooter.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if(item.status.translationState==Status.TranslationState.SHOWN){
|
||||
translationProgress.setVisibility(View.GONE);
|
||||
translationInfo.setVisibility(View.VISIBLE);
|
||||
translationShowOriginal.setVisibility(View.VISIBLE);
|
||||
translationInfo.setText(translationInfo.getContext().getString(R.string.post_translated, Locale.forLanguageTag(item.status.translation.detectedSourceLanguage).getDisplayLanguage(), item.status.translation.provider));
|
||||
if(updateText){
|
||||
if(item.translatedText==null){
|
||||
item.setTranslatedText(item.status.translation.content);
|
||||
}
|
||||
text.setText(item.translatedText);
|
||||
}
|
||||
}else{ // LOADING
|
||||
translationProgress.setVisibility(View.VISIBLE);
|
||||
translationInfo.setVisibility(View.INVISIBLE);
|
||||
translationShowOriginal.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -859,6 +859,8 @@ public class PhotoViewer implements ZoomPanView.Listener{
|
||||
|
||||
@Override
|
||||
public void onVideoSizeChanged(MediaPlayer mp, int width, int height){
|
||||
if(width<=0 || height<=0)
|
||||
return;
|
||||
FrameLayout.LayoutParams params=(FrameLayout.LayoutParams) wrap.getLayoutParams();
|
||||
params.width=width;
|
||||
params.height=height;
|
||||
|
||||
@@ -119,6 +119,9 @@ public class ZoomPanView extends FrameLayout implements ScaleGestureDetector.OnS
|
||||
|
||||
int width=right-left;
|
||||
int height=bottom-top;
|
||||
if(width==0 || height==0)
|
||||
return;
|
||||
|
||||
float scale=Math.min(width/(float)child.getWidth(), height/(float)child.getHeight());
|
||||
minScale=scale;
|
||||
maxScale=Math.max(3f, height/(float)child.getHeight());
|
||||
@@ -306,8 +309,6 @@ public class ZoomPanView extends FrameLayout implements ScaleGestureDetector.OnS
|
||||
}, 1f).setMinimumVisibleChange(DynamicAnimation.MIN_VISIBLE_CHANGE_ALPHA));
|
||||
}
|
||||
}else{
|
||||
if(animatingTransition)
|
||||
Log.w(TAG, "updateViewTransform: ", new Throwable().fillInStackTrace());
|
||||
child.setScaleX(matrixValues[Matrix.MSCALE_X]);
|
||||
child.setScaleY(matrixValues[Matrix.MSCALE_Y]);
|
||||
child.setTranslationX(matrixValues[Matrix.MTRANS_X]);
|
||||
|
||||
@@ -81,9 +81,10 @@ public class HtmlParser{
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, String> idsByUrl=mentions.stream().collect(Collectors.toMap(m->m.url, m->m.id));
|
||||
Map<String, String> idsByUrl=mentions.stream().distinct().collect(Collectors.toMap(m->m.url, m->m.id));
|
||||
// Hashtags in remote posts have remote URLs, these have local URLs so they don't match.
|
||||
// Map<String, String> tagsByUrl=tags.stream().collect(Collectors.toMap(t->t.url, t->t.name));
|
||||
Map<String, Hashtag> tagsByTag=tags.stream().distinct().collect(Collectors.toMap(t->t.name.toLowerCase(), Function.identity()));
|
||||
|
||||
final SpannableStringBuilder ssb=new SpannableStringBuilder();
|
||||
Jsoup.parseBodyFragment(source).body().traverse(new NodeVisitor(){
|
||||
@@ -96,6 +97,7 @@ public class HtmlParser{
|
||||
}else if(node instanceof Element el){
|
||||
switch(el.nodeName()){
|
||||
case "a" -> {
|
||||
Object linkObject=null;
|
||||
String href=el.attr("href");
|
||||
LinkSpan.Type linkType;
|
||||
if(el.hasClass("hashtag")){
|
||||
@@ -103,6 +105,7 @@ public class HtmlParser{
|
||||
if(text.startsWith("#")){
|
||||
linkType=LinkSpan.Type.HASHTAG;
|
||||
href=text.substring(1);
|
||||
linkObject=tagsByTag.get(text.substring(1).toLowerCase());
|
||||
}else{
|
||||
linkType=LinkSpan.Type.URL;
|
||||
}
|
||||
@@ -117,7 +120,7 @@ public class HtmlParser{
|
||||
}else{
|
||||
linkType=LinkSpan.Type.URL;
|
||||
}
|
||||
openSpans.add(new SpanInfo(new LinkSpan(href, null, linkType, accountID), ssb.length(), el));
|
||||
openSpans.add(new SpanInfo(new LinkSpan(href, null, linkType, accountID, linkObject), ssb.length(), el));
|
||||
}
|
||||
case "br" -> ssb.append('\n');
|
||||
case "span" -> {
|
||||
@@ -213,7 +216,7 @@ public class HtmlParser{
|
||||
String url=matcher.group(3);
|
||||
if(TextUtils.isEmpty(matcher.group(4)))
|
||||
url="http://"+url;
|
||||
ssb.setSpan(new LinkSpan(url, null, LinkSpan.Type.URL, null), matcher.start(3), matcher.end(3), 0);
|
||||
ssb.setSpan(new LinkSpan(url, null, LinkSpan.Type.URL, null, null), matcher.start(3), matcher.end(3), 0);
|
||||
}while(matcher.find()); // Find more URLs
|
||||
return ssb;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.content.Context;
|
||||
import android.text.TextPaint;
|
||||
import android.text.style.CharacterStyle;
|
||||
|
||||
import org.joinmastodon.android.model.Hashtag;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
|
||||
public class LinkSpan extends CharacterStyle {
|
||||
@@ -13,12 +14,14 @@ public class LinkSpan extends CharacterStyle {
|
||||
private String link;
|
||||
private Type type;
|
||||
private String accountID;
|
||||
private Object linkObject;
|
||||
|
||||
public LinkSpan(String link, OnLinkClickListener listener, Type type, String accountID){
|
||||
public LinkSpan(String link, OnLinkClickListener listener, Type type, String accountID, Object linkObject){
|
||||
this.listener=listener;
|
||||
this.link=link;
|
||||
this.type=type;
|
||||
this.accountID=accountID;
|
||||
this.linkObject=linkObject;
|
||||
}
|
||||
|
||||
public int getColor(){
|
||||
@@ -35,7 +38,12 @@ public class LinkSpan extends CharacterStyle {
|
||||
switch(getType()){
|
||||
case URL -> UiUtils.openURL(context, accountID, link);
|
||||
case MENTION -> UiUtils.openProfileByID(context, accountID, link);
|
||||
case HASHTAG -> UiUtils.openHashtagTimeline(context, accountID, link);
|
||||
case HASHTAG -> {
|
||||
if(linkObject instanceof Hashtag ht)
|
||||
UiUtils.openHashtagTimeline(context, accountID, ht);
|
||||
else
|
||||
UiUtils.openHashtagTimeline(context, accountID, link);
|
||||
}
|
||||
case CUSTOM -> listener.onLinkClick(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ import org.joinmastodon.android.fragments.ProfileFragment;
|
||||
import org.joinmastodon.android.fragments.ThreadFragment;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.Emoji;
|
||||
import org.joinmastodon.android.model.Hashtag;
|
||||
import org.joinmastodon.android.model.Relationship;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||
@@ -342,10 +343,17 @@ public class UiUtils{
|
||||
Nav.go((Activity)context, ProfileFragment.class, args);
|
||||
}
|
||||
|
||||
public static void openHashtagTimeline(Context context, String accountID, Hashtag hashtag){
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
args.putParcelable("hashtag", Parcels.wrap(hashtag));
|
||||
Nav.go((Activity)context, HashtagTimelineFragment.class, args);
|
||||
}
|
||||
|
||||
public static void openHashtagTimeline(Context context, String accountID, String hashtag){
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
args.putString("hashtag", hashtag);
|
||||
args.putString("hashtagName", hashtag);
|
||||
Nav.go((Activity)context, HashtagTimelineFragment.class, args);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,15 +15,12 @@ import android.widget.TextView;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.search.GetSearchResults;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.Emoji;
|
||||
import org.joinmastodon.android.model.Hashtag;
|
||||
import org.joinmastodon.android.model.SearchResults;
|
||||
import org.joinmastodon.android.model.viewmodel.AccountViewModel;
|
||||
import org.joinmastodon.android.ui.BetterItemAnimator;
|
||||
import org.joinmastodon.android.ui.OutlineProviders;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
|
||||
import org.joinmastodon.android.ui.utils.HideableSingleViewRecyclerAdapter;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.joinmastodon.android.ui.views.FilterChipView;
|
||||
@@ -96,6 +93,24 @@ public class ComposeAutocompleteViewController{
|
||||
outRect.right=V.dp(8);
|
||||
}
|
||||
});
|
||||
// Set empty adapter to prevent NPEs
|
||||
list.setAdapter(new RecyclerView.Adapter<>(){
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType){
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount(){
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
contentView.addView(list, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
|
||||
emptyButton=new FilterChipView(activity);
|
||||
@@ -222,11 +237,13 @@ public class ComposeAutocompleteViewController{
|
||||
}
|
||||
|
||||
private void doSearchUsers(){
|
||||
currentRequest=new GetSearchResults(lastText, GetSearchResults.Type.ACCOUNTS, false)
|
||||
currentRequest=new GetSearchResults(lastText, GetSearchResults.Type.ACCOUNTS, false, null, 0, 0)
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(SearchResults result){
|
||||
currentRequest=null;
|
||||
if(mode!=Mode.USERS)
|
||||
return;
|
||||
List<AccountViewModel> oldList=users;
|
||||
users=result.accounts.stream().map(a->new AccountViewModel(a, accountID)).collect(Collectors.toList());
|
||||
if(isLoading){
|
||||
@@ -256,7 +273,7 @@ public class ComposeAutocompleteViewController{
|
||||
}
|
||||
|
||||
private void doSearchHashtags(){
|
||||
currentRequest=new GetSearchResults(lastText, GetSearchResults.Type.HASHTAGS, false)
|
||||
currentRequest=new GetSearchResults(lastText, GetSearchResults.Type.HASHTAGS, false, null, 0, 0)
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(SearchResults result){
|
||||
|
||||
@@ -74,9 +74,9 @@ public class ComposePollViewController{
|
||||
pollWrap=view.findViewById(R.id.poll_wrap);
|
||||
|
||||
Instance instance=fragment.instance;
|
||||
if(instance.configuration!=null && instance.configuration.polls!=null && instance.configuration.polls.maxOptions>0)
|
||||
if(instance!=null && instance.configuration!=null && instance.configuration.polls!=null && instance.configuration.polls.maxOptions>0)
|
||||
maxPollOptions=instance.configuration.polls.maxOptions;
|
||||
if(instance.configuration!=null && instance.configuration.polls!=null && instance.configuration.polls.maxCharactersPerOption>0)
|
||||
if(instance!=null && instance.configuration!=null && instance.configuration.polls!=null && instance.configuration.polls.maxCharactersPerOption>0)
|
||||
maxPollOptionLength=instance.configuration.polls.maxCharactersPerOption;
|
||||
|
||||
pollOptionsView=pollWrap.findViewById(R.id.poll_options);
|
||||
|
||||
@@ -18,7 +18,7 @@ public class MediaGridLayout extends ViewGroup{
|
||||
public static final int MAX_WIDTH=400; // dp
|
||||
private static final int GAP=2; // dp
|
||||
private PhotoLayoutHelper.TiledLayoutResult tiledLayout;
|
||||
private int[] columnStarts=new int[10], columnEnds=new int[10], rowStarts=new int[10], rowEnds=new int[10];
|
||||
private int[] columnStarts, columnEnds, rowStarts, rowEnds;
|
||||
|
||||
public MediaGridLayout(Context context){
|
||||
this(context, null);
|
||||
@@ -45,6 +45,14 @@ public class MediaGridLayout extends ViewGroup{
|
||||
width=Math.round(width*(tiledLayout.width/(float)PhotoLayoutHelper.MAX_WIDTH));
|
||||
}
|
||||
|
||||
if(rowStarts==null || rowStarts.length<tiledLayout.rowSizes.length){
|
||||
rowStarts=new int[tiledLayout.rowSizes.length];
|
||||
rowEnds=new int[tiledLayout.rowSizes.length];
|
||||
}
|
||||
if(columnStarts==null || columnStarts.length<tiledLayout.columnSizes.length){
|
||||
columnStarts=new int[tiledLayout.columnSizes.length];
|
||||
columnEnds=new int[tiledLayout.columnSizes.length];
|
||||
}
|
||||
int offset=0;
|
||||
for(int i=0;i<tiledLayout.columnSizes.length;i++){
|
||||
columnStarts[i]=offset;
|
||||
@@ -77,7 +85,7 @@ public class MediaGridLayout extends ViewGroup{
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b){
|
||||
if(tiledLayout==null)
|
||||
if(tiledLayout==null || rowStarts==null)
|
||||
return;
|
||||
|
||||
int maxWidth=V.dp(MAX_WIDTH);
|
||||
|
||||
9
mastodon/src/main/res/drawable/ic_privacy_tip_24px.xml
Normal file
9
mastodon/src/main/res/drawable/ic_privacy_tip_24px.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:fillColor="@android:color/white"
|
||||
android:pathData="M11,17H13V11H11ZM12,9Q12.425,9 12.713,8.712Q13,8.425 13,8Q13,7.575 12.713,7.287Q12.425,7 12,7Q11.575,7 11.288,7.287Q11,7.575 11,8Q11,8.425 11.288,8.712Q11.575,9 12,9ZM12,22Q8.525,21.125 6.263,18.012Q4,14.9 4,11.1V5L12,2L20,5V11.1Q20,14.9 17.738,18.012Q15.475,21.125 12,22ZM12,19.9Q14.6,19.075 16.3,16.6Q18,14.125 18,11.1V6.375L12,4.125L6,6.375V11.1Q6,14.125 7.7,16.6Q9.4,19.075 12,19.9ZM12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Z"/>
|
||||
</vector>
|
||||
@@ -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:fillColor="@android:color/white"
|
||||
android:pathData="M2,14Q1.175,14 0.588,13.412Q0,12.825 0,12V6Q0,5.7 0.125,5.425Q0.25,5.15 0.45,4.95L5.4,0L6.15,0.75Q6.3,0.9 6.4,1.137Q6.5,1.375 6.5,1.6V1.8L5.8,5H11Q11.425,5 11.713,5.287Q12,5.575 12,6V7.25Q12,7.4 11.975,7.537Q11.95,7.675 11.9,7.8L9.65,13.1Q9.475,13.525 9.088,13.762Q8.7,14 8.25,14ZM7.95,12 L10,7.15V7Q10,7 10,7Q10,7 10,7H3.35L3.95,4.3L2,6.2V12Q2,12 2,12Q2,12 2,12ZM18.6,24 L17.85,23.25Q17.7,23.1 17.6,22.863Q17.5,22.625 17.5,22.4V22.2L18.2,19H13Q12.575,19 12.288,18.712Q12,18.425 12,18V16.75Q12,16.6 12.025,16.462Q12.05,16.325 12.1,16.2L14.35,10.9Q14.55,10.475 14.925,10.238Q15.3,10 15.75,10H22Q22.825,10 23.413,10.587Q24,11.175 24,12V18Q24,18.3 23.888,18.562Q23.775,18.825 23.55,19.05ZM16.05,12 L14,16.85V17Q14,17 14,17Q14,17 14,17H20.65L20.05,19.7L22,17.8V12Q22,12 22,12Q22,12 22,12ZM2,12V6.2V7Q2,7 2,7Q2,7 2,7V7.15V12Q2,12 2,12Q2,12 2,12ZM22,12V17.8V17Q22,17 22,17Q22,17 22,17V16.85V12Q22,12 22,12Q22,12 22,12Z"/>
|
||||
</vector>
|
||||
@@ -1,8 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<org.joinmastodon.android.ui.views.LinkedTextView
|
||||
android:id="@+id/text"
|
||||
@@ -16,4 +17,10 @@
|
||||
android:paddingBottom="8dp"
|
||||
android:textAppearance="@style/m3_body_large"/>
|
||||
|
||||
</FrameLayout>
|
||||
<ViewStub
|
||||
android:id="@+id/translation_info"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout="@layout/footer_text_translation"/>
|
||||
|
||||
</LinearLayout>
|
||||
44
mastodon/src/main/res/layout/footer_text_translation.xml
Normal file
44
mastodon/src/main/res/layout/footer_text_translation.xml
Normal file
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
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">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/translation_progress"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center"
|
||||
style="?android:progressBarStyleSmall"/>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:paddingVertical="8dp"
|
||||
android:clipToPadding="false"
|
||||
android:baselineAligned="false"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/translation_info_text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:textAppearance="@style/m3_body_small"
|
||||
android:textColor="?colorM3Secondary"
|
||||
tools:text="Translated from Japanese using DeepL.com"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/translation_show_original"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
style="@style/Widget.Mastodon.M3.Button.Text"
|
||||
android:paddingHorizontal="8dp"
|
||||
android:layout_marginEnd="-8dp"
|
||||
android:text="@string/translation_show_original"/>
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
62
mastodon/src/main/res/layout/header_hashtag_timeline.xml
Normal file
62
mastodon/src/main/res/layout/header_hashtag_timeline.xml
Normal file
@@ -0,0 +1,62 @@
|
||||
<?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:paddingHorizontal="16dp"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toStartOf="@id/follow_btn_wrap"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:textAppearance="@style/m3_headline_small"
|
||||
android:textColor="?colorM3OnSurface"
|
||||
android:maxLines="4"
|
||||
android:ellipsize="end"
|
||||
android:minHeight="36dp"
|
||||
android:gravity="center_vertical"
|
||||
tools:text="#CatsOfMastodonButLong"/>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/follow_btn_wrap"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@id/title"
|
||||
android:layout_alignBottom="@id/title"
|
||||
android:layout_alignParentEnd="true">
|
||||
|
||||
<org.joinmastodon.android.ui.views.ProgressBarButton
|
||||
android:id="@+id/profile_action_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="36dp"
|
||||
android:layout_gravity="center"
|
||||
style="@style/Widget.Mastodon.M3.Button.Filled"
|
||||
android:paddingHorizontal="16dp"
|
||||
tools:text="@string/button_follow" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/action_progress"
|
||||
style="?android:progressBarStyleSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:elevation="10dp"
|
||||
android:indeterminate="true"
|
||||
android:outlineProvider="none"
|
||||
android:visibility="gone" />
|
||||
</FrameLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/subtitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/title"
|
||||
android:layout_marginTop="8dp"
|
||||
android:textAppearance="@style/m3_label_large"
|
||||
android:textColor="?colorM3OnSurfaceVariant"
|
||||
tools:text="123 posts"/>
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<group android:id="@+id/menu_group1">
|
||||
<!-- TODO translate -->
|
||||
<item android:id="@+id/translate" android:title="@string/translate_post"/>
|
||||
<item android:id="@+id/bookmark" android:title="@string/add_bookmark"/>
|
||||
<item android:id="@+id/share" android:title="@string/button_share"/>
|
||||
<item android:id="@+id/open_in_browser" android:title="@string/open_in_browser"/>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<string name="ok">حسنًا</string>
|
||||
<string name="preparing_auth">جَارٍ الإعدَادُ لِلمُصادَقَة…</string>
|
||||
<string name="finishing_auth">يُنهي المصادقة…</string>
|
||||
<string name="user_boosted">%s إعادة نشر</string>
|
||||
<string name="user_boosted">قام %s بإعادة نشر</string>
|
||||
<string name="in_reply_to">ردًا على %s</string>
|
||||
<string name="notifications">الإشعارات</string>
|
||||
<string name="user_followed_you">%s بَدَأ بِمُتابَعَتِك</string>
|
||||
@@ -242,7 +242,7 @@
|
||||
<string name="skip">تخطى</string>
|
||||
<string name="notification_type_follow">متابعُون جُدُد</string>
|
||||
<string name="notification_type_favorite">المفضلة</string>
|
||||
<string name="notification_type_reblog">المشاركات</string>
|
||||
<string name="notification_type_reblog">المعاد نشرها</string>
|
||||
<string name="notification_type_mention">الإشارات</string>
|
||||
<string name="notification_type_poll">استطلاع رأي</string>
|
||||
<string name="choose_account">اختر حسابًا</string>
|
||||
@@ -277,7 +277,7 @@
|
||||
<string name="more_options">مزيد من الخيارات</string>
|
||||
<string name="new_post">منشور جديد</string>
|
||||
<string name="button_reply">ردّ</string>
|
||||
<string name="button_reblog">شارك</string>
|
||||
<string name="button_reblog">إعادة النشر</string>
|
||||
<string name="button_favorite">فضّل</string>
|
||||
<string name="button_share">شارك</string>
|
||||
<string name="media_no_description">وسائط بدون وصف</string>
|
||||
@@ -292,8 +292,8 @@
|
||||
<string name="followed_user">أنت تتابع الآن %s</string>
|
||||
<string name="following_user_requested">طَلَبَ %s مُتابَعتك</string>
|
||||
<string name="open_in_browser">افتح في المتصفح</string>
|
||||
<string name="hide_boosts_from_user">اخف مشاركات %s</string>
|
||||
<string name="show_boosts_from_user">أظهر مشاركات %s</string>
|
||||
<string name="hide_boosts_from_user">أخفِ المعاد نشرها مِن %s</string>
|
||||
<string name="show_boosts_from_user">أظهر ما أعاد %s نشرَه</string>
|
||||
<string name="signup_reason">لماذا تريد الانضمام؟</string>
|
||||
<string name="signup_reason_note">هذا سوف يساعدنا في مراجعة تطبيقك.</string>
|
||||
<string name="clear">امسح</string>
|
||||
@@ -346,10 +346,10 @@
|
||||
<item quantity="other">%,d تفضيل</item>
|
||||
</plurals>
|
||||
<plurals name="x_reblogs">
|
||||
<item quantity="zero">%,d إعادة نشر</item>
|
||||
<item quantity="zero">لم يُعد نشره</item>
|
||||
<item quantity="one">إعادة نشر واحدة</item>
|
||||
<item quantity="two">أعيد نشره مرّتان</item>
|
||||
<item quantity="few">أعيد نشره %,d مرة</item>
|
||||
<item quantity="few">أعيد نشره %,d مرات</item>
|
||||
<item quantity="many">أعيد نشره %,d مرات</item>
|
||||
<item quantity="other">أعيد نشره %,d مرات</item>
|
||||
</plurals>
|
||||
@@ -698,4 +698,18 @@
|
||||
<string name="time_minutes_ago_short">مُنذُ %dد</string>
|
||||
<string name="time_hours_ago_short">مُنذُ %dسا</string>
|
||||
<string name="time_days_ago_short">مُنذُ %d أيام</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<string name="translate_post">تُرجِم مِن %s</string>
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
<string name="post_translated">مُترجَم مِن %1$s باستخدام %2$s</string>
|
||||
<string name="translation_show_original">إظهار الأصل</string>
|
||||
<string name="translation_failed">فشِلَت الترجَمة. قد لم يتمكّن مدير الخادم من تفعيل الترجمات على هذا الخادم أو أنّ هذا الخادم يُشغِّل نسخة قديمة من ماستدون حيث الترجمات غير مدعومة بعد.</string>
|
||||
<plurals name="x_participants">
|
||||
<item quantity="zero">لا مُشارِك</item>
|
||||
<item quantity="one">مشارِك واحد</item>
|
||||
<item quantity="two">مشاركَيْنِ</item>
|
||||
<item quantity="few">مشاركين</item>
|
||||
<item quantity="many">مُشارِكًا</item>
|
||||
<item quantity="other">مُشارك</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
||||
@@ -527,4 +527,6 @@
|
||||
<string name="time_minutes_ago_short">%d хв таму</string>
|
||||
<string name="time_hours_ago_short">%d г таму</string>
|
||||
<string name="time_days_ago_short">%d дз таму</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -199,4 +199,6 @@
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -182,4 +182,6 @@
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -293,4 +293,6 @@
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -639,4 +639,6 @@
|
||||
<string name="time_minutes_ago_short">Před %dm</string>
|
||||
<string name="time_hours_ago_short">Před %dh</string>
|
||||
<string name="time_days_ago_short">Před %dd</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -503,4 +503,6 @@
|
||||
<string name="search_open_url">Åbn URL i Mastodon</string>
|
||||
<string name="posts_matching_hashtag">Indlæg med “%s”</string>
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -581,4 +581,6 @@
|
||||
<string name="time_minutes_ago_short">vor %d Minuten</string>
|
||||
<string name="time_hours_ago_short">vor %d Stunden</string>
|
||||
<string name="time_days_ago_short">vor %d Tagen</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -387,6 +387,7 @@
|
||||
<string name="welcome_to_mastodon">Καλώς ήρθες στο Mastodon</string>
|
||||
<string name="welcome_paragraph1">Το Mastodon είναι ένα αποκεντρωμένο κοινωνικό δίκτυο που σημαίνει ότι καμία εταιρεία δεν το ελέγχει. Αποτελείται από πολλούς ανεξάρτητους διακομιστές, όλοι συνδεδεμένοι μαζί.</string>
|
||||
<string name="what_are_servers">Τι είναι οι διακομιστές;</string>
|
||||
<string name="welcome_paragraph2">Κάθε λογαριασμός Mastodon φιλοξενείται σε ένα διακομιστή - ο καθένας με τις δικές του αξίες, κανόνες & διαχειριστές. Ανεξάρτητα από το ποιον μπορεί να επιλέξεις, μπορείς να ακολουθήσεις και να αλληλεπιδράσεις με άτομα από οποιονδήποτε διακομιστή.</string>
|
||||
<string name="opening_link">Άνοιγμα συνδέσμου…</string>
|
||||
<string name="link_not_supported">Αυτός ο σύνδεσμος δεν υποστηρίζεται στην εφαρμογή</string>
|
||||
<string name="log_out_all_accounts">Αποσύνδεση από όλους τους λογαριασμούς</string>
|
||||
@@ -581,4 +582,21 @@
|
||||
<string name="time_minutes_ago_short">%dλ πριν</string>
|
||||
<string name="time_hours_ago_short">%dώ πριν</string>
|
||||
<string name="time_days_ago_short">%dημ πριν</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<string name="translate_post">Μετάφραση από %s</string>
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
<string name="post_translated">Μεταφράστηκε από %1$s χρησιμοποιώντας %2$s</string>
|
||||
<string name="translation_show_original">Εμφάνιση αρχικού</string>
|
||||
<string name="translation_failed">Η μετάφραση απέτυχε. Ίσως ο διαχειριστής δεν έχει ενεργοποιήσει μεταφράσεις σε αυτόν τον διακομιστή ή αυτός ο διακομιστής εκτελεί μια παλαιότερη έκδοση του Mastodon όπου οι μεταφράσεις δεν υποστηρίζονται ακόμα.</string>
|
||||
<string name="settings_privacy">Ιδιωτικότητα και προσιτότητα</string>
|
||||
<string name="settings_discoverable">Παροχή προφίλ και δημοσιεύσεων σε αλγορίθμους ανακάλυψης</string>
|
||||
<string name="settings_indexable">Συμπερίληψη δημόσιων αναρτήσεων στα αποτελέσματα αναζήτησης</string>
|
||||
<plurals name="x_participants">
|
||||
<item quantity="one">%,d συμμετέχων</item>
|
||||
<item quantity="other">%,d συμμετέχοντες</item>
|
||||
</plurals>
|
||||
<plurals name="x_posts_today">
|
||||
<item quantity="one">%,d ανάρτηση σήμερα</item>
|
||||
<item quantity="other">%,d αναρτήσεις σήμερα</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
||||
@@ -573,4 +573,6 @@
|
||||
<string name="time_minutes_ago_short">hace %dm</string>
|
||||
<string name="time_hours_ago_short">hace %dh</string>
|
||||
<string name="time_days_ago_short">hace %dd</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -441,4 +441,6 @@
|
||||
<string name="clear_all">Garbitu dena</string>
|
||||
<string name="search_open_url">Ireki URLa Mastodonen</string>
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -387,6 +387,7 @@
|
||||
<string name="welcome_to_mastodon">به ماستودون خوش آمدید</string>
|
||||
<string name="welcome_paragraph1">ماستودون یک شبکه اجتماعی غیر متمرکز است،به این معنی که هیچ شرکتی آن را کنترل نمی کند. این از بسیاری از کارسازهای مستقل تشکیل شده است که همه به هم متصل هستند.</string>
|
||||
<string name="what_are_servers">کارساز شما کجاست؟</string>
|
||||
<string name="welcome_paragraph2">هر حساب ماستودون بر روی یک سرور میزبانی می شود — هر کدام با مقادیر، قوانین، & مدیران خاص خود. مهم نیست کدام یک را انتخاب می کنید، می توانید افراد را در هر کارسازی دنبال کنید و با آنها تعامل داشته باشید.</string>
|
||||
<string name="opening_link">باز کردن پیوند…</string>
|
||||
<string name="link_not_supported">این پیوند در کاره پشتیبانی نمی شود</string>
|
||||
<string name="log_out_all_accounts">از همه حسابها خارج شوید</string>
|
||||
@@ -581,4 +582,21 @@
|
||||
<string name="time_minutes_ago_short">%dدقيقه پيش</string>
|
||||
<string name="time_hours_ago_short">%dساعت پيش</string>
|
||||
<string name="time_days_ago_short">%dروز پیش</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<string name="translate_post">ترجمه از %s</string>
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
<string name="post_translated">ترجمه از %1$s با %2$s</string>
|
||||
<string name="translation_show_original">نمایش اصلی</string>
|
||||
<string name="translation_failed">ترجمه ناموفق بود. شاید مدیر ترجمهها را در این کارساز فعال نکرده باشد یا این کارساز نسخه قدیمی ماستودون را اجرا می کند که در آن ترجمهها هنوز پشتیبانی نمی شوند.</string>
|
||||
<string name="settings_privacy">محرمانگی و دسترسی</string>
|
||||
<string name="settings_discoverable">مشخص کردن مشخصات و فرستهها در الگوریتمهای اکتشاف</string>
|
||||
<string name="settings_indexable">قرار دادن فرستههای عمومی در نتایج جستجو</string>
|
||||
<plurals name="x_participants">
|
||||
<item quantity="one">%,d شرکت کننده</item>
|
||||
<item quantity="other">%,d شرکتکننده</item>
|
||||
</plurals>
|
||||
<plurals name="x_posts_today">
|
||||
<item quantity="one">%,d فرسته امروز</item>
|
||||
<item quantity="other">%,d فرسته امروز</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
||||
@@ -283,7 +283,7 @@
|
||||
</plurals>
|
||||
<plurals name="x_reblogs">
|
||||
<item quantity="one">%,d tehostus</item>
|
||||
<item quantity="other">%,tehostusta</item>
|
||||
<item quantity="other">%,d tehostusta</item>
|
||||
</plurals>
|
||||
<string name="timestamp_via_app">%1$s sovelluksella %2$s</string>
|
||||
<string name="time_now">nyt</string>
|
||||
@@ -385,7 +385,32 @@
|
||||
<string name="signup_or_login">tai</string>
|
||||
<string name="learn_more">Lue lisää</string>
|
||||
<string name="welcome_to_mastodon">Tervetuloa Mastodoniin</string>
|
||||
<string name="welcome_paragraph1">Mastodon on hajautettu sosiaalinen verkosto, joka tarkoittaa sitä, ettei sitä hallitse mikään yksittäinen yritys. Se koostuu monista itsenäisesti ylläpidetyistä palvelimista, jotka on liitetty yhteen.</string>
|
||||
<string name="what_are_servers">Mitä palvelimet ovat?</string>
|
||||
<string name="welcome_paragraph2">Jokainen Mastodon tili isännöi palvelimella - kullakin on omat arvot, säännöt, & ylläpitäjät. Riippumatta siitä, minkä valitset, voit seurata ja olla vuorovaikutuksessa ihmisten kanssa millä tahansa palvelimella.</string>
|
||||
<string name="opening_link">Avataan linkki…</string>
|
||||
<string name="link_not_supported">Tämä linkki ei ole tuettu sovelluksessa</string>
|
||||
<string name="log_out_all_accounts">Kirjaudu ulos kaikista tileistä</string>
|
||||
<string name="confirm_log_out_all_accounts">Kirjaudu ulos kaikista tileistä?</string>
|
||||
<string name="retry">Yritä uudelleen</string>
|
||||
<string name="post_failed">Viestin lähettäminen epäonnistui</string>
|
||||
<!-- %s is formatted file size ("467 KB image") -->
|
||||
<string name="attachment_description_image">%s kuva</string>
|
||||
<string name="attachment_description_video">%s video</string>
|
||||
<string name="attachment_description_audio">%s ääni</string>
|
||||
<string name="attachment_description_unknown">%s tiedosto</string>
|
||||
<string name="attachment_type_image">Kuva</string>
|
||||
<string name="attachment_type_video">Video</string>
|
||||
<string name="attachment_type_audio">Ääni</string>
|
||||
<string name="attachment_type_gif">GIF</string>
|
||||
<string name="attachment_type_unknown">Tiedosto</string>
|
||||
<string name="attachment_x_percent_uploaded">%d%% ladattu</string>
|
||||
<string name="add_poll_option">Lisää kyselyyn vaihtoehto</string>
|
||||
<string name="poll_length">Kyselyn kesto</string>
|
||||
<string name="poll_style">Tyyli</string>
|
||||
<string name="compose_poll_single_choice">Valitse yksi</string>
|
||||
<string name="compose_poll_multiple_choice">Monivalinta</string>
|
||||
<string name="delete_poll_option">Poista kyselyn vaihtoehto</string>
|
||||
<string name="poll_style_title">Kyselyn tyyli</string>
|
||||
<string name="alt_text">Selitys</string>
|
||||
<string name="help">Ohje</string>
|
||||
@@ -443,8 +468,15 @@
|
||||
<string name="date_at_time">%1$s klo %2$s</string>
|
||||
<string name="today">tänään</string>
|
||||
<string name="yesterday">eilen</string>
|
||||
<string name="tomorrow">huomenna</string>
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<string name="pause_notifications_ends">Päättyy %s</string>
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<string name="pause_notifications_banner">Ilmoitukset jatkuvat %s.</string>
|
||||
<string name="resume_notifications_now">Jatka nyt</string>
|
||||
<string name="open_system_notification_settings">Siirry ilmoitusasetuksiin</string>
|
||||
<string name="about_server">Tietoja</string>
|
||||
<string name="server_rules">Säännöt</string>
|
||||
<string name="server_administrator">Ylläpitäjä</string>
|
||||
<string name="send_email_to_server_admin">Viestin ylläpitäjä</string>
|
||||
<string name="notifications_disabled_in_system">Ota ilmoitukset käyttöön laitteesi asetuksista nähdäksesi päivityksiä mistä tahansa.</string>
|
||||
@@ -550,4 +582,18 @@
|
||||
<string name="time_minutes_ago_short">%dm sitten</string>
|
||||
<string name="time_hours_ago_short">%dh sitten</string>
|
||||
<string name="time_days_ago_short">%dd sitten</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<string name="translate_post">Käännetty kielestä %s</string>
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
<string name="post_translated">Käännetty kielestä %1$s käyttäen %2$s</string>
|
||||
<string name="translation_show_original">Näytä alkuperäinen</string>
|
||||
<string name="translation_failed">Käännös epäonnistui. Ehkä järjestelmänvalvoja ei ole ottanut käyttöön käännöksiä tällä palvelimella tai tällä palvelimella on käynnissä vanhempi versio Mastodonista, jossa käännöksiä ei vielä tueta.</string>
|
||||
<plurals name="x_participants">
|
||||
<item quantity="one">%d osallistuja</item>
|
||||
<item quantity="other">%d osallistujaa</item>
|
||||
</plurals>
|
||||
<plurals name="x_posts_today">
|
||||
<item quantity="one">%,d viesti tänään</item>
|
||||
<item quantity="other">%,d viestiä tänään</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
||||
@@ -211,12 +211,12 @@
|
||||
<item quantity="other">%,d tagasunod</item>
|
||||
</plurals>
|
||||
<plurals name="x_following">
|
||||
<item quantity="one">%, d Sumusunod</item>
|
||||
<item quantity="other">%, d Sumusunod</item>
|
||||
<item quantity="one">%,d Sumusunod</item>
|
||||
<item quantity="other">%,d Sumusunod</item>
|
||||
</plurals>
|
||||
<plurals name="x_favorites">
|
||||
<item quantity="one">%, d Paborito</item>
|
||||
<item quantity="other">%, d paborito</item>
|
||||
<item quantity="one">%,d Paborito</item>
|
||||
<item quantity="other">%,d paborito</item>
|
||||
</plurals>
|
||||
<string name="timestamp_via_app">%1$s sa pamamagitan ng %2$s</string>
|
||||
<string name="time_now">ngayon</string>
|
||||
@@ -284,4 +284,6 @@
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -582,4 +582,18 @@
|
||||
<string name="time_minutes_ago_short">il y a %dm</string>
|
||||
<string name="time_hours_ago_short">Il y a %dh</string>
|
||||
<string name="time_days_ago_short">Il y a %dj</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<string name="translate_post">Traduire depuis %s</string>
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
<string name="post_translated">Traduit depuis %1$s via %2$s</string>
|
||||
<string name="translation_show_original">Afficher l’original</string>
|
||||
<string name="translation_failed">La traduction a échoué. Peut-être que l’administrateur n’a pas activé les traductions sur ce serveur ou que ce serveur utilise une ancienne version de Mastodon où les traductions ne sont pas encore prises en charge.</string>
|
||||
<plurals name="x_participants">
|
||||
<item quantity="one">%,d participant</item>
|
||||
<item quantity="other">%,d participants</item>
|
||||
</plurals>
|
||||
<plurals name="x_posts_today">
|
||||
<item quantity="one">%,d message aujourd’hui</item>
|
||||
<item quantity="other">%,d messages aujourd’hui</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
||||
@@ -20,4 +20,6 @@
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -640,4 +640,6 @@
|
||||
<string name="time_minutes_ago_short">%dm air ais</string>
|
||||
<string name="time_hours_ago_short">%du air ais</string>
|
||||
<string name="time_days_ago_short">%dl air ais</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -4,12 +4,14 @@
|
||||
<string name="next">Seguinte</string>
|
||||
<string name="loading_instance">Obtendo info do servidor…</string>
|
||||
<string name="error">Erro</string>
|
||||
<string name="not_a_mastodon_instance">%s non semella ser un servidor Mastodon.</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="preparing_auth">Preparándose para a autenticación…</string>
|
||||
<string name="finishing_auth">Rematando coa autenticación…</string>
|
||||
<string name="user_boosted">%s promoveu</string>
|
||||
<string name="in_reply_to">Como resposta a %s</string>
|
||||
<string name="notifications">Notificacións</string>
|
||||
<string name="user_followed_you">%s comezou a seguirte</string>
|
||||
<string name="share_toot_title">Compartir</string>
|
||||
<string name="settings">Axustes</string>
|
||||
<string name="publish">Publicar</string>
|
||||
@@ -347,4 +349,6 @@
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -47,4 +47,6 @@
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -227,4 +227,6 @@
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -372,4 +372,6 @@
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -382,4 +382,6 @@
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -20,4 +20,6 @@
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -553,4 +553,6 @@
|
||||
<string name="time_minutes_ago_short">%dm yang lalu</string>
|
||||
<string name="time_hours_ago_short">%dj yang lalu</string>
|
||||
<string name="time_days_ago_short">%dh yang lalu</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -582,4 +582,21 @@
|
||||
<string name="time_minutes_ago_short">fyrir %dm síðan</string>
|
||||
<string name="time_hours_ago_short">fyrir %dh síðan</string>
|
||||
<string name="time_days_ago_short">fyrir %dd síðan</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<string name="translate_post">Þýða úr %s</string>
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
<string name="post_translated">Þýtt úr %1$s með %2$s</string>
|
||||
<string name="translation_show_original">Sýna upprunalegt</string>
|
||||
<string name="translation_failed">Þýðing mistókst. Mögulega hefur kerfisstjórinn ekki virkjað þýðingar á þessum netþjóni, eða að netþjónninn sé keyrður á eldri útgáfu Mastodon þar sem þýðingar séu ekki studdar.</string>
|
||||
<string name="settings_privacy">Gagnaleynd og útbreiðsla</string>
|
||||
<string name="settings_discoverable">Hafa notandasnið og færslur með í reikniritum leitar</string>
|
||||
<string name="settings_indexable">Hafa opinberar færslur með í leitarniðurstöðum</string>
|
||||
<plurals name="x_participants">
|
||||
<item quantity="one">%,d þátttakandi</item>
|
||||
<item quantity="other">%,d þátttakendur</item>
|
||||
</plurals>
|
||||
<plurals name="x_posts_today">
|
||||
<item quantity="one">%,d færsla í dag</item>
|
||||
<item quantity="other">%,d færslur í dag</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
||||
@@ -582,4 +582,19 @@
|
||||
<string name="time_minutes_ago_short">%dmin fa</string>
|
||||
<string name="time_hours_ago_short">%do fa</string>
|
||||
<string name="time_days_ago_short">%dg fa</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<string name="translate_post">Traduci da %s</string>
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
<string name="post_translated">Tradotto da %1$s utilizzando %2$s</string>
|
||||
<string name="translation_show_original">Mostra originale</string>
|
||||
<string name="translation_failed">Traduzione fallita. Forse l\'amministratore non ha abilitato le traduzioni su questo server, o su questo server è in esecuzione una versione precedente di Mastodon in cui le traduzioni non sono ancora supportate.</string>
|
||||
<string name="settings_indexable">Includi i post pubblici nei risultati di ricerca</string>
|
||||
<plurals name="x_participants">
|
||||
<item quantity="one">%,d participante</item>
|
||||
<item quantity="other">%,d partecipanti</item>
|
||||
</plurals>
|
||||
<plurals name="x_posts_today">
|
||||
<item quantity="one">%,d post oggi</item>
|
||||
<item quantity="other">%,d post oggi</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
||||
@@ -88,4 +88,6 @@
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -553,4 +553,19 @@
|
||||
<string name="time_minutes_ago_short">%d 分前</string>
|
||||
<string name="time_hours_ago_short">%d 時間前</string>
|
||||
<string name="time_days_ago_short">%d 日前</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<string name="translate_post">%s から翻訳</string>
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
<string name="post_translated">%2$s による %1$s からの翻訳</string>
|
||||
<string name="translation_show_original">原文を表示</string>
|
||||
<string name="translation_failed">翻訳に失敗しました。このサーバーは翻訳機能を有効にしていないか、翻訳機能のない旧バージョンの Mastodon を実行しているのかもしれません。</string>
|
||||
<string name="settings_privacy">プライバシーとつながりやすさ</string>
|
||||
<string name="settings_discoverable">アカウントを見つけやすくする</string>
|
||||
<string name="settings_indexable">公開投稿を検索できるようにする</string>
|
||||
<plurals name="x_participants">
|
||||
<item quantity="other">参加者 %d 人</item>
|
||||
</plurals>
|
||||
<plurals name="x_posts_today">
|
||||
<item quantity="other">今日の投稿 %,d 件</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
||||
@@ -242,4 +242,6 @@
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -300,4 +300,6 @@
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -180,4 +180,6 @@
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -85,6 +85,10 @@
|
||||
<item quantity="one">%d dag resterend</item>
|
||||
<item quantity="other">%d dagen resterend</item>
|
||||
</plurals>
|
||||
<plurals name="x_votes">
|
||||
<item quantity="one">%,d stem</item>
|
||||
<item quantity="other">%,d stemmen</item>
|
||||
</plurals>
|
||||
<string name="poll_closed">Gesloten</string>
|
||||
<string name="confirm_mute_title">Account negeren</string>
|
||||
<string name="confirm_mute">Het negeren van %s bevestigen</string>
|
||||
@@ -383,6 +387,7 @@
|
||||
<string name="welcome_to_mastodon">Welkom bij Mastodon</string>
|
||||
<string name="welcome_paragraph1">Mastodon is een gedecentraliseerd sociaal netwerk, wat betekent dat geen enkel bedrijf het controleert. Het bestaat uit veel onafhankelijk opererende servers, allemaal met elkaar verbonden.</string>
|
||||
<string name="what_are_servers">Wat zijn servers?</string>
|
||||
<string name="welcome_paragraph2">Elk Mastodon-account wordt gehost op een server – elk met diens eigen waarden, regels en beheerders. Het maakt niet uit welke server je kiest, je kunt mensen op elke server volgen en ermee communiceren.</string>
|
||||
<string name="opening_link">Koppeling aan het openen…</string>
|
||||
<string name="link_not_supported">Deze koppeling wordt niet ondersteund in de app</string>
|
||||
<string name="log_out_all_accounts">Bij alle accounts afmelden</string>
|
||||
@@ -401,6 +406,7 @@
|
||||
<string name="attachment_type_unknown">Bestand</string>
|
||||
<string name="attachment_x_percent_uploaded">%d%% geüpload</string>
|
||||
<string name="add_poll_option">Enquete-optie toevoegen</string>
|
||||
<string name="poll_length">Lengte enquête</string>
|
||||
<string name="poll_style">Stijl</string>
|
||||
<string name="compose_poll_single_choice">Kies een</string>
|
||||
<string name="compose_poll_multiple_choice">Meerkeuze</string>
|
||||
@@ -409,9 +415,38 @@
|
||||
<string name="alt_text">Alternatieve tekst</string>
|
||||
<string name="help">Hulp</string>
|
||||
<string name="what_is_alt_text">Wat is alternatieve tekst?</string>
|
||||
<string name="alt_text_help">Alt tekst biedt afbeeldingsbeschrijvingen voor mensen met een visiuele beperking en verbindingen met een lage bandbreedte of voor mensen die naar extra context zoeken.\n\nJe kunt de toegankelijkheid en het begrip voor iedereen verbeteren door duidelijk, beknopt en objectief te schrijven.\n\n<ul><li>Beschrijf belangrijke elementen</li>\n<li>Vat tekst in afbeeldingen samen</li>\n<li>Gebruik de reguliere zinsopbouw</li>\n<li>Vermijd overbodige informatie</li>\n<li>Focus op trends en belangrijke bevindingen in complexe beelden (zoals diagrammen of kaarten)</li></ul> \n</string>
|
||||
<string name="edit_post">Bericht bewerken</string>
|
||||
<string name="no_verified_link">Geen geverifieerde koppeling</string>
|
||||
<string name="compose_autocomplete_emoji_empty">Emoji doorzoeken</string>
|
||||
<string name="compose_autocomplete_users_empty">Vind wie je zoekt</string>
|
||||
<string name="no_search_results">Deze zoektermen leveren geen resultaat op</string>
|
||||
<string name="language">Taal</string>
|
||||
<string name="language_default">Standaard</string>
|
||||
<string name="language_system">Systeem</string>
|
||||
<string name="language_detecting">Taal detecteren</string>
|
||||
<string name="language_cant_detect">Kan taal niet detecteren</string>
|
||||
<string name="language_detected">Gedetecteerd</string>
|
||||
<string name="media_hidden">Media verborgen</string>
|
||||
<string name="post_hidden">Bericht verborgen</string>
|
||||
<string name="report_title_post">Bericht rapporteren</string>
|
||||
<string name="forward_report_explanation">De account bevindt zich op een andere server. Wil je daar eveneens een geanonimiseerde kopie van dit rapport naar toesturen?</string>
|
||||
<!-- %s is the server domain -->
|
||||
<string name="forward_report_to_server">Doorsturen naar %s</string>
|
||||
<!-- Shown on the "stamp" on the screen that appears after you report a post/user. Please keep the translation short, preferably a single word -->
|
||||
<string name="reported">Gerapporteerd</string>
|
||||
<string name="report_unfollow_explanation">Als je hun berichten niet meer in je home feed wilt zien, moet je deze persoon niet meer volgen.</string>
|
||||
<string name="muted_user">%s gedempt</string>
|
||||
<string name="report_sent_already_blocked">Je hebt deze gebruiker al geblokkeerd, dus je hoeft niets meer te doen terwijl we je rapport beoordelen.</string>
|
||||
<string name="report_personal_already_blocked">Je hebt deze gebruiker al geblokkeerd, dus er is niets anders dat je hoeft te doen.\n\nBedankt voor het helpen om Mastodon een veilige plek voor iedereen te behouden!</string>
|
||||
<string name="blocked_user">%s geblokkeerd</string>
|
||||
<string name="mark_all_notifications_read">Alles als gelezen markeren</string>
|
||||
<string name="settings_display">Weergave</string>
|
||||
<string name="settings_filters">Filters</string>
|
||||
<string name="settings_server_explanation">Overzicht, regels, moderators</string>
|
||||
<!-- %s is the app name (Mastodon, key app_name). I made it a placeholder so everything Just Works™ with forks -->
|
||||
<string name="about_app">Over %s</string>
|
||||
<string name="default_post_language">Standaard taal bericht</string>
|
||||
<string name="settings_alt_text_reminders">Alt-tekst-herinneringen toevoegen</string>
|
||||
<string name="settings_confirm_unfollow">Vraag voor ontvolgen iemand</string>
|
||||
<string name="settings_confirm_boost">Vragen voor boosten</string>
|
||||
@@ -437,6 +472,44 @@
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<string name="pause_notifications_ends">Eindigt %s</string>
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<string name="pause_notifications_banner">Notificaties worden hervat %s.</string>
|
||||
<string name="resume_notifications_now">Nu hervatten</string>
|
||||
<string name="open_system_notification_settings">Ga naar de meldingsinstellingen</string>
|
||||
<string name="about_server">Over</string>
|
||||
<string name="server_rules">Regels</string>
|
||||
<string name="server_administrator">Beheerder</string>
|
||||
<string name="send_email_to_server_admin">Bericht aan beheerder</string>
|
||||
<string name="notifications_disabled_in_system">Schakel meldingen vanuit instellingen van uw apparaat in om van overal updates te zien.</string>
|
||||
<string name="settings_even_more">Nog meer instellingen</string>
|
||||
<string name="settings_show_cws">Inhoudswaarschuwingen tonen</string>
|
||||
<string name="settings_hide_sensitive_media">Als gevoelig gemarkeerde media verbergen</string>
|
||||
<string name="settings_show_interaction_counts">Aantal berichtinteracties</string>
|
||||
<string name="settings_show_emoji_in_names">Aangepaste emoji in weergavenamen</string>
|
||||
<plurals name="in_x_seconds">
|
||||
<item quantity="one">in %d seconde</item>
|
||||
<item quantity="other">in %d seconden</item>
|
||||
</plurals>
|
||||
<plurals name="in_x_minutes">
|
||||
<item quantity="one">in %d minuut</item>
|
||||
<item quantity="other">in %d minuten</item>
|
||||
</plurals>
|
||||
<plurals name="in_x_hours">
|
||||
<item quantity="one">in %d uur</item>
|
||||
<item quantity="other">in %d uur</item>
|
||||
</plurals>
|
||||
<plurals name="x_hours_ago">
|
||||
<item quantity="one">%d uur geleden</item>
|
||||
<item quantity="other">%d uur geleden</item>
|
||||
</plurals>
|
||||
<string name="alt_text_reminder_title">Media zonder alt-tekst</string>
|
||||
<plurals name="alt_text_reminder_x_images">
|
||||
<item quantity="one">%s van je afbeeldingen mist alt-tekst. Toch plaatsen?</item>
|
||||
<item quantity="other">%s van je afbeeldingen missen alt-tekst. Toch plaatsen?</item>
|
||||
</plurals>
|
||||
<plurals name="alt_text_reminder_x_attachments">
|
||||
<item quantity="one">%s van je mediabijlagen mist alt-tekst. Toch plaatsen?</item>
|
||||
<item quantity="other">%s van je mediabijlagen missen alt-tekst. Toch plaatsen?</item>
|
||||
</plurals>
|
||||
<string name="count_one">Een</string>
|
||||
<string name="count_two">Twee</string>
|
||||
<string name="count_three">Drie</string>
|
||||
@@ -444,7 +517,83 @@
|
||||
<string name="alt_text_reminder_post_anyway">Plaatsen</string>
|
||||
<!-- %s is the username -->
|
||||
<string name="unfollow_confirmation">%s ontvolgen?</string>
|
||||
<string name="filter_active">Actief</string>
|
||||
<string name="filter_inactive">Inactief</string>
|
||||
<string name="settings_add_filter">Filter toevoegen</string>
|
||||
<string name="settings_edit_filter">Filter bewerken</string>
|
||||
<string name="settings_filter_duration">Duur</string>
|
||||
<string name="settings_filter_muted_words">Gedempte woorden</string>
|
||||
<string name="settings_filter_context">Gedempt van</string>
|
||||
<string name="settings_filter_show_cw">Toon met inhoudswaarschuwing</string>
|
||||
<string name="settings_filter_show_cw_explanation">Berichten die met dit filter overeenkomen, maar achter een inhoudswaarschuwing zitten toch tonen</string>
|
||||
<string name="settings_delete_filter">Filter verwijderen</string>
|
||||
<string name="filter_duration_forever">Voor altijd</string>
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<string name="settings_filter_ends">Eindigt %s</string>
|
||||
<plurals name="settings_x_muted_words">
|
||||
<item quantity="one">%d gedempt woord of zin</item>
|
||||
<item quantity="other">%d gedempte woorden of zinnen</item>
|
||||
</plurals>
|
||||
<string name="selection_2_options">%1$s en %2$s</string>
|
||||
<string name="selection_3_options">%1$s, %2$s en %3$s</string>
|
||||
<string name="selection_4_or_more">%1$s, %2$s en %3$d meer</string>
|
||||
<string name="filter_context_home_lists">Startpagina & lijsten</string>
|
||||
<string name="filter_context_notifications">Meldingen</string>
|
||||
<string name="filter_context_public_timelines">Openbare tijdlijnen</string>
|
||||
<string name="filter_context_threads_replies">Threads & antwoorden</string>
|
||||
<string name="filter_context_profiles">Profielen</string>
|
||||
<string name="settings_filter_title">Titel</string>
|
||||
<string name="settings_delete_filter_title">Filter ‘%s’ verwijderen?</string>
|
||||
<string name="settings_delete_filter_confirmation">Dit filter zal op al uw apparaten uit uw account worden verwijderd.</string>
|
||||
<string name="add_muted_word">Gedempte woord toevoegen</string>
|
||||
<string name="edit_muted_word">Gedempte woord bewerken</string>
|
||||
<string name="add">Toevoegen</string>
|
||||
<string name="filter_word_or_phrase">Woord of zin</string>
|
||||
<string name="filter_add_word_help">Woorden zijn niet hoofdlettergevoelig en komen alleen overeen met volledige woorden.\n\nAls je op de term ‘Apple’ filtert, verbergt het berichten die ‘apple’ of ‘aPpLe’ bevatten, maar niet ‘ananas’.</string>
|
||||
<string name="settings_delete_filter_word">‘%s’ verwijderen?</string>
|
||||
<string name="enter_selection_mode">Selecteren</string>
|
||||
<string name="select_all">Alles selecteren</string>
|
||||
<string name="settings_filter_duration_title">Filter tijdsduur</string>
|
||||
<string name="filter_duration_custom">Aangepast</string>
|
||||
<plurals name="settings_delete_x_filter_words">
|
||||
<item quantity="one">%d woord verwijderen?</item>
|
||||
<item quantity="other">%d woorden verwijderen?</item>
|
||||
</plurals>
|
||||
<plurals name="x_items_selected">
|
||||
<item quantity="one">%d geselecteerd</item>
|
||||
<item quantity="other">%d geselecteerd</item>
|
||||
</plurals>
|
||||
<string name="required_form_field_blank">Mag niet leeg zijn</string>
|
||||
<string name="filter_word_already_in_list">Al in de lijst</string>
|
||||
<string name="app_update_ready">App-update voltooid</string>
|
||||
<string name="app_update_version">Versie %s</string>
|
||||
<string name="downloading_update">Downloaden (%d%%)</string>
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<string name="post_matches_filter_x">Komt overeen met filter ‘%s’</string>
|
||||
<string name="search_mastodon">Mastodon doorzoeken</string>
|
||||
<string name="clear_all">Alles wissen</string>
|
||||
<string name="search_open_url">URL in Mastodon openen</string>
|
||||
<string name="posts_matching_hashtag">Berichten met ‘%s’</string>
|
||||
<string name="search_go_to_account">Ga naar %s</string>
|
||||
<string name="posts_matching_string">Berichten met ‘%s’</string>
|
||||
<string name="accounts_matching_string">Personen met ‘%s’</string>
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<string name="time_seconds_ago_short">%ds geleden</string>
|
||||
<string name="time_minutes_ago_short">%dm geleden</string>
|
||||
<string name="time_hours_ago_short">%du geleden</string>
|
||||
<string name="time_days_ago_short">%d dagen geleden</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<string name="translate_post">Vanuit het %s vertalen</string>
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
<string name="post_translated">Vertaald vanuit het %1$s door %2$s</string>
|
||||
<string name="translation_show_original">Origineel bekijken</string>
|
||||
<string name="translation_failed">Vertaling mislukt. Mogelijk heeft de serverbeheerder vertalingen niet ingeschakeld op deze server, of draait deze server een oude versie van Mastodon waar vertalingen nog niet worden ondersteund.</string>
|
||||
<plurals name="x_participants">
|
||||
<item quantity="one">%d deelnemer</item>
|
||||
<item quantity="other">%d deelnemers</item>
|
||||
</plurals>
|
||||
<plurals name="x_posts_today">
|
||||
<item quantity="one">%,d bericht vandaag</item>
|
||||
<item quantity="other">%,d berichten vandaag</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
||||
@@ -581,4 +581,6 @@
|
||||
<string name="time_minutes_ago_short">%dm siden</string>
|
||||
<string name="time_hours_ago_short">%dt siden</string>
|
||||
<string name="time_days_ago_short">%dd siden</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -79,4 +79,6 @@
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -457,4 +457,6 @@
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -571,4 +571,6 @@
|
||||
<string name="time_minutes_ago_short">%dm atrás</string>
|
||||
<string name="time_hours_ago_short">%dh atrás</string>
|
||||
<string name="time_days_ago_short">%dd atrás</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -234,4 +234,6 @@
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -48,4 +48,6 @@
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -640,4 +640,25 @@
|
||||
<string name="time_minutes_ago_short">%d мин. назад</string>
|
||||
<string name="time_hours_ago_short">%d ч. назад</string>
|
||||
<string name="time_days_ago_short">%d д. назад</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<string name="translate_post">Перевести %s</string>
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
<string name="post_translated">%1$s переведён с помощью %2$s</string>
|
||||
<string name="translation_show_original">Показать оригинал</string>
|
||||
<string name="translation_failed">Перевод не удался. Возможно, администратор не включил переводы на этом сервере или на этом сервере установлена более старая версия Mastodon, где переводы еще не поддерживаются.</string>
|
||||
<string name="settings_privacy">Приватность и доступ</string>
|
||||
<string name="settings_discoverable">Показывать профиль и посты в алгоритмах рекомендаций</string>
|
||||
<string name="settings_indexable">Включить публичные посты в результаты поиска</string>
|
||||
<plurals name="x_participants">
|
||||
<item quantity="one">%,d участник</item>
|
||||
<item quantity="few">%,d участника</item>
|
||||
<item quantity="many">%,d участников</item>
|
||||
<item quantity="other">%,d участников</item>
|
||||
</plurals>
|
||||
<plurals name="x_posts_today">
|
||||
<item quantity="one">%,d пост сегодня</item>
|
||||
<item quantity="few">%,d поста сегодня</item>
|
||||
<item quantity="many">%,d постов сегодня</item>
|
||||
<item quantity="other">%,d постов сегодня</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
||||
@@ -75,4 +75,6 @@
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -274,6 +274,8 @@
|
||||
<string name="trending_posts_info_banner">To so objave, ki plenijo pozornost po Mastodonu.</string>
|
||||
<string name="trending_links_info_banner">To so novice, o katerih se govori na Mastodonu.</string>
|
||||
<!-- %s is the server domain -->
|
||||
<string name="local_timeline_info_banner">To so vse objave vseh uporabnikov na vašem strežniku (%s).</string>
|
||||
<string name="recommended_accounts_info_banner">Glede na to, komu sledite, vam bodo ti računi všeč.</string>
|
||||
<string name="see_new_posts">Pokaži nove objave</string>
|
||||
<string name="load_missing_posts">Naloži manjkajoče objave</string>
|
||||
<string name="follow_back">Sledijo nazaj</string>
|
||||
@@ -455,8 +457,11 @@
|
||||
<!-- %s is the app name (Mastodon, key app_name). I made it a placeholder so everything Just Works™ with forks -->
|
||||
<string name="about_app">O programu %s</string>
|
||||
<string name="default_post_language">Privzeti jezik objave</string>
|
||||
<string name="settings_confirm_delete_post">Vprašaj pred brisanjem objav</string>
|
||||
<string name="pause_all_notifications">Premor za vse</string>
|
||||
<string name="pause_notifications_off">Izklopljeno</string>
|
||||
<string name="notifications_policy_anyone">Kdor koli</string>
|
||||
<string name="notifications_policy_followed">Ljudje, ki vam sledijo</string>
|
||||
<string name="notifications_policy_follower">Ljudje, ki jim sledite</string>
|
||||
<string name="notifications_policy_no_one">Nihče</string>
|
||||
<string name="notification_type_mentions_and_replies">Omembe in odgovori</string>
|
||||
@@ -504,6 +509,7 @@
|
||||
<string name="filter_context_profiles">Profili</string>
|
||||
<string name="settings_filter_title">Naslov</string>
|
||||
<string name="settings_delete_filter_title">Ali želite izbrisati filter »%s«?</string>
|
||||
<string name="settings_delete_filter_confirmation">Ta filter bo izbrisan iz vašega računa na vseh vaših napravah.</string>
|
||||
<string name="add_muted_word">Dodaj utišano besedo</string>
|
||||
<string name="edit_muted_word">Uredi utišano besedo</string>
|
||||
<string name="add">Dodaj</string>
|
||||
@@ -532,4 +538,13 @@
|
||||
<string name="time_minutes_ago_short">pred %d meseci</string>
|
||||
<string name="time_hours_ago_short">pred %dh urami</string>
|
||||
<string name="time_days_ago_short">pred %d dnemi</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<string name="translate_post">Prevedi iz jezika: %s</string>
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
<string name="post_translated">Prevedeno iz %1$s s pomočjo %2$s</string>
|
||||
<string name="translation_show_original">Pokaži izvirnik</string>
|
||||
<string name="translation_failed">Prevod je spodletel. Morda skrbnik ni omogočil prevajanja na tem strežniku ali pa strežnik teče na starejši različici Masotodona, na kateri prevajanje še ni podprto.</string>
|
||||
<string name="settings_privacy">Zasebnost in dosegljivost</string>
|
||||
<string name="settings_discoverable">Izpostavljaj profile in objave v algoritmih odkrivanja</string>
|
||||
<string name="settings_indexable">Med zadetke iskanja vključi javne objave</string>
|
||||
</resources>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
<string name="in_reply_to">Som svar på %s</string>
|
||||
<string name="notifications">Notiser</string>
|
||||
<string name="user_followed_you">%s följde dig</string>
|
||||
<string name="user_favorited">%s favoritmarkerade ditt inlägg</string>
|
||||
<string name="share_toot_title">Dela</string>
|
||||
<string name="settings">Inställningar</string>
|
||||
<string name="publish">Publicera</string>
|
||||
@@ -229,6 +230,7 @@
|
||||
<string name="file_saved">Filen sparad</string>
|
||||
<string name="downloading">Laddar ner…</string>
|
||||
<!-- %s is the server domain -->
|
||||
<string name="recommended_accounts_info_banner">Du kanske gillar dessa konton baserat på andra konton du följer.</string>
|
||||
<string name="see_new_posts">Se nya inlägg</string>
|
||||
<string name="load_missing_posts">Ladda saknade inlägg</string>
|
||||
<string name="follow_back">Följ tillbaka</string>
|
||||
@@ -353,6 +355,8 @@
|
||||
<string name="attachment_description_video">%s video</string>
|
||||
<string name="attachment_description_audio">%s ljud</string>
|
||||
<string name="attachment_description_unknown">%s fil</string>
|
||||
<string name="attachment_type_image">Bild</string>
|
||||
<string name="attachment_type_video">Video</string>
|
||||
<string name="attachment_type_audio">Ljud</string>
|
||||
<string name="attachment_type_gif">GIF</string>
|
||||
<string name="attachment_type_unknown">Fil</string>
|
||||
@@ -383,6 +387,7 @@
|
||||
<string name="about_server">Om</string>
|
||||
<string name="server_rules">Regler</string>
|
||||
<string name="server_administrator">Administratör</string>
|
||||
<string name="settings_show_emoji_in_names">Anpassad emoji i visningsnamn</string>
|
||||
<plurals name="in_x_hours">
|
||||
<item quantity="one">om %d timme</item>
|
||||
<item quantity="other">om %d timmar</item>
|
||||
@@ -391,6 +396,9 @@
|
||||
<item quantity="one">%d timme sedan</item>
|
||||
<item quantity="other">%d timmar sedan</item>
|
||||
</plurals>
|
||||
<string name="count_two">Två</string>
|
||||
<string name="count_three">Tre</string>
|
||||
<string name="count_four">Fyra</string>
|
||||
<!-- %s is the username -->
|
||||
<string name="filter_active">Aktiv</string>
|
||||
<string name="filter_inactive">Inaktiv</string>
|
||||
@@ -401,12 +409,19 @@
|
||||
<string name="selection_2_options">%1$s och %2$s</string>
|
||||
<string name="selection_3_options">%1$s, %2$s och %3$s</string>
|
||||
<string name="filter_context_profiles">Profiler</string>
|
||||
<string name="settings_delete_filter_confirmation">Detta filter kommer raderas från ditt konto på alla dina enheter.</string>
|
||||
<string name="add">Lägg till</string>
|
||||
<string name="filter_word_or_phrase">Ord eller fras</string>
|
||||
<string name="enter_selection_mode">Välj</string>
|
||||
<string name="select_all">Välj alla</string>
|
||||
<plurals name="settings_delete_x_filter_words">
|
||||
<item quantity="one">Radera %d ord?</item>
|
||||
<item quantity="other">Radera %d ord?</item>
|
||||
</plurals>
|
||||
<string name="app_update_version">Version %s</string>
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<string name="post_matches_filter_x">Matchar filter \"%s\"</string>
|
||||
<string name="search_mastodon">Sök i Mastodon</string>
|
||||
<string name="clear_all">Rensa alla</string>
|
||||
<string name="search_open_url">Öppna URL i Mastodon</string>
|
||||
<string name="posts_matching_hashtag">Inlägg med \"%s\"</string>
|
||||
@@ -416,4 +431,7 @@
|
||||
<string name="time_minutes_ago_short">%dm sedan</string>
|
||||
<string name="time_hours_ago_short">%dt sedan</string>
|
||||
<string name="time_days_ago_short">%dd sedan</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<string name="translate_post">Översätt från %s</string>
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -553,4 +553,19 @@
|
||||
<string name="time_minutes_ago_short">%d นาทีที่แล้ว</string>
|
||||
<string name="time_hours_ago_short">%d ชั่วโมงที่แล้ว</string>
|
||||
<string name="time_days_ago_short">%d วันที่แล้ว</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<string name="translate_post">แปลจาก %s</string>
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
<string name="post_translated">แปลจาก %1$s โดยใช้ %2$s</string>
|
||||
<string name="translation_show_original">แสดงดั้งเดิม</string>
|
||||
<string name="translation_failed">การแปลล้มเหลว บางทีผู้ดูแลอาจไม่ได้เปิดใช้งานการแปลในเซิร์ฟเวอร์นี้หรือเซิร์ฟเวอร์นี้กำลังใช้ Mastodon รุ่นเก่ากว่าที่ยังไม่รองรับการแปล</string>
|
||||
<string name="settings_privacy">ความเป็นส่วนตัวและการเข้าถึง</string>
|
||||
<string name="settings_discoverable">แสดงโปรไฟล์และโพสต์ในอัลกอริทึมการค้นพบ</string>
|
||||
<string name="settings_indexable">รวมโพสต์สาธารณะในผลลัพธ์การค้นหา</string>
|
||||
<plurals name="x_participants">
|
||||
<item quantity="other">%,d ผู้มีส่วนร่วม</item>
|
||||
</plurals>
|
||||
<plurals name="x_posts_today">
|
||||
<item quantity="other">%,d โพสต์วันนี้</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
||||
@@ -387,6 +387,7 @@
|
||||
<string name="welcome_to_mastodon">Mastodon\'a hoş geldiniz</string>
|
||||
<string name="welcome_paragraph1">Mastodon merkezi olmayan bir sosyal ağdır, yani onu tek bir şirket kontrol etmiyor. Hepsi birbirine bağlı, bağımsız olarak çalışan birçok sunucudan oluşur.</string>
|
||||
<string name="what_are_servers">Sunucular nedir?</string>
|
||||
<string name="welcome_paragraph2">Her Mastodon hesabı bir sunucuda barındırılır - her birinin kendi değerleri, kuralları ve yöneticileri vardır. Hangisini seçerseniz seçin, herhangi bir sunucudaki insanları takip edebilir ve onlarla etkileşime geçebilirsiniz.</string>
|
||||
<string name="opening_link">Bağlantı açılıyor…</string>
|
||||
<string name="link_not_supported">Bu bağlantı uygulamada desteklenmiyor</string>
|
||||
<string name="log_out_all_accounts">Tüm hesaplardan çıkış yap</string>
|
||||
@@ -581,4 +582,21 @@
|
||||
<string name="time_minutes_ago_short">%ddk önce</string>
|
||||
<string name="time_hours_ago_short">%dsa önce</string>
|
||||
<string name="time_days_ago_short">%dg önce</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<string name="translate_post">%s dilinden çevrildi</string>
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
<string name="post_translated">%2$s kullanılarak %1$s dilinden çevrildi</string>
|
||||
<string name="translation_show_original">Özgün içeriği göster</string>
|
||||
<string name="translation_failed">Çeviri başarısız oldu. Yönetici bu sunucuda çevirileri etkinleştirmemiş olabilir veya bu sunucu çevirilerin henüz desteklenmediği eski bir Mastodon sürümünü çalıştırıyor olabilir.</string>
|
||||
<string name="settings_privacy">Gizlilik ve erişim</string>
|
||||
<string name="settings_discoverable">Profil ve gönderileri keşif algoritmalarında kullan</string>
|
||||
<string name="settings_indexable">Herkese açık gönderileri arama sonuçlarına ekle</string>
|
||||
<plurals name="x_participants">
|
||||
<item quantity="one">%d katılımcılar</item>
|
||||
<item quantity="other">%d katılımcılar</item>
|
||||
</plurals>
|
||||
<plurals name="x_posts_today">
|
||||
<item quantity="one">%,d bunu gönder</item>
|
||||
<item quantity="other">%,d bunları gönder</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
||||
@@ -640,4 +640,25 @@
|
||||
<string name="time_minutes_ago_short">%dхв. тому</string>
|
||||
<string name="time_hours_ago_short">%dгод. тому</string>
|
||||
<string name="time_days_ago_short">%dд. тому</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<string name="translate_post">Перекласти з %s</string>
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
<string name="post_translated">Перекладено з %1$s за допомогою %2$s</string>
|
||||
<string name="translation_show_original">Показати оригінал</string>
|
||||
<string name="translation_failed">Не вдалося виконати переклад. Можливо, адміністратор не активував переклади на цьому сервері або цей сервер використовує стару версію Mastodon, де переклади ще не підтримуються.</string>
|
||||
<string name="settings_privacy">Приватність і досяжність</string>
|
||||
<string name="settings_discoverable">Враховувати профіль та дописи в алгоритмах пошуку</string>
|
||||
<string name="settings_indexable">Включити загальнодоступні дописи в результати пошуку</string>
|
||||
<plurals name="x_participants">
|
||||
<item quantity="one">%,d учасник</item>
|
||||
<item quantity="few">%,d учасники</item>
|
||||
<item quantity="many">%,d учасників</item>
|
||||
<item quantity="other">%,d учасника</item>
|
||||
</plurals>
|
||||
<plurals name="x_posts_today">
|
||||
<item quantity="one">%,d допис сьогодні</item>
|
||||
<item quantity="few">%,d дописи сьогодні</item>
|
||||
<item quantity="many">%,d дописів сьогодні</item>
|
||||
<item quantity="other">%,d дописа сьогодні</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
||||
@@ -20,4 +20,6 @@
|
||||
<!-- %s is the timestamp ("tomorrow at 12:34") -->
|
||||
<!-- Shown like a content warning, %s is the name of the filter -->
|
||||
<!-- Shown in the post header. Please keep it short -->
|
||||
<!-- %s is the name of the post language -->
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
</resources>
|
||||
|
||||
@@ -266,7 +266,7 @@
|
||||
<item quantity="other">%,d lượt thích</item>
|
||||
</plurals>
|
||||
<plurals name="x_reblogs">
|
||||
<item quantity="other">%,đăng lại</item>
|
||||
<item quantity="other">%,d đăng lại</item>
|
||||
</plurals>
|
||||
<string name="timestamp_via_app">%1$s qua %2$s</string>
|
||||
<string name="time_now">vừa xong</string>
|
||||
@@ -553,4 +553,16 @@
|
||||
<string name="time_minutes_ago_short">%dp</string>
|
||||
<string name="time_hours_ago_short">%dh</string>
|
||||
<string name="time_days_ago_short">%d ngày</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<string name="translate_post">Dịch từ %s</string>
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
<string name="post_translated">Dịch từ %1$s bằng %2$s</string>
|
||||
<string name="translation_show_original">Bản gốc</string>
|
||||
<string name="translation_failed">Dịch không thành công. Có thể quản trị viên chưa bật dịch trên máy chủ này hoặc máy chủ này đang chạy phiên bản cũ hơn của Mastodon chưa hỗ trợ dịch.</string>
|
||||
<plurals name="x_participants">
|
||||
<item quantity="other">%,d người thảo luận</item>
|
||||
</plurals>
|
||||
<plurals name="x_posts_today">
|
||||
<item quantity="other">%,d tút hôm nay</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
||||
@@ -552,4 +552,13 @@
|
||||
<string name="time_minutes_ago_short">%d 分钟前</string>
|
||||
<string name="time_hours_ago_short">%d 小时前</string>
|
||||
<string name="time_days_ago_short">%d 天前</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<string name="translate_post">从 %s 翻译</string>
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
<string name="post_translated">从 %1$s 翻译成 %2$s</string>
|
||||
<string name="translation_show_original">显示原文</string>
|
||||
<string name="translation_failed">翻译失败。此服务器运行的 Mastodon 版本不支持翻译功能,或管理员未将翻译功能开启。</string>
|
||||
<string name="settings_privacy">隐私与可达性</string>
|
||||
<string name="settings_discoverable">在发现算法中展示您的个人资料和嘟文</string>
|
||||
<string name="settings_indexable">将您的公开嘟文纳入搜索范围</string>
|
||||
</resources>
|
||||
|
||||
@@ -553,4 +553,19 @@
|
||||
<string name="time_minutes_ago_short">%d 分鐘前</string>
|
||||
<string name="time_hours_ago_short">%d 小時前</string>
|
||||
<string name="time_days_ago_short">%d 天前</string>
|
||||
<!-- %s is the name of the post language -->
|
||||
<string name="translate_post">翻譯自 %s</string>
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
<string name="post_translated">透過 %2$s 翻譯 %1$s</string>
|
||||
<string name="translation_show_original">顯示原文</string>
|
||||
<string name="translation_failed">翻譯失敗。也許管理員未於此伺服器啟用翻譯功能,或此伺服器為未支援翻譯功能之舊版本 Mastodon。</string>
|
||||
<string name="settings_privacy">隱私權及觸及</string>
|
||||
<string name="settings_discoverable">於探索演算法中推薦個人檔案及嘟文</string>
|
||||
<string name="settings_indexable">允許公開嘟文顯示於搜尋結果中</string>
|
||||
<plurals name="x_participants">
|
||||
<item quantity="other">%,d 位參與者</item>
|
||||
</plurals>
|
||||
<plurals name="x_posts_today">
|
||||
<item quantity="other">本日共 %,d 則嘟文</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
||||
@@ -589,4 +589,23 @@
|
||||
<string name="time_minutes_ago_short">%dm ago</string>
|
||||
<string name="time_hours_ago_short">%dh ago</string>
|
||||
<string name="time_days_ago_short">%dd ago</string>
|
||||
|
||||
<!-- %s is the name of the post language -->
|
||||
<string name="translate_post">Translate from %s</string>
|
||||
<!-- %1$s is the language, %2$s is the name of the translation service -->
|
||||
<string name="post_translated">Translated from %1$s using %2$s</string>
|
||||
<string name="translation_show_original">Show original</string>
|
||||
<string name="translation_failed">Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.</string>
|
||||
<string name="settings_privacy">Privacy and reach</string>
|
||||
<string name="settings_discoverable">Feature profile and posts in discovery algorithms</string>
|
||||
<string name="settings_indexable">Include public posts in search results</string>
|
||||
|
||||
<plurals name="x_participants">
|
||||
<item quantity="one">%,d participant</item>
|
||||
<item quantity="other">%,d participants</item>
|
||||
</plurals>
|
||||
<plurals name="x_posts_today">
|
||||
<item quantity="one">%,d post today</item>
|
||||
<item quantity="other">%,d posts today</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user