Compare commits

..

66 Commits

Author SHA1 Message Date
sk
32081b71f5 throw exception if no instance for session 2023-05-29 13:31:42 +02:00
sk
7849c34d1f fix account list alignment 2023-05-29 13:25:14 +02:00
sk
24977ec613 bump version 2023-05-29 13:03:18 +02:00
sk
786bbab0d5 Merge remote-tracking branch 'weblate/main' 2023-05-29 13:01:36 +02:00
sk
1facb07c28 Merge remote-tracking branch 'upstream/l10n_master' 2023-05-29 13:01:24 +02:00
sk
bba5aba22d settings icons not important for accessibility 2023-05-29 12:56:36 +02:00
sk
d7b85d6eba move invalid strings 2023-05-29 12:47:38 +02:00
sk
6832bfb95c don't display blocked_by relationship
closes sk22#526
2023-05-29 12:34:53 +02:00
sk
4c379b67a3 only auto-open search on pleroma instances 2023-05-29 03:33:31 +02:00
sk
3a2ae1ce71 clean up preferences when removing account 2023-05-29 02:40:15 +02:00
sk
c80afaf9c0 avoid sessions without instance info 2023-05-29 02:40:02 +02:00
sk
31d22bac47 remove unused method 2023-05-29 02:38:52 +02:00
Jacoco
b5f6687925 More Akkoma improvements (#524)
* Only open account if domain matches
Akkoma will seemingly show results that don't match well. This checks if the domain matches before continuing

* Add "RE:" for quotes where it's missing

* Fix no hashtag history in search

* Skip not implemented discovery and select search on Pleroma

* Set proper max account fields for Pleroma

* Use Pleroma's non-standard poll limits

* Mark notifications as read properly on Pleroma

* Akkoma bubble timeline

* Respect Reply Visibility preference on all timelines

* vertically center if hashtag has no history

* only open account search result if uri equals

* add getInstance and isPleroma methods

* change timelines api, support compatibility checks

---------

Co-authored-by: sk <sk22@mailbox.org>
2023-05-29 02:37:46 +02:00
taniamarquessilva
b3f25af923 Translated using Weblate (Portuguese (Portugal))
Currently translated at 100.0% (286 of 286 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/pt_PT/
2023-05-28 20:19:30 +00:00
taniamarquessilva
78c141e946 Translated using Weblate (Portuguese)
Currently translated at 14.6% (42 of 286 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/pt/
2023-05-28 20:19:30 +00:00
taniamarquessilva
83d36ce736 Translated using Weblate (Portuguese)
Currently translated at 52.9% (9 of 17 strings)

Translation: Megalodon/metadata
Translate-URL: https://translate.codeberg.org/projects/megalodon/metadata/pt/
2023-05-28 20:19:30 +00:00
taniamarquessilva
b928357ff1 Translated using Weblate (Portuguese (Portugal))
Currently translated at 100.0% (286 of 286 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/pt_PT/
2023-05-28 20:19:30 +00:00
ihor_ck
c074bc57bc Translated using Weblate (Ukrainian)
Currently translated at 100.0% (286 of 286 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/uk/
2023-05-28 20:19:30 +00:00
Linerly
0e80c88b7d Translated using Weblate (Indonesian)
Currently translated at 100.0% (286 of 286 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/id/
2023-05-28 20:19:30 +00:00
Choukajohn
5ffa5b01fc Translated using Weblate (French)
Currently translated at 100.0% (286 of 286 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/fr/
2023-05-28 20:19:30 +00:00
gallegonovato
61d9929485 Translated using Weblate (Spanish)
Currently translated at 100.0% (286 of 286 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/es/
2023-05-28 20:19:30 +00:00
sk
231f19d113 ugly workaround for sk22#520
it's really, really ugly :(
2023-05-28 22:14:03 +02:00
sk
bb41f62db5 Merge remote-tracking branch 'upstream/master' 2023-05-28 19:55:27 +02:00
Gregory K
47edc3180b Merge pull request #586 from sk22/fix/hashtags-crash-akkoma
Fix crash when searching for Hashtags on Akkoma servers
2023-05-28 20:55:04 +03:00
sk
9939d99c4b Merge branch 'fix/hashtags-crash-akkoma' 2023-05-28 19:54:39 +02:00
sk
8053e8bb05 fix hashtag search crash on akkoma servers
closes mastodon#468
closes sk22#523
2023-05-28 19:51:29 +02:00
sk
b7e9380bc4 enable unspecified as default formatting option
closes sk22#521
2023-05-28 14:55:53 +02:00
Jacoco
83600087e1 Fix images being stretched on Pleroma (#522)
Closes sk22#488

* Update image bounds after load when metadata is null

* Fix broken image layout in some scenarios

* Transition when image dimensions update

* Replace blurhash with accent color on Pleroma

* fall back to solid color regardless of server

* use fragment's context instead of passing it down

---------

Co-authored-by: sk <sk22@mailbox.org>
2023-05-28 14:44:23 +02:00
Eugen Rochko
fe84dc4823 New translations strings.xml (Chinese Simplified) 2023-05-27 16:39:55 +02:00
sk
c38eb545b1 use matched filter for determining warning title
fixes a bug where, when multiple filters apply, the
WarningFilteredStatusDisplayItem would not check if the warning applies to the
current context. now, matched filter is determined through the predicate
(though not exactly what a predicate is supposed to do, i guess) and passed
down to the WarningFilteredStatusDisplayItem. cc @LucasGGamerM
2023-05-27 13:09:36 +02:00
sk
1fc2f81dab fix creating posts on other people's account timelines
closes sk22#508
2023-05-27 01:50:10 +02:00
LucasGGamerM
69ddc95c2c fix crash when notification markers are null
This would happen when an account had 0 notifications and received one.
After which, the user would tap on the notification icon on the tab bar
and the app would crash.
2023-05-27 01:40:05 +02:00
sk
a6ac68499c use url as fallback for remote url 2023-05-27 01:37:10 +02:00
sk
c10d7cfee4 use remote url; file name as fallback for alt text 2023-05-27 01:32:49 +02:00
sk
f933bdbc53 button with ripple for files and instance picker 2023-05-27 01:13:32 +02:00
LucasGGamerM
274bca84d9 Add display item for unknown/file attachments
Co-authored-by: LucasGGamerM <lucassggabriel@gmail.com>
2023-05-27 01:11:26 +02:00
sk
6abfe6ddd7 add unit tests for status filter predicate 2023-05-26 17:02:39 +02:00
sk
ab7489a049 bump version 2023-05-26 02:37:32 +02:00
sk
a6fd6ae135 add javadoc 2023-05-26 02:37:25 +02:00
Espasant3
b30d4a025f Translated using Weblate (Galician)
Currently translated at 99.6% (274 of 275 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/gl/
2023-05-26 00:16:40 +00:00
Daudix_UFO
5b747bfc74 Translated using Weblate (Russian)
Currently translated at 100.0% (275 of 275 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/ru/
2023-05-26 00:16:40 +00:00
gallegonovato
a410d19114 Translated using Weblate (Spanish)
Currently translated at 100.0% (275 of 275 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/es/
2023-05-26 00:16:39 +00:00
gicorada
a8589cc5b0 Translated using Weblate (Italian)
Currently translated at 100.0% (17 of 17 strings)

Translation: Megalodon/metadata
Translate-URL: https://translate.codeberg.org/projects/megalodon/metadata/it/
2023-05-26 00:16:39 +00:00
Eryk Michalak
b057c9f7a8 Translated using Weblate (Polish)
Currently translated at 100.0% (17 of 17 strings)

Translation: Megalodon/metadata
Translate-URL: https://translate.codeberg.org/projects/megalodon/metadata/pl/
2023-05-26 00:16:39 +00:00
ihor_ck
96e4a4933c Translated using Weblate (Ukrainian)
Currently translated at 100.0% (275 of 275 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/uk/
2023-05-26 00:16:39 +00:00
Eryk Michalak
630064500d Translated using Weblate (Polish)
Currently translated at 100.0% (275 of 275 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/pl/
2023-05-26 00:16:39 +00:00
gicorada
9543294996 Translated using Weblate (Italian)
Currently translated at 100.0% (275 of 275 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/it/
2023-05-26 00:16:39 +00:00
Linerly
56e9cc3406 Translated using Weblate (Indonesian)
Currently translated at 100.0% (275 of 275 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/id/
2023-05-26 00:16:39 +00:00
Choukajohn
be569cbe72 Translated using Weblate (French)
Currently translated at 100.0% (275 of 275 strings)

Translation: Megalodon/values
Translate-URL: https://translate.codeberg.org/projects/megalodon/values/fr/
2023-05-26 00:16:39 +00:00
Eugen Rochko
2e1795dc6f New translations strings.xml (Russian) 2023-05-20 13:04:15 +02:00
Eugen Rochko
cd1be782fa New translations strings.xml (Armenian) 2023-05-16 18:44:56 +02:00
Eugen Rochko
67059f3d71 New translations strings.xml (Armenian) 2023-05-16 17:30:41 +02:00
Eugen Rochko
15f4d3326b New translations strings.xml (Russian) 2023-05-15 08:47:41 +02:00
Eugen Rochko
e65404a466 New translations strings.xml (Dutch) 2023-05-13 20:26:36 +02:00
Eugen Rochko
3d47d1b4db New translations full_description.txt (Dutch) 2023-05-13 19:05:00 +02:00
Eugen Rochko
d1749ab610 New translations strings.xml (Dutch) 2023-05-13 19:04:59 +02:00
Eugen Rochko
806c264686 New translations strings.xml (Vietnamese) 2023-05-13 17:46:17 +02:00
Eugen Rochko
34a9cb5a74 New translations strings.xml (Dutch) 2023-05-13 17:46:16 +02:00
Eugen Rochko
64fad2e871 New translations strings.xml (Vietnamese) 2023-05-13 16:36:00 +02:00
Eugen Rochko
9c89c26097 New translations strings.xml (Dutch) 2023-05-13 01:52:41 +02:00
Eugen Rochko
e3b6a5d389 New translations strings.xml (Dutch) 2023-05-13 00:57:05 +02:00
Eugen Rochko
0fb54efde5 New translations strings.xml (Dutch) 2023-05-12 23:58:21 +02:00
Eugen Rochko
a4a3f32dba New translations strings.xml (Dutch) 2023-05-12 22:45:52 +02:00
Eugen Rochko
03a1e29e0c New translations strings.xml (Dutch) 2023-05-12 19:43:17 +02:00
Eugen Rochko
eda9ff272b New translations strings.xml (Dutch) 2023-05-12 18:35:16 +02:00
Eugen Rochko
b3728e06ac New translations strings.xml (Swedish) 2023-05-11 12:28:06 +02:00
75 changed files with 1352 additions and 189 deletions

View File

@@ -15,8 +15,8 @@ android {
applicationId "org.joinmastodon.android.sk"
minSdk 23
targetSdk 33
versionCode 83
versionName "1.2.3+fork.83"
versionCode 85
versionName "1.2.3+fork.85"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
resourceConfigurations += ['ar-rSA', 'ar-rDZ', 'be-rBY', 'bn-rBD', 'bs-rBA', 'ca-rES', 'cs-rCZ', 'da-rDK', 'de-rDE', 'el-rGR', 'es-rES', 'eu-rES', 'fa-rIR', 'fi-rFI', 'fil-rPH', 'fr-rFR', 'ga-rIE', 'gd-rGB', 'gl-rES', 'hi-rIN', 'hr-rHR', 'hu-rHU', 'hy-rAM', 'ig-rNG', 'in-rID', 'is-rIS', 'it-rIT', 'iw-rIL', 'ja-rJP', 'kab', 'ko-rKR', 'my-rMM', 'nl-rNL', 'no-rNO', 'oc-rFR', 'pl-rPL', 'pt-rBR', 'pt-rPT', 'ro-rRO', 'ru-rRU', 'si-rLK', 'sl-rSI', 'sv-rSE', 'th-rTH', 'tr-rTR', 'uk-rUA', 'ur-rIN', 'vi-rVN', 'zh-rCN', 'zh-rTW']
}

View File

@@ -0,0 +1,81 @@
package org.joinmastodon.android.utils;
import static org.joinmastodon.android.model.Filter.FilterAction.*;
import static org.joinmastodon.android.model.Filter.FilterContext.*;
import static org.junit.Assert.*;
import org.joinmastodon.android.model.Filter;
import org.joinmastodon.android.model.Status;
import org.junit.Test;
import java.time.Instant;
import java.util.EnumSet;
import java.util.List;
public class StatusFilterPredicateTest {
private static final Filter hideMeFilter = new Filter(), warnMeFilter = new Filter();
private static final List<Filter> allFilters = List.of(hideMeFilter, warnMeFilter);
private static final Status
hideInHomePublic = Status.ofFake(null, "hide me, please", Instant.now()),
warnInHomePublic = Status.ofFake(null, "display me with a warning", Instant.now());
static {
hideMeFilter.phrase = "hide me";
hideMeFilter.filterAction = HIDE;
hideMeFilter.context = EnumSet.of(PUBLIC, HOME);
warnMeFilter.phrase = "warning";
warnMeFilter.filterAction = WARN;
warnMeFilter.context = EnumSet.of(PUBLIC, HOME);
}
@Test
public void testHide() {
assertFalse("should not pass because matching filter applies to given context",
new StatusFilterPredicate(allFilters, HOME).test(hideInHomePublic));
}
@Test
public void testHideRegardlessOfContext() {
assertTrue("filters without context should always pass",
new StatusFilterPredicate(allFilters, null).test(hideInHomePublic));
}
@Test
public void testHideInDifferentContext() {
assertTrue("should pass because matching filter does not apply to given context",
new StatusFilterPredicate(allFilters, THREAD).test(hideInHomePublic));
}
@Test
public void testHideWithWarningText() {
assertTrue("should pass because matching filter is for warnings",
new StatusFilterPredicate(allFilters, HOME).test(warnInHomePublic));
}
@Test
public void testWarn() {
assertFalse("should not pass because filter applies to given context",
new StatusFilterPredicate(allFilters, HOME, WARN).test(warnInHomePublic));
}
@Test
public void testWarnRegardlessOfContext() {
assertTrue("filters without context should always pass",
new StatusFilterPredicate(allFilters, null, WARN).test(warnInHomePublic));
}
@Test
public void testWarnInDifferentContext() {
assertTrue("should pass because filter does not apply to given context",
new StatusFilterPredicate(allFilters, THREAD, WARN).test(warnInHomePublic));
}
@Test
public void testWarnWithHideText() {
assertTrue("should pass because matching filter is for hiding",
new StatusFilterPredicate(allFilters, HOME, WARN).test(hideInHomePublic));
}
}

View File

@@ -77,6 +77,16 @@ public class GlobalUserPreferences{
catch (JsonSyntaxException ignored) { return orElse; }
}
public static void removeAccount(String accountId) {
recentLanguages.remove(accountId);
pinnedTimelines.remove(accountId);
accountsInGlitchMode.remove(accountId);
accountsWithLocalOnlySupport.remove(accountId);
accountsWithContentTypesEnabled.remove(accountId);
accountsDefaultContentTypes.remove(accountId);
save();
}
public static void load(){
SharedPreferences prefs=getPrefs();
playGifs=prefs.getBoolean("playGifs", true);
@@ -186,4 +196,3 @@ public class GlobalUserPreferences{
DARK
}
}

View File

@@ -19,7 +19,6 @@ import org.joinmastodon.android.model.CacheablePaginatedResponse;
import org.joinmastodon.android.model.Filter;
import org.joinmastodon.android.model.Instance;
import org.joinmastodon.android.model.Notification;
import org.joinmastodon.android.model.PaginatedResponse;
import org.joinmastodon.android.model.SearchResult;
import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.utils.StatusFilterPredicate;
@@ -160,7 +159,7 @@ public class CacheController{
}
}
Instance instance=AccountSessionManager.getInstance().getInstanceInfo(accountSession.domain);
new GetNotifications(maxID, count, onlyPosts ? EnumSet.of(Notification.Type.STATUS) : onlyMentions ? EnumSet.of(Notification.Type.MENTION): EnumSet.allOf(Notification.Type.class), instance.pleroma != null)
new GetNotifications(maxID, count, onlyPosts ? EnumSet.of(Notification.Type.STATUS) : onlyMentions ? EnumSet.of(Notification.Type.MENTION): EnumSet.allOf(Notification.Type.class), instance.isPleroma())
.setCallback(new Callback<>(){
@Override
public void onSuccess(List<Notification> result){

View File

@@ -0,0 +1,30 @@
package org.joinmastodon.android.api.requests.notifications;
import android.text.TextUtils;
import com.google.gson.reflect.TypeToken;
import org.joinmastodon.android.api.MastodonAPIRequest;
import org.joinmastodon.android.model.Notification;
import java.util.List;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
public class PleromaMarkNotificationsRead extends MastodonAPIRequest<List<Notification>> {
private String maxID;
public PleromaMarkNotificationsRead(String maxID) {
super(HttpMethod.POST, "/pleroma/notifications/read", new TypeToken<>(){});
this.maxID = maxID;
}
@Override
public RequestBody getRequestBody() {
MultipartBody.Builder builder=new MultipartBody.Builder()
.setType(MultipartBody.FORM);
if(!TextUtils.isEmpty(maxID))
builder.addFormDataPart("max_id", maxID);
return builder.build();
}
}

View File

@@ -0,0 +1,23 @@
package org.joinmastodon.android.api.requests.timelines;
import android.text.TextUtils;
import com.google.gson.reflect.TypeToken;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.api.MastodonAPIRequest;
import org.joinmastodon.android.model.Status;
import java.util.List;
public class GetBubbleTimeline extends MastodonAPIRequest<List<Status>> {
public GetBubbleTimeline(String maxID, int limit) {
super(HttpMethod.GET, "/timelines/bubble", new TypeToken<>(){});
if(!TextUtils.isEmpty(maxID))
addQueryParameter("max_id", maxID);
if(limit>0)
addQueryParameter("limit", limit+"");
if(GlobalUserPreferences.replyVisibility != null)
addQueryParameter("reply_visibility", GlobalUserPreferences.replyVisibility);
}
}

View File

@@ -2,6 +2,7 @@ package org.joinmastodon.android.api.requests.timelines;
import com.google.gson.reflect.TypeToken;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.api.MastodonAPIRequest;
import org.joinmastodon.android.model.Status;
@@ -16,5 +17,7 @@ public class GetHashtagTimeline extends MastodonAPIRequest<List<Status>>{
addQueryParameter("min_id", minID);
if(limit>0)
addQueryParameter("limit", ""+limit);
if(GlobalUserPreferences.replyVisibility != null)
addQueryParameter("reply_visibility", GlobalUserPreferences.replyVisibility);
}
}

View File

@@ -2,6 +2,7 @@ package org.joinmastodon.android.api.requests.timelines;
import com.google.gson.reflect.TypeToken;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.api.MastodonAPIRequest;
import org.joinmastodon.android.model.Status;
@@ -18,5 +19,7 @@ public class GetListTimeline extends MastodonAPIRequest<List<Status>> {
addQueryParameter("limit", ""+limit);
if(sinceID!=null)
addQueryParameter("since_id", sinceID);
if(GlobalUserPreferences.replyVisibility != null)
addQueryParameter("reply_visibility", GlobalUserPreferences.replyVisibility);
}
}

View File

@@ -4,6 +4,7 @@ import android.text.TextUtils;
import com.google.gson.reflect.TypeToken;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.api.MastodonAPIRequest;
import org.joinmastodon.android.model.Status;
@@ -20,5 +21,7 @@ public class GetPublicTimeline extends MastodonAPIRequest<List<Status>>{
addQueryParameter("max_id", maxID);
if(limit>0)
addQueryParameter("limit", limit+"");
if(GlobalUserPreferences.replyVisibility != null)
addQueryParameter("reply_visibility", GlobalUserPreferences.replyVisibility);
}
}

View File

@@ -7,6 +7,7 @@ import org.joinmastodon.android.api.StatusInteractionController;
import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.Application;
import org.joinmastodon.android.model.Filter;
import org.joinmastodon.android.model.Instance;
import org.joinmastodon.android.model.Markers;
import org.joinmastodon.android.model.Preferences;
import org.joinmastodon.android.model.PushSubscription;
@@ -87,4 +88,8 @@ public class AccountSession{
pushSubscriptionManager=new PushSubscriptionManager(getID());
return pushSubscriptionManager;
}
public Instance getInstance() {
return AccountSessionManager.getInstance().getInstanceInfo(domain);
}
}

View File

@@ -15,6 +15,7 @@ import android.util.Log;
import org.joinmastodon.android.BuildConfig;
import org.joinmastodon.android.E;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.MainActivity;
import org.joinmastodon.android.MastodonApp;
import org.joinmastodon.android.R;
@@ -110,6 +111,12 @@ public class AccountSessionManager{
sessions.put(session.getID(), session);
lastActiveAccountID=session.getID();
writeAccountsFile();
// write initial instance info to file immediately to avoid sessions without instance info
InstanceInfoStorageWrapper wrapper = new InstanceInfoStorageWrapper();
wrapper.instance = instance;
MastodonAPIController.runInBackground(()->writeInstanceInfoFile(wrapper, instance.uri));
updateMoreInstanceInfo(instance, instance.uri);
if(PushSubscriptionManager.arePushNotificationsAvailable()){
session.getPushSubscriptionManager().registerAccountForPush(null);
@@ -178,6 +185,7 @@ public class AccountSessionManager{
AccountSession session=getAccount(id);
session.getCacheController().closeDatabase();
MastodonApp.context.deleteDatabase(id+".db");
GlobalUserPreferences.removeAccount(id);
sessions.remove(id);
if(lastActiveAccountID.equals(id)){
if(sessions.isEmpty())
@@ -455,11 +463,12 @@ public class AccountSessionManager{
}
public Instance getInstanceInfo(String domain){
return instances.get(domain);
}
public Instance getInstanceInfoForAccount(String account) {
return AccountSessionManager.getInstance().getInstanceInfo(instance.getAccount(account).domain);
Instance instance = instances.get(domain);
if (instance == null) {
throw new IllegalStateException("Cannot get instance for " + domain + ". Sessions: "
+ String.join(", ", instances.keySet()));
}
return instance;
}
public void updateAccountInfo(String id, Account account){

View File

@@ -85,7 +85,8 @@ public class AccountTimelineFragment extends StatusListFragment{
}
protected void onStatusCreated(StatusCreatedEvent ev){
if(!AccountSessionManager.getInstance().isSelf(accountID, ev.status.account))
AccountSessionManager asm = AccountSessionManager.getInstance();
if(!asm.isSelf(accountID, ev.status.account) || !asm.isSelf(accountID, user))
return;
if(filter==GetAccountStatuses.Filter.PINNED) return;
if(filter==GetAccountStatuses.Filter.DEFAULT){

View File

@@ -551,6 +551,14 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
}
}
public void onImageUpdated(MediaGridStatusDisplayItem.Holder holder, int index) {
holder.rebind();
MediaGridStatusDisplayItem.Holder mediaGrid = findHolderOfType(holder.getItemID(), MediaGridStatusDisplayItem.Holder.class);
if(mediaGrid!=null){
adapter.notifyItemChanged(mediaGrid.getAbsoluteAdapterPosition());
}
}
public void onGapClick(GapStatusDisplayItem.Holder item){}
public void onWarningClick(WarningFilteredStatusDisplayItem.Holder warning){

View File

@@ -245,10 +245,6 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
accountID=getArguments().getString("account");
contentType = GlobalUserPreferences.accountsDefaultContentTypes.get(accountID);
if (contentType == null && GlobalUserPreferences.accountsWithContentTypesEnabled.contains(accountID)) {
// if formatting is enabled, use plain to avoid confusing unspecified default setting
contentType = ContentType.PLAIN;
}
AccountSession session=AccountSessionManager.getInstance().getAccount(accountID);
self=session.self;
@@ -1091,7 +1087,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
}
req.status=text;
req.localOnly=localOnly;
req.visibility=localOnly && instance.pleroma != null ? StatusPrivacy.LOCAL : statusVisibility;
req.visibility=localOnly && instance.isPleroma() ? StatusPrivacy.LOCAL : statusVisibility;
req.sensitive=sensitive;
req.language=language;
req.contentType=contentType;
@@ -1747,11 +1743,24 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
pollChanged=true;
updatePublishButtonState();
}));
option.edit.setFilters(new InputFilter[]{new InputFilter.LengthFilter(instance.configuration!=null && instance.configuration.polls!=null && instance.configuration.polls.maxCharactersPerOption>0 ? instance.configuration.polls.maxCharactersPerOption : 50)});
int maxCharactersPerOption = 50;
if(instance.configuration!=null && instance.configuration.polls!=null && instance.configuration.polls.maxCharactersPerOption>0)
maxCharactersPerOption = instance.configuration.polls.maxCharactersPerOption;
else if(instance.pollLimits!=null && instance.pollLimits.maxOptionChars>0)
maxCharactersPerOption = instance.pollLimits.maxOptionChars;
option.edit.setFilters(new InputFilter[]{new InputFilter.LengthFilter(maxCharactersPerOption)});
pollOptionsView.addView(option.view);
pollOptions.add(option);
if(pollOptions.size()==(instance.configuration!=null && instance.configuration.polls!=null && instance.configuration.polls.maxOptions>0 ? instance.configuration.polls.maxOptions : 4))
int maxPollOptions = 4;
if(instance.configuration!=null && instance.configuration.polls!=null && instance.configuration.polls.maxOptions>0)
maxPollOptions = instance.configuration.polls.maxOptions;
else if (instance.pollLimits!=null && instance.pollLimits.maxOptions>0)
maxPollOptions = instance.pollLimits.maxOptions;
if(pollOptions.size()==maxPollOptions)
addPollOptionBtn.setVisibility(View.GONE);
return option;
}
@@ -1893,7 +1902,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
Menu m=visibilityPopup.getMenu();
MenuItem localOnlyItem = visibilityPopup.getMenu().findItem(R.id.local_only);
boolean prefsSaysSupported = GlobalUserPreferences.accountsWithLocalOnlySupport.contains(accountID);
if (instance.pleroma != null) {
if (instance.isPleroma()) {
m.findItem(R.id.vis_local).setVisible(true);
} else if (localOnly || prefsSaysSupported) {
localOnlyItem.setVisible(true);

View File

@@ -30,8 +30,11 @@ import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.lists.GetLists;
import org.joinmastodon.android.api.requests.tags.GetFollowedHashtags;
import org.joinmastodon.android.api.session.AccountSession;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.model.Hashtag;
import org.joinmastodon.android.model.HeaderPaginationList;
import org.joinmastodon.android.model.Instance;
import org.joinmastodon.android.model.ListTimeline;
import org.joinmastodon.android.model.TimelineDefinition;
import org.joinmastodon.android.ui.DividerItemDecoration;
@@ -164,7 +167,7 @@ public class EditTimelinesFragment extends RecyclerFragment<TimelineDefinition>
makeBackItem(listsMenu);
makeBackItem(hashtagsMenu);
TimelineDefinition.ALL_TIMELINES.forEach(tl -> addTimelineToOptions(tl, timelinesMenu));
TimelineDefinition.getAllTimelines(accountID).forEach(tl -> addTimelineToOptions(tl, timelinesMenu));
listTimelines.stream().map(TimelineDefinition::ofList).forEach(tl -> addTimelineToOptions(tl, listsMenu));
hashtags.stream().map(TimelineDefinition::ofHashtag).forEach(tl -> addTimelineToOptions(tl, hashtagsMenu));
@@ -190,7 +193,7 @@ public class EditTimelinesFragment extends RecyclerFragment<TimelineDefinition>
@Override
protected void doLoadData(int offset, int count){
onDataLoaded(GlobalUserPreferences.pinnedTimelines.getOrDefault(accountID, TimelineDefinition.DEFAULT_TIMELINES), false);
onDataLoaded(GlobalUserPreferences.pinnedTimelines.getOrDefault(accountID, TimelineDefinition.getDefaultTimelines(accountID)), false);
updateOptionsMenu();
}

View File

@@ -66,6 +66,7 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
private int currentTab=R.id.tab_home;
private String accountID;
private boolean isPleroma;
@Override
public void onCreate(Bundle savedInstanceState){
@@ -73,16 +74,20 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
E.register(this);
accountID=getArguments().getString("account");
setTitle(R.string.sk_app_name);
Instance instance = AccountSessionManager.getInstance().getAccount(accountID).getInstance();
isPleroma = instance.isPleroma();
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N)
setRetainInstance(true);
// TODO: clean up
if(savedInstanceState==null){
Bundle args=new Bundle();
args.putString("account", accountID);
homeTabFragment=new HomeTabFragment();
homeTabFragment.setArguments(args);
args=new Bundle(args);
args.putBoolean("disableDiscover", isPleroma);
args.putBoolean("noAutoLoad", true);
searchFragment=new DiscoverFragment();
searchFragment.setArguments(args);
@@ -231,6 +236,7 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
if (newFragment instanceof HasFab fabulous) fabulous.showFab();
currentTab=tab;
((FragmentStackActivity)getActivity()).invalidateSystemBarColors(this);
if (tab == R.id.tab_search && isPleroma) searchFragment.selectSearch();
}
private void maybeTriggerLoading(Fragment newFragment){
@@ -290,10 +296,10 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
public void updateNotificationBadge() {
AccountSession session = AccountSessionManager.getInstance().getAccount(accountID);
Instance instance = AccountSessionManager.getInstance().getInstanceInfo(session.domain);
Instance instance = session.getInstance();
if (instance == null) return;
new GetNotifications(null, 1, EnumSet.allOf(Notification.Type.class), instance != null && instance.pleroma != null)
new GetNotifications(null, 1, EnumSet.allOf(Notification.Type.class), instance != null && instance.isPleroma())
.setCallback(new Callback<>() {
@Override
public void onSuccess(List<Notification> notifications) {

View File

@@ -106,7 +106,7 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab
super.onCreate(savedInstanceState);
E.register(this);
accountID = getArguments().getString("account");
timelineDefinitions = GlobalUserPreferences.pinnedTimelines.getOrDefault(accountID, TimelineDefinition.DEFAULT_TIMELINES);
timelineDefinitions = GlobalUserPreferences.pinnedTimelines.getOrDefault(accountID, TimelineDefinition.getDefaultTimelines(accountID));
assert timelineDefinitions != null;
if (timelineDefinitions.size() == 0) timelineDefinitions = List.of(TimelineDefinition.HOME_TIMELINE);
count = timelineDefinitions.size();

View File

@@ -9,7 +9,10 @@ import com.squareup.otto.Subscribe;
import org.joinmastodon.android.E;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.MastodonErrorResponse;
import org.joinmastodon.android.api.requests.markers.SaveMarkers;
import org.joinmastodon.android.api.requests.notifications.PleromaMarkNotificationsRead;
import org.joinmastodon.android.api.session.AccountSession;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.events.AllNotificationsSeenEvent;
import org.joinmastodon.android.events.PollUpdatedEvent;
@@ -18,6 +21,7 @@ import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.CacheablePaginatedResponse;
import org.joinmastodon.android.model.Emoji;
import org.joinmastodon.android.model.Filter;
import org.joinmastodon.android.model.Instance;
import org.joinmastodon.android.model.Notification;
import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.ui.displayitems.AccountCardStatusDisplayItem;
@@ -40,6 +44,7 @@ import java.util.stream.Stream;
import androidx.recyclerview.widget.RecyclerView;
import me.grishka.appkit.Nav;
import me.grishka.appkit.api.ErrorResponse;
import me.grishka.appkit.api.SimpleCallback;
public class NotificationsListFragment extends BaseStatusListFragment<Notification>{
@@ -151,13 +156,16 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
loadRelationships(needRelationships);
maxID=result.maxID;
if(offset==0 && !result.items.isEmpty() && !result.isFromCache()){
if(offset==0 && !result.items.isEmpty() && !result.isFromCache() && AccountSessionManager.getInstance().getAccount(accountID).markers.notifications != null){
E.post(new AllNotificationsSeenEvent());
new SaveMarkers(null, result.items.get(0).id).exec(accountID);
if (AccountSessionManager.getInstance().getAccount(accountID).markers != null)
AccountSessionManager.getInstance().getAccount(accountID).markers
.notifications.lastReadId = result.items.get(0).id;
AccountSessionManager.getInstance().writeAccountsFile();
if (AccountSessionManager.getInstance().getAccount(accountID).getInstance().isPleroma())
new PleromaMarkNotificationsRead(result.items.get(0).id).exec(accountID);
}
}
});

View File

@@ -20,7 +20,7 @@ public abstract class PinnableStatusListFragment extends StatusListFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
pinnedTimelines = new ArrayList<>(GlobalUserPreferences.pinnedTimelines.getOrDefault(accountID, TimelineDefinition.DEFAULT_TIMELINES));
pinnedTimelines = new ArrayList<>(GlobalUserPreferences.pinnedTimelines.getOrDefault(accountID, TimelineDefinition.getDefaultTimelines(accountID)));
}
@Override

View File

@@ -31,7 +31,6 @@ import android.view.ViewOutlineProvider;
import android.view.ViewTreeObserver;
import android.view.WindowInsets;
import android.view.inputmethod.InputMethodManager;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
@@ -51,6 +50,7 @@ import org.joinmastodon.android.api.requests.accounts.GetAccountStatuses;
import org.joinmastodon.android.api.requests.accounts.GetOwnAccount;
import org.joinmastodon.android.api.requests.accounts.SetAccountFollowed;
import org.joinmastodon.android.api.requests.accounts.UpdateAccountCredentials;
import org.joinmastodon.android.api.session.AccountSession;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.fragments.account_list.FollowerListFragment;
import org.joinmastodon.android.fragments.account_list.FollowingListFragment;
@@ -58,6 +58,7 @@ import org.joinmastodon.android.fragments.report.ReportReasonChoiceFragment;
import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.AccountField;
import org.joinmastodon.android.model.Attachment;
import org.joinmastodon.android.model.Instance;
import org.joinmastodon.android.model.Relationship;
import org.joinmastodon.android.ui.BetterItemAnimator;
import org.joinmastodon.android.ui.SimpleViewHolder;
@@ -137,6 +138,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
private Account account;
private String accountID;
private String domain;
private Relationship relationship;
private int statusBarHeight;
private boolean isOwnProfile;
@@ -151,7 +153,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
private PhotoViewer currentPhotoViewer;
private boolean editModeLoading;
private static final int MAX_FIELDS=4;
private int maxFields = 4;
// from ProfileAboutFragment
public UsableRecyclerView list;
@@ -172,6 +174,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
setRetainInstance(true);
accountID=getArguments().getString("account");
domain=AccountSessionManager.getInstance().getAccount(accountID).domain;
if(getArguments().containsKey("profileAccount")){
account=Parcels.unwrap(getArguments().getParcelable("profileAccount"));
profileAccountID=account.id;
@@ -179,6 +182,12 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
loaded=true;
if(!isOwnProfile)
loadRelationship();
else {
Instance instance = AccountSessionManager.getInstance().getInstanceInfo(domain);
if (instance.isPleroma()) {
maxFields = instance.pleroma.metadata.fieldsLimits.maxFields;
}
}
}else{
profileAccountID=getArguments().getString("profileAccountID");
if(!getArguments().getBoolean("noAutoLoad", false))
@@ -324,7 +333,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
username.setOnLongClickListener(v->{
String usernameString=account.acct;
if(!usernameString.contains("@")){
usernameString+="@"+AccountSessionManager.getInstance().getAccount(accountID).domain;
usernameString+="@"+domain;
}
UiUtils.copyText(username, '@'+usernameString);
return true;
@@ -510,7 +519,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
ssb.append(account.acct);
if(isSelf){
ssb.append('@');
ssb.append(AccountSessionManager.getInstance().getAccount(accountID).domain);
ssb.append(domain);
}
ssb.append(" ");
Drawable lock=username.getResources().getDrawable(R.drawable.ic_lock, getActivity().getTheme()).mutate();
@@ -520,7 +529,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
username.setText(ssb);
}else{
// noinspection SetTextI18n
username.setText('@'+account.acct+(isSelf ? ('@'+AccountSessionManager.getInstance().getAccount(accountID).domain) : ""));
username.setText('@'+account.acct+(isSelf ? ('@'+domain) : ""));
}
CharSequence parsedBio=HtmlParser.parse(account.note, account.emojis, Collections.emptyList(), Collections.emptyList(), accountID);
if(TextUtils.isEmpty(parsedBio)){
@@ -1189,7 +1198,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
public int getItemCount(){
if(isInEditMode){
int size=metadataListData.size();
if(size<MAX_FIELDS)
if(size<maxFields)
size++;
return size;
}
@@ -1306,7 +1315,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
@Override
public void onClick(){
metadataListData.add(new AccountField());
if(metadataListData.size()==MAX_FIELDS){ // replace this row with new row
if(metadataListData.size()==maxFields){ // replace this row with new row
adapter.notifyItemChanged(metadataListData.size()-1);
}else{
adapter.notifyItemInserted(metadataListData.size()-1);

View File

@@ -105,7 +105,7 @@ public class SettingsFragment extends MastodonToolbarFragment{
imageCache = ImageCache.getInstance(getActivity());
accountID=getArguments().getString("account");
AccountSession session=AccountSessionManager.getInstance().getAccount(accountID);
Instance instance = AccountSessionManager.getInstance().getInstanceInfo(session.domain);
Instance instance = session.getInstance();
String instanceName = UiUtils.getInstanceName(accountID);
if(GithubSelfUpdater.needSelfUpdating()){
@@ -223,7 +223,7 @@ public class SettingsFragment extends MastodonToolbarFragment{
GlobalUserPreferences.showReplies=i.checked;
GlobalUserPreferences.save();
}));
if (instance.pleroma != null) {
if (instance.isPleroma()) {
items.add(new ButtonItem(R.string.sk_settings_reply_visibility, R.drawable.ic_fluent_chat_24_regular, b->{
PopupMenu popupMenu=new PopupMenu(getActivity(), b, Gravity.CENTER_HORIZONTAL);
popupMenu.inflate(R.menu.reply_visibility);
@@ -362,8 +362,6 @@ public class SettingsFragment extends MastodonToolbarFragment{
contentTypeMenu = popupMenu.getMenu();
contentTypeMenu.findItem(ContentType.getContentTypeRes(contentType)).setChecked(true);
ContentType.adaptMenuToInstance(contentTypeMenu, instance);
contentTypeMenu.findItem(R.id.content_type_null).setVisible(
!GlobalUserPreferences.accountsWithContentTypesEnabled.contains(accountID));
}));
items.add(new SmallTextItem(getString(R.string.sk_settings_default_content_type_explanation)));
items.add(new SwitchItem(R.string.sk_settings_support_local_only, 0, GlobalUserPreferences.accountsWithLocalOnlySupport.contains(accountID), i->{

View File

@@ -74,7 +74,7 @@ public class ThreadFragment extends StatusListFragment{
}
AccountSession account=AccountSessionManager.getInstance().getAccount(accountID);
Instance instance=AccountSessionManager.getInstance().getInstanceInfo(account.domain);
if(instance.pleroma != null){
if(instance.isPleroma()){
List<String> threadIds=new ArrayList<>();
threadIds.add(mainStatus.id);
for(Status s:result.descendants){

View File

@@ -0,0 +1,55 @@
package org.joinmastodon.android.fragments.discover;
import android.os.Bundle;
import android.view.View;
import org.joinmastodon.android.api.requests.timelines.GetBubbleTimeline;
import org.joinmastodon.android.api.requests.timelines.GetPublicTimeline;
import org.joinmastodon.android.fragments.StatusListFragment;
import org.joinmastodon.android.model.Filter;
import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.ui.utils.DiscoverInfoBannerHelper;
import org.joinmastodon.android.utils.StatusFilterPredicate;
import java.util.List;
import java.util.stream.Collectors;
import me.grishka.appkit.api.SimpleCallback;
public class BubbleTimelineFragment extends StatusListFragment {
private DiscoverInfoBannerHelper bannerHelper=new DiscoverInfoBannerHelper(DiscoverInfoBannerHelper.BannerType.BUBBLE_TIMELINE);
private String maxID;
@Override
protected boolean wantsComposeButton() {
return true;
}
@Override
protected void doLoadData(int offset, int count){
currentRequest=new GetBubbleTimeline(refreshing ? null : maxID, count)
.setCallback(new SimpleCallback<>(this){
@Override
public void onSuccess(List<Status> result){
if(!result.isEmpty())
maxID=result.get(result.size()-1).id;
if (getActivity() == null) return;
result=result.stream().filter(new StatusFilterPredicate(accountID, getFilterContext())).collect(Collectors.toList());
onDataLoaded(result, !result.isEmpty());
}
})
.exec(accountID);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);
bannerHelper.maybeAddBanner(contentWrap);
}
@Override
protected Filter.FilterContext getFilterContext() {
return Filter.FilterContext.PUBLIC;
}
}

View File

@@ -19,6 +19,7 @@ import android.widget.TextView;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.R;
import org.joinmastodon.android.fragments.HomeFragment;
import org.joinmastodon.android.fragments.IsOnTop;
import org.joinmastodon.android.fragments.ScrollableToTop;
import org.joinmastodon.android.ui.SimpleViewHolder;
@@ -238,7 +239,7 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
else scrollToTop();
}
private void selectSearch() {
public void selectSearch() {
searchEdit.requestFocus();
onSearchEditFocusChanged(searchEdit, true);
getActivity().getSystemService(InputMethodManager.class).showSoftInput(searchEdit, 0);
@@ -272,6 +273,8 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
searchBack.setEnabled(false);
searchBack.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
getActivity().getSystemService(InputMethodManager.class).hideSoftInputFromWindow(searchEdit.getWindowToken(), 0);
if (getArguments().getBoolean("disableDiscover"))
((HomeFragment) getParentFragment()).onBackPressed();
}
@Override

View File

@@ -1,5 +1,8 @@
package org.joinmastodon.android.fragments.discover;
import static org.joinmastodon.android.ui.displayitems.HashtagStatusDisplayItem.Holder.withHistoryParams;
import static org.joinmastodon.android.ui.displayitems.HashtagStatusDisplayItem.Holder.withoutHistoryParams;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
@@ -105,6 +108,14 @@ public class TrendingHashtagsFragment extends RecyclerFragment<Hashtag> implemen
@Override
public void onBind(Hashtag item){
title.setText('#'+item.name);
if (item.history == null || item.history.isEmpty()) {
subtitle.setText(null);
chart.setVisibility(View.GONE);
title.setLayoutParams(withoutHistoryParams);
return;
}
chart.setVisibility(View.VISIBLE);
title.setLayoutParams(withHistoryParams);
int numPeople=item.history.get(0).accounts;
if(item.history.size()>1)
numPeople+=item.history.get(1).accounts;

View File

@@ -124,6 +124,7 @@ public class CustomWelcomeFragment extends InstanceCatalogFragment {
super.onViewCreated(view, savedInstanceState);
view.setBackgroundColor(UiUtils.getThemeColor(getActivity(), R.attr.colorWindowBackground));
list.setItemAnimator(new BetterItemAnimator());
((UsableRecyclerView) list).setSelector(null);
}
@Override

View File

@@ -86,6 +86,8 @@ public class Instance extends BaseModel{
public Pleroma pleroma;
public PleromaPollLimits pollLimits;
@Override
public void postprocess() throws ObjectValidationException{
super.postprocess();
@@ -134,6 +136,10 @@ public class Instance extends BaseModel{
return ci;
}
public boolean isPleroma() {
return pleroma != null;
}
@Parcel
public static class Rule{
public String id;
@@ -198,6 +204,28 @@ public class Instance extends BaseModel{
@Parcel
public static class Pleroma extends BaseModel {
// metadata etc
public Pleroma.Metadata metadata;
@Parcel
public static class Metadata {
public List<String> features;
public Pleroma.Metadata.FieldsLimits fieldsLimits;
@Parcel
public static class FieldsLimits {
public int maxFields;
public int maxRemoteFields;
public int nameLength;
public int valueLength;
}
}
}
@Parcel
public static class PleromaPollLimits {
public int maxExpiration;
public int maxOptionChars;
public int maxOptions;
public int minExpiration;
}
}

View File

@@ -50,6 +50,8 @@ public class Status extends BaseModel implements DisplayItemsParent, Searchable{
public long favouritesCount;
public long repliesCount;
public Instant editedAt;
// might not be provided (by older mastodon servers),
// so megalodon will use the locally cached filters if filtered == null
public List<FilterResult> filtered;
public String url;
@@ -180,7 +182,6 @@ public class Status extends BaseModel implements DisplayItemsParent, Searchable{
s.mentions = List.of();
s.tags = List.of();
s.emojis = List.of();
s.filtered = List.of();
return s;
}

View File

@@ -8,17 +8,20 @@ import androidx.annotation.DrawableRes;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import org.joinmastodon.android.BuildConfig;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.session.AccountSession;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.fragments.HashtagTimelineFragment;
import org.joinmastodon.android.fragments.HomeTimelineFragment;
import org.joinmastodon.android.fragments.ListTimelineFragment;
import org.joinmastodon.android.fragments.NotificationsListFragment;
import org.joinmastodon.android.fragments.discover.BubbleTimelineFragment;
import org.joinmastodon.android.fragments.discover.FederatedTimelineFragment;
import org.joinmastodon.android.fragments.discover.LocalTimelineFragment;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class TimelineDefinition {
private TimelineType type;
@@ -58,6 +61,14 @@ public class TimelineDefinition {
this.type = type;
}
public boolean isCompatible(AccountSession session) {
return true;
}
public boolean wantsDefault(AccountSession session) {
return true;
}
public String getTitle(Context ctx) {
return title != null ? title : getDefaultTitle(ctx);
}
@@ -78,6 +89,7 @@ public class TimelineDefinition {
case POST_NOTIFICATIONS -> ctx.getString(R.string.sk_timeline_posts);
case LIST -> listTitle;
case HASHTAG -> hashtagName;
case BUBBLE -> ctx.getString(R.string.sk_timeline_bubble);
};
}
@@ -89,6 +101,7 @@ public class TimelineDefinition {
case POST_NOTIFICATIONS -> Icon.POST_NOTIFICATIONS;
case LIST -> Icon.LIST;
case HASHTAG -> Icon.HASHTAG;
case BUBBLE -> Icon.BUBBLE;
};
}
@@ -100,6 +113,7 @@ public class TimelineDefinition {
case LIST -> new ListTimelineFragment();
case HASHTAG -> new HashtagTimelineFragment();
case POST_NOTIFICATIONS -> new NotificationsListFragment();
case BUBBLE -> new BubbleTimelineFragment();
};
}
@@ -156,7 +170,7 @@ public class TimelineDefinition {
return args;
}
public enum TimelineType { HOME, LOCAL, FEDERATED, POST_NOTIFICATIONS, LIST, HASHTAG }
public enum TimelineType { HOME, LOCAL, FEDERATED, POST_NOTIFICATIONS, LIST, HASHTAG, BUBBLE }
public enum Icon {
HEART(R.drawable.ic_fluent_heart_24_regular, R.string.sk_icon_heart),
@@ -219,7 +233,8 @@ public class TimelineDefinition {
FEDERATED(R.drawable.ic_fluent_earth_24_regular, R.string.sk_timeline_federated, true),
POST_NOTIFICATIONS(R.drawable.ic_fluent_chat_24_regular, R.string.sk_timeline_posts, true),
LIST(R.drawable.ic_fluent_people_24_regular, R.string.sk_list, true),
HASHTAG(R.drawable.ic_fluent_number_symbol_24_regular, R.string.sk_hashtag, true);
HASHTAG(R.drawable.ic_fluent_number_symbol_24_regular, R.string.sk_hashtag, true),
BUBBLE(R.drawable.ic_fluent_circle_24_regular, R.string.sk_timeline_bubble, true);
public final int iconRes, nameRes;
public final boolean hidden;
@@ -239,14 +254,49 @@ public class TimelineDefinition {
public static final TimelineDefinition LOCAL_TIMELINE = new TimelineDefinition(TimelineType.LOCAL);
public static final TimelineDefinition FEDERATED_TIMELINE = new TimelineDefinition(TimelineType.FEDERATED);
public static final TimelineDefinition POSTS_TIMELINE = new TimelineDefinition(TimelineType.POST_NOTIFICATIONS);
public static final TimelineDefinition BUBBLE_TIMELINE = new TimelineDefinition(TimelineType.BUBBLE) {
@Override
public boolean isCompatible(AccountSession session) {
// still enabling the bubble timeline for all pleroma/akkoma instances since i know of
// at least one instance that supports it, but doesn't list "bubble_timeline"
return session.getInstance().isPleroma();
}
public static final List<TimelineDefinition> DEFAULT_TIMELINES = BuildConfig.BUILD_TYPE.equals("playRelease")
? List.of(HOME_TIMELINE.copy(), LOCAL_TIMELINE.copy())
: List.of(HOME_TIMELINE.copy(), LOCAL_TIMELINE.copy(), FEDERATED_TIMELINE.copy());
public static final List<TimelineDefinition> ALL_TIMELINES = List.of(
HOME_TIMELINE.copy(),
LOCAL_TIMELINE.copy(),
FEDERATED_TIMELINE.copy(),
POSTS_TIMELINE.copy()
@Override
public boolean wantsDefault(AccountSession session) {
Instance instance = session.getInstance();
return instance.isPleroma() && instance.pleroma.metadata.features.contains("bubble_timeline");
}
};
public static List<TimelineDefinition> getDefaultTimelines(String accountId) {
AccountSession session = AccountSessionManager.getInstance().getAccount(accountId);
return DEFAULT_TIMELINES.stream()
.filter(tl -> tl.isCompatible(session) && tl.wantsDefault(session))
.map(TimelineDefinition::copy)
.collect(Collectors.toList());
}
public static List<TimelineDefinition> getAllTimelines(String accountId) {
AccountSession session = AccountSessionManager.getInstance().getAccount(accountId);
return ALL_TIMELINES.stream()
.filter(tl -> tl.isCompatible(session))
.map(TimelineDefinition::copy)
.collect(Collectors.toList());
}
private static final List<TimelineDefinition> DEFAULT_TIMELINES = List.of(
HOME_TIMELINE,
LOCAL_TIMELINE,
BUBBLE_TIMELINE,
FEDERATED_TIMELINE
);
private static final List<TimelineDefinition> ALL_TIMELINES = List.of(
HOME_TIMELINE,
LOCAL_TIMELINE,
FEDERATED_TIMELINE,
POSTS_TIMELINE,
BUBBLE_TIMELINE
);
}

View File

@@ -18,13 +18,15 @@ package org.joinmastodon.android.ui;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.view.View;
import android.view.ViewPropertyAnimator;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SimpleItemAnimator;
import org.joinmastodon.android.ui.displayitems.MediaGridStatusDisplayItem;
import me.grishka.appkit.utils.CubicBezierInterpolator;
import java.util.ArrayList;
@@ -358,7 +360,14 @@ public class BetterItemAnimator extends SimpleItemAnimator{
mChangeAnimations.add(changeInfo.oldHolder);
oldViewAnim.translationX(changeInfo.toX - changeInfo.fromX);
oldViewAnim.translationY(changeInfo.toY - changeInfo.fromY);
oldViewAnim.alpha(0).setListener(new AnimatorListenerAdapter() {
float alpha = 0;
if (holder instanceof MediaGridStatusDisplayItem.Holder mediaItemHolder) {
if (mediaItemHolder.isSizeUpdating()) {
alpha = 1; // Image will flicker out and then in if alpha is 0
mediaItemHolder.sizeUpdated();
}
}
oldViewAnim.alpha(alpha).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animator) {
dispatchChangeStarting(changeInfo.oldHolder, true);

View File

@@ -0,0 +1,64 @@
package org.joinmastodon.android.ui.displayitems;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import org.joinmastodon.android.R;
import org.joinmastodon.android.fragments.BaseStatusListFragment;
import org.joinmastodon.android.model.Attachment;
import org.joinmastodon.android.model.Card;
import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.ui.drawables.BlurhashCrossfadeDrawable;
import org.joinmastodon.android.ui.utils.UiUtils;
import me.grishka.appkit.imageloader.ImageLoaderViewHolder;
public class FileStatusDisplayItem extends StatusDisplayItem{
private final Attachment attachment;
public FileStatusDisplayItem(String parentID, BaseStatusListFragment<?> parentFragment, Attachment attachment) {
super(parentID, parentFragment);
this.attachment=attachment;
}
@Override
public Type getType() {
return Type.FILE;
}
public static class Holder extends StatusDisplayItem.Holder<FileStatusDisplayItem> {
private final TextView title, domain;
public Holder(Context context, ViewGroup parent) {
super(context, R.layout.display_item_file, parent);
title=findViewById(R.id.title);
domain=findViewById(R.id.domain);
findViewById(R.id.inner).setOnClickListener(this::onClick);
}
@Override
public void onBind(FileStatusDisplayItem item) {
Uri url = Uri.parse(getUrl());
title.setText(item.attachment.description != null
? item.attachment.description
: url.getLastPathSegment());
title.setEllipsize(item.attachment.description != null ? TextUtils.TruncateAt.END : TextUtils.TruncateAt.MIDDLE);
domain.setText(url.getHost());
}
private void onClick(View v) {
UiUtils.openURL(itemView.getContext(), item.parentFragment.getAccountID(), getUrl());
}
private String getUrl() {
return item.attachment.remoteUrl == null ? item.attachment.url : item.attachment.remoteUrl;
}
}
}

View File

@@ -1,7 +1,9 @@
package org.joinmastodon.android.ui.displayitems;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import org.joinmastodon.android.R;
@@ -25,6 +27,13 @@ public class HashtagStatusDisplayItem extends StatusDisplayItem{
public static class Holder extends StatusDisplayItem.Holder<HashtagStatusDisplayItem>{
private final TextView title, subtitle;
private final HashtagChartView chart;
public static final RelativeLayout.LayoutParams
withHistoryParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT),
withoutHistoryParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
static {
withoutHistoryParams.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
}
public Holder(Context context, ViewGroup parent){
super(context, R.layout.item_trending_hashtag, parent);
@@ -37,6 +46,14 @@ public class HashtagStatusDisplayItem extends StatusDisplayItem{
public void onBind(HashtagStatusDisplayItem _item){
Hashtag item=_item.tag;
title.setText('#'+item.name);
if (item.history == null || item.history.isEmpty()) {
subtitle.setText(null);
chart.setVisibility(View.GONE);
title.setLayoutParams(withoutHistoryParams);
return;
}
chart.setVisibility(View.VISIBLE);
title.setLayoutParams(withHistoryParams);
int numPeople=item.history.get(0).accounts;
if(item.history.size()>1)
numPeople+=item.history.get(1).accounts;

View File

@@ -7,6 +7,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.view.View;
@@ -17,7 +18,6 @@ import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.R;
import org.joinmastodon.android.fragments.BaseStatusListFragment;
import org.joinmastodon.android.model.Attachment;
@@ -40,7 +40,7 @@ import me.grishka.appkit.utils.CubicBezierInterpolator;
public class MediaGridStatusDisplayItem extends StatusDisplayItem{
private static final String TAG="MediaGridDisplayItem";
private final PhotoLayoutHelper.TiledLayoutResult tiledLayout;
private PhotoLayoutHelper.TiledLayoutResult tiledLayout;
private final TypedObjectPool<GridItemType, MediaAttachmentViewController> viewPool;
private final List<Attachment> attachments;
private final ArrayList<ImageLoaderRequest> requests=new ArrayList<>();
@@ -98,6 +98,8 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
private int altTextIndex=-1;
private Animator altTextAnimator;
private boolean sizeUpdating = false;
public Holder(Activity activity, ViewGroup parent){
super(new FrameLayoutThatOnlyMeasuresFirstChild(activity));
wrapper=(FrameLayout)itemView;
@@ -126,6 +128,7 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
}
layout.removeAllViews();
controllers.clear();
int i=0;
for(Attachment att:item.attachments){
MediaAttachmentViewController c=item.viewPool.obtain(switch(att.type){
@@ -158,6 +161,19 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
@Override
public void setImage(int index, Drawable drawable){
Rect bounds=drawable.getBounds();
drawable.setBounds(bounds.left, bounds.top, bounds.left+drawable.getIntrinsicWidth(), bounds.top+drawable.getIntrinsicHeight());
if(item.attachments.get(index).meta==null){
Attachment.Metadata metadata = new Attachment.Metadata();
metadata.width=drawable.getIntrinsicWidth();
metadata.height=drawable.getIntrinsicHeight();
item.attachments.get(index).meta=metadata;
item.tiledLayout=PhotoLayoutHelper.processThumbs(item.attachments);
sizeUpdating = true;
item.parentFragment.onImageUpdated(this, index);
}
controllers.get(index).setImage(drawable);
}
@@ -314,5 +330,13 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
layout.setClipChildren(clip);
wrapper.setClipChildren(clip);
}
public boolean isSizeUpdating() {
return sizeUpdating;
}
public void sizeUpdated() {
sizeUpdating = false;
}
}
}

View File

@@ -2,6 +2,7 @@ package org.joinmastodon.android.ui.displayitems;
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
@@ -9,6 +10,7 @@ import android.view.ViewGroup;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.session.AccountSession;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.fragments.BaseStatusListFragment;
import org.joinmastodon.android.fragments.HashtagTimelineFragment;
@@ -20,12 +22,14 @@ import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.Attachment;
import org.joinmastodon.android.model.DisplayItemsParent;
import org.joinmastodon.android.model.Filter;
import org.joinmastodon.android.model.Instance;
import org.joinmastodon.android.model.Notification;
import org.joinmastodon.android.model.Poll;
import org.joinmastodon.android.model.ScheduledStatus;
import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.ui.PhotoLayoutHelper;
import org.joinmastodon.android.ui.text.HtmlParser;
import org.joinmastodon.android.ui.utils.UiUtils;
import org.joinmastodon.android.utils.StatusFilterPredicate;
import org.parceler.Parcels;
@@ -78,6 +82,7 @@ public abstract class StatusDisplayItem{
case EXTENDED_FOOTER -> new ExtendedFooterStatusDisplayItem.Holder(activity, parent);
case MEDIA_GRID -> new MediaGridStatusDisplayItem.Holder(activity, parent);
case WARNING -> new WarningFilteredStatusDisplayItem.Holder(activity, parent);
case FILE -> new FileStatusDisplayItem.Holder(activity, parent);
};
}
@@ -94,10 +99,6 @@ public abstract class StatusDisplayItem{
args.putString("account", accountID);
ScheduledStatus scheduledStatus = parentObject instanceof ScheduledStatus ? (ScheduledStatus) parentObject : null;
if (!statusForContent.filterRevealed) {
statusForContent.filterRevealed = new StatusFilterPredicate(accountID, filterContext, Filter.FilterAction.WARN).test(status);
}
ReblogOrReplyLineStatusDisplayItem replyLine = null;
boolean threadReply = statusForContent.inReplyToAccountId != null &&
statusForContent.inReplyToAccountId.equals(statusForContent.account.id);
@@ -165,14 +166,32 @@ public abstract class StatusDisplayItem{
items.add(replyLine);
}
if (statusForContent.quote != null) {
boolean hasQuoteInlineTag = statusForContent.content.contains("<span class=\"quote-inline\">");
if (!hasQuoteInlineTag) {
String quoteUrl = statusForContent.quote.url;
String quoteInline = String.format("<span class=\"quote-inline\">%sRE: <a href=\"%s\">%s</a></span>",
statusForContent.content.endsWith("</p>") ? "" : "<br/><br/>", quoteUrl, quoteUrl);
statusForContent.content += quoteInline;
}
}
if(!TextUtils.isEmpty(statusForContent.content))
items.add(new TextStatusDisplayItem(parentID, HtmlParser.parse(statusForContent.content, statusForContent.emojis, statusForContent.mentions, statusForContent.tags, accountID), fragment, statusForContent, disableTranslate));
else if (!GlobalUserPreferences.replyLineAboveHeader && replyLine != null)
replyLine.needBottomPadding=true;
else
header.needBottomPadding=true;
List<Attachment> imageAttachments=statusForContent.mediaAttachments.stream().filter(att->att.type.isImage()).collect(Collectors.toList());
List<Attachment> imageAttachments=statusForContent.mediaAttachments.stream()
.filter(att->att.type.isImage() && !att.type.equals(Attachment.Type.UNKNOWN))
.collect(Collectors.toList());
if(!imageAttachments.isEmpty()){
int color = UiUtils.getThemeColor(fragment.getContext(), R.attr.colorAccentLightest);
for (Attachment att : imageAttachments) {
if (att.blurhashPlaceholder == null) {
att.blurhashPlaceholder = new ColorDrawable(color);
}
}
PhotoLayoutHelper.TiledLayoutResult layout=PhotoLayoutHelper.processThumbs(imageAttachments);
items.add(new MediaGridStatusDisplayItem(parentID, fragment, layout, imageAttachments, statusForContent));
}
@@ -181,6 +200,12 @@ public abstract class StatusDisplayItem{
items.add(new AudioStatusDisplayItem(parentID, fragment, statusForContent, att));
}
}
statusForContent.mediaAttachments.stream()
.filter(att->att.type.equals(Attachment.Type.UNKNOWN))
.map(att -> new FileStatusDisplayItem(parentID, fragment, att))
.forEach(items::add);
if(statusForContent.poll!=null){
buildPollItems(parentID, fragment, statusForContent.poll, items);
}
@@ -196,8 +221,15 @@ public abstract class StatusDisplayItem{
item.index=i++;
}
Filter applyingFilter = null;
if (!statusForContent.filterRevealed) {
StatusFilterPredicate predicate = new StatusFilterPredicate(accountID, filterContext, Filter.FilterAction.WARN);
statusForContent.filterRevealed = predicate.test(status);
applyingFilter = predicate.getApplyingFilter();
}
ArrayList<StatusDisplayItem> result = statusForContent.filterRevealed ? items :
new ArrayList<>(List.of(new WarningFilteredStatusDisplayItem(parentID, fragment, statusForContent, items)));
new ArrayList<>(List.of(new WarningFilteredStatusDisplayItem(parentID, fragment, statusForContent, items, applyingFilter)));
if (addFooter && status.hasGapAfter && !(fragment instanceof ThreadFragment)) {
StatusDisplayItem gap = new GapStatusDisplayItem(parentID, fragment);
@@ -230,7 +262,8 @@ public abstract class StatusDisplayItem{
GAP,
EXTENDED_FOOTER,
MEDIA_GRID,
WARNING
WARNING,
FILE
}
public static abstract class Holder<T extends StatusDisplayItem> extends BindableViewHolder<T> implements UsableRecyclerView.DisableableClickable{

View File

@@ -65,6 +65,7 @@ public class TextStatusDisplayItem extends StatusDisplayItem{
spoilerEmojiHelper.setText(parsedSpoilerText);
}
session = AccountSessionManager.getInstance().getAccount(parentFragment.getAccountID());
UiUtils.loadMaxWidth(parentFragment.getContext());
}
public void setTranslationShown(boolean translationShown) {
@@ -241,8 +242,19 @@ public class TextStatusDisplayItem extends StatusDisplayItem{
readMore.setVisibility(View.GONE);
}
// incredibly ugly workaround for https://github.com/sk22/megalodon/issues/520
// i am so, so sorry. FIXME
// attempts to use OnPreDrawListener, OnGlobalLayoutListener and .post have failed -
// the view didn't want to reliably update after calling .setVisibility etc :(
int width = parent.getWidth() != 0 ? parent.getWidth()
: item.parentFragment.getView().getWidth() != 0
? item.parentFragment.getView().getWidth()
: item.parentFragment.getParentFragment() != null && item.parentFragment.getParentFragment().getView().getWidth() != 0
? item.parentFragment.getParentFragment().getView().getWidth() // YIKES
: UiUtils.MAX_WIDTH;
text.measure(
View.MeasureSpec.makeMeasureSpec(parent.getWidth(), View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
if (GlobalUserPreferences.collapseLongPosts && !item.status.textExpandable) {

View File

@@ -7,6 +7,7 @@ import android.widget.TextView;
import org.joinmastodon.android.R;
import org.joinmastodon.android.fragments.BaseStatusListFragment;
import org.joinmastodon.android.model.Filter;
import org.joinmastodon.android.model.Status;
import java.util.List;
@@ -15,11 +16,13 @@ public class WarningFilteredStatusDisplayItem extends StatusDisplayItem{
public boolean loading;
public final Status status;
public List<StatusDisplayItem> filteredItems;
public Filter applyingFilter;
public WarningFilteredStatusDisplayItem(String parentID, BaseStatusListFragment<?> parentFragment, Status status, List<StatusDisplayItem> filteredItems){
public WarningFilteredStatusDisplayItem(String parentID, BaseStatusListFragment<?> parentFragment, Status status, List<StatusDisplayItem> filteredItems, Filter applyingFilter){
super(parentID, parentFragment);
this.status=status;
this.filteredItems = filteredItems;
this.applyingFilter = applyingFilter;
}
@Override
@@ -41,7 +44,7 @@ public class WarningFilteredStatusDisplayItem extends StatusDisplayItem{
@Override
public void onBind(WarningFilteredStatusDisplayItem item) {
filteredItems = item.filteredItems;
text.setText(item.parentFragment.getString(R.string.sk_filtered, item.status.filtered.get(item.status.filtered.size() -1).filter.title));
text.setText(item.parentFragment.getString(R.string.sk_filtered, item.applyingFilter.title));
}
@Override

View File

@@ -38,6 +38,7 @@ public class DiscoverInfoBannerHelper{
case LOCAL_TIMELINE -> R.string.local_timeline_info_banner;
case FEDERATED_TIMELINE -> R.string.sk_federated_timeline_info_banner;
case POST_NOTIFICATIONS -> R.string.sk_notify_posts_info_banner;
case BUBBLE_TIMELINE -> R.string.sk_bubble_timeline_info_banner;
});
}
}
@@ -63,6 +64,7 @@ public class DiscoverInfoBannerHelper{
LOCAL_TIMELINE,
FEDERATED_TIMELINE,
POST_NOTIFICATIONS,
// ACCOUNTS
// ACCOUNTS,
BUBBLE_TIMELINE
}
}

View File

@@ -99,6 +99,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
@@ -633,9 +634,9 @@ public class UiUtils {
if (relationship.blocking) {
button.setText(R.string.button_blocked);
secondaryStyle = true;
} else if (relationship.blockedBy) {
button.setText(R.string.button_follow);
secondaryStyle = false;
// } else if (relationship.blockedBy) {
// button.setText(R.string.button_follow);
// secondaryStyle = false;
} else if (relationship.requested) {
button.setText(R.string.button_follow_pending);
secondaryStyle = true;
@@ -649,7 +650,8 @@ public class UiUtils {
if (keepText) button.setText(textBefore);
button.setEnabled(!relationship.blockedBy);
// https://github.com/sk22/megalodon/issues/526
// button.setEnabled(!relationship.blockedBy);
int attr = secondaryStyle ? R.attr.secondaryButtonStyle : android.R.attr.buttonStyle;
TypedArray ta = button.getContext().obtainStyledAttributes(new int[]{attr});
int styleRes = ta.getResourceId(0, 0);
@@ -946,7 +948,7 @@ public class UiUtils {
public static String getInstanceName(String accountID) {
AccountSession session = AccountSessionManager.getInstance().getAccount(accountID);
Instance instance = AccountSessionManager.getInstance().getInstanceInfo(session.domain);
Instance instance = session.getInstance();
return instance != null && !instance.title.isBlank() ? instance.title : session.domain;
}
@@ -1112,14 +1114,20 @@ public class UiUtils {
if (!results.statuses.isEmpty()) {
args.putParcelable("status", Parcels.wrap(results.statuses.get(0)));
Nav.go((Activity) context, ThreadFragment.class, args);
} else if (!results.accounts.isEmpty()) {
args.putParcelable("profileAccount", Parcels.wrap(results.accounts.get(0)));
Nav.go((Activity) context, ProfileFragment.class, args);
} else {
if (launchBrowser) launchWebBrowser(context, url);
else
Toast.makeText(context, R.string.sk_resource_not_found, Toast.LENGTH_SHORT).show();
return;
}
Optional<Account> account = results.accounts.stream()
.filter(a -> uri.equals(Uri.parse(a.url))).findAny();
if (account.isPresent()) {
args.putParcelable("profileAccount", Parcels.wrap(account.get()));
Nav.go((Activity) context, ProfileFragment.class, args);
return;
}
if (launchBrowser) {
launchWebBrowser(context, url);
return;
}
Toast.makeText(context, R.string.sk_resource_not_found, Toast.LENGTH_SHORT).show();
}
@Override

View File

@@ -6,6 +6,7 @@ import org.joinmastodon.android.model.Status;
import java.time.Instant;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -14,11 +15,32 @@ public class StatusFilterPredicate implements Predicate<Status>{
private final List<Filter> filters;
private final Filter.FilterContext context;
private final Filter.FilterAction action;
private Filter applyingFilter;
/**
* @param context null makes the predicate pass automatically
* @param action defines what the predicate should check:
* status should not be hidden or should not display with warning
*/
public StatusFilterPredicate(List<Filter> filters, Filter.FilterContext context, Filter.FilterAction action){
this.filters = filters;
this.context = context;
this.action = action;
}
public StatusFilterPredicate(List<Filter> filters, Filter.FilterContext context){
this.filters=filters;
this(filters, context, Filter.FilterAction.HIDE);
}
/**
* @param context null makes the predicate pass automatically
* @param action defines what the predicate should check:
* status should not be hidden or should not display with warning
*/
public StatusFilterPredicate(String accountID, Filter.FilterContext context, Filter.FilterAction action){
filters=AccountSessionManager.getInstance().getAccount(accountID).wordFilters.stream().filter(f->f.context.contains(context)).collect(Collectors.toList());
this.context = context;
this.action = Filter.FilterAction.HIDE;
this.action = action;
}
/**
@@ -29,32 +51,35 @@ public class StatusFilterPredicate implements Predicate<Status>{
}
/**
* @param context null makes the predicate pass automatically
* @param action defines what the predicate should check:
* should not be hidden or should not display with warning
* @return whether the status should be displayed without being hidden/warned about.
* will always return true if the context is null.
* true = display this status,
* false = filter this status
*/
public StatusFilterPredicate(String accountID, Filter.FilterContext context, Filter.FilterAction action){
filters=AccountSessionManager.getInstance().getAccount(accountID).wordFilters.stream().filter(f->f.context.contains(context)).collect(Collectors.toList());
this.context = context;
this.action = action;
}
@Override
public boolean test(Status status){
if (context == null) return true;
Stream<Filter> stream = status.filtered != null
Stream<Filter> matchingFilters = status.filtered != null
// use server-provided per-status info (status.filtered) if available
? status.filtered.stream().map(f -> f.filter)
// or fall back to cached filters
: filters.stream().filter(filter -> filter.matches(status));
return stream
Optional<Filter> applyingFilter = matchingFilters
// discard expired filters
.filter(filter -> filter.expiresAt == null || filter.expiresAt.isAfter(Instant.now()))
// only apply filters for given context
.filter(filter -> filter.context.contains(context))
// treating filterAction = null (from filters list) as FilterAction.HIDE
.noneMatch(filter -> filter.filterAction == null ? action == Filter.FilterAction.HIDE : filter.filterAction == action);
.filter(filter -> filter.filterAction == null ? action == Filter.FilterAction.HIDE : filter.filterAction == action)
.findAny();
this.applyingFilter = applyingFilter.orElse(null);
return applyingFilter.isEmpty();
}
public Filter getApplyingFilter() {
return applyingFilter;
}
}

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?android:attr/colorControlHighlight">
<item android:drawable="@drawable/bg_search_field" />
</ripple>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M11.772,3.744C14.114,1.4 17.913,1.4 20.256,3.744C22.539,6.027 22.597,9.692 20.431,12.046L20.243,12.243L11.443,21.041L11.407,21.072C9.945,22.388 7.691,22.344 6.284,20.936C4.965,19.617 4.843,17.555 5.918,16.098C5.941,16.052 5.969,16.009 6.002,15.968L6.056,15.908L6.143,15.82L6.284,15.672L6.287,15.675L13.723,8.221C13.989,7.954 14.405,7.93 14.699,8.147L14.783,8.22C15.05,8.485 15.075,8.902 14.857,9.196L14.785,9.28L7.19,16.893C6.473,17.769 6.522,19.063 7.34,19.881C8.169,20.71 9.488,20.749 10.364,19.999L19.197,11.168C20.952,9.411 20.952,6.562 19.195,4.804C17.493,3.102 14.766,3.049 12.999,4.645L12.831,4.804L12.819,4.819L3.282,14.355C2.989,14.648 2.515,14.648 2.222,14.355C1.955,14.089 1.931,13.672 2.149,13.378L2.222,13.294L11.771,3.744L11.772,3.744Z"
android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@@ -0,0 +1,59 @@
<?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">
<org.joinmastodon.android.ui.views.MaxWidthFrameLayout
android:id="@+id/inner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:maxWidth="@dimen/layout_max_width">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginVertical="4dp"
android:background="@drawable/bg_search_button"
android:paddingVertical="12dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="18dp"
android:importantForAccessibility="no"
android:src="@drawable/ic_fluent_attach_24_regular" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingHorizontal="16dp"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/m3_body_large"
android:singleLine="true"
android:ellipsize="middle"
tools:text="07a9d88625a9d63d680f35baf040156e71ed87e5f068f14d332c0c5a83f7a939.webm"/>
<TextView
android:id="@+id/domain"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/m3_body_medium"
android:textColor="?android:textColorSecondary"
tools:text="example.com"/>
</LinearLayout>
</LinearLayout>
</org.joinmastodon.android.ui.views.MaxWidthFrameLayout>
</FrameLayout>

View File

@@ -29,10 +29,10 @@
<TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="24sp"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/avatar"
android:layout_toStartOf="@id/button"
android:layout_marginTop="2sp"
android:layout_above="@+id/username"
android:singleLine="true"
android:ellipsize="end"
android:gravity="center_vertical"
@@ -40,16 +40,16 @@
tools:text="User"/>
<TextView
android:id="@+id/username"
android:id="@id/username"
android:layout_width="match_parent"
android:layout_height="20sp"
android:layout_below="@id/name"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/avatar"
android:layout_toStartOf="@id/button"
android:layout_alignBottom="@id/avatar"
android:singleLine="true"
android:ellipsize="end"
android:gravity="center_vertical"
android:textAppearance="@style/m3_title_small"
android:paddingBottom="3sp"
tools:text="\@user@server"/>
<View

View File

@@ -8,7 +8,7 @@
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_search_field">
android:background="@drawable/bg_search_button">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"

View File

@@ -33,6 +33,7 @@
android:textColor="?android:textColorSecondary" />
<ImageView
android:id="@+id/icon"
android:importantForAccessibility="no"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>

View File

@@ -465,21 +465,7 @@
<string name="privacy_policy_subtitle">على الرغم من أن تطبيق ماستدون لا يجمع أي بيانات، فإن الخادم الذي قمت بالتسجيل من خلاله قد تكون له سياسة مختلفة. خذ دقيقة للمراجعة والموافقة على سياسة خصوصية التطبيق ماستدون وسياسة الخصوصية للخادم الخاص بك.</string>
<string name="i_agree">أنا مُوافِق</string>
<string name="empty_list">هذه القائمة فارغة</string>
<string name="confirm_delete_and_redraft">هل أنت متأكد أنك تريد حذف وإعادة صياغة هذا المنشور؟</string>
<string name="visibility_unlisted">غير مدرج</string>
<string name="list_timelines">القوائم</string>
<string name="follow_requests">طلبات المتابعة</string>
<string name="instance_signup_closed">هذا الخادم لا يقبل تسجيلات جديدة.</string>
<string name="pinned_posts">مدبّس</string>
<string name="delete_and_redraft">حذف وإعادة الصياغة</string>
<string name="confirm_delete_and_redraft_title">حذف وإعادة صياغة الرسالة</string>
<string name="pin_post">تدبيس على الصفحة الشخصية</string>
<string name="confirm_pin_post_title">تدبيس الرسالة على الصفحة الشخصية</string>
<string name="settings_show_federated_timeline">إظهار الخيط الفديرالي</string>
<string name="settings_contribute_fork">المساهمة في Megalodon</string>
<string name="accept_follow_request">قبول طلب المتابعة</string>
<string name="reject_follow_request">رفض طلب المتابعة</string>
<string name="lists_with_user">قوائم بها %s</string>
<string name="text_copied">تم النسخ إلى الحافظة</string>
<string name="add_bookmark">إضافة إلى الفواصل المرجعية</string>
<string name="remove_bookmark">إزالة من الفواصل المرجعية</string>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="sk_confirm_delete_and_redraft">هل أنت متأكد أنك تريد حذف وإعادة صياغة هذا المنشور؟</string>
<string name="sk_visibility_unlisted">غير مدرج</string>
<string name="sk_list_timelines">القوائم</string>
<string name="sk_follow_requests">طلبات المتابعة</string>
<string name="sk_pinned_posts">مدبّس</string>
<string name="sk_delete_and_redraft">حذف وإعادة الصياغة</string>
<string name="sk_confirm_delete_and_redraft_title">حذف وإعادة صياغة الرسالة</string>
<string name="sk_pin_post">تدبيس على الصفحة الشخصية</string>
<string name="sk_confirm_pin_post_title">تدبيس الرسالة على الصفحة الشخصية</string>
<string name="sk_settings_show_federated_timeline">إظهار الخيط الفديرالي</string>
<string name="sk_settings_contribute">المساهمة في Megalodon</string>
<string name="sk_accept_follow_request">قبول طلب المتابعة</string>
<string name="sk_reject_follow_request">رفض طلب المتابعة</string>
<string name="sk_lists_with_user">قوائم بها %s</string>
</resources>

View File

@@ -83,8 +83,8 @@
<string name="sk_settings_translation_availability_note_unavailable">%s no parece admitir la traducción.</string>
<string name="sk_loading_fediverse_resource_title">Buscándolo en el Fediverso</string>
<string name="sk_quote_post">Publicar sobre esto</string>
<string name="sk_undo_reblog">Deshacer reblogueo</string>
<string name="sk_reblog_with_visibility">Rebloguea con visibilidad</string>
<string name="sk_undo_reblog">Deshacer compartir</string>
<string name="sk_reblog_with_visibility">Comparte con visibilidad</string>
<string name="sk_hashtags_you_follow">Etiquetas que sigues</string>
<string name="sk_copy_link_to_post">Copiar enlace de la publicación</string>
<string name="sk_open_with_account">Abrir con otra cuenta</string>
@@ -94,9 +94,9 @@
<string name="sk_already_bookmarked">Ya en marcadores</string>
<string name="sk_favorited_as">Marcado favorito como %s</string>
<string name="sk_already_favorited">Ya es un favorito</string>
<string name="sk_reblog_as">Impulsar con otra cuenta</string>
<string name="sk_reblogged_as">Impulsado como %s</string>
<string name="sk_already_reblogged">Ya se había impulsado</string>
<string name="sk_reblog_as">Compartir con otra cuenta</string>
<string name="sk_reblogged_as">Compartido como %s</string>
<string name="sk_already_reblogged">Ya impulsado</string>
<string name="sk_reply_as">Responder con otra cuenta</string>
<string name="sk_bookmark_as">Añadir a marcadores con otra cuenta</string>
<string name="sk_favorite_as">Marcar favorito con otra cuenta</string>
@@ -214,7 +214,7 @@
<string name="sk_alt_button">ALT</string>
<string name="sk_post_edited">editado</string>
<string name="sk_notification_type_update">Publicaciones editadas</string>
<string name="sk_notify_update">Editó una publicación impulsada</string>
<string name="sk_notify_update">editado una publicación compartida</string>
<string name="sk_searching">Buscando…</string>
<string name="sk_no_results">Sin resultados</string>
<string name="sk_save_draft">¿Guardar el borrador\?</string>
@@ -271,6 +271,19 @@
<string name="sk_notification_action_replied">Respuesta enviada a %s</string>
<string name="sk_reply_line_above_avatar">\"En respuesta a\" línea sobre el avatar</string>
<string name="sk_show_thread">Mostrar hilo</string>
<string name="sk_compact_reblog_reply_line">Línea compacta de reblog/respuesta</string>
<string name="sk_compact_reblog_reply_line">Línea compacta compartida/respondida</string>
<string name="sk_settings_confirm_before_reblog">Confirmar antes de volver a publicar</string>
<string name="sk_reacted_with">reaccionó con %s</string>
<string name="sk_reacted">reaccionó</string>
<string name="sk_content_type">Tipo del contenido</string>
<string name="sk_content_type_unspecified">Sin especificar</string>
<string name="sk_content_type_plain">Texto sin formato</string>
<string name="sk_content_type_html">HTML</string>
<string name="sk_content_type_markdown">Markdown</string>
<string name="sk_content_type_bbcode">BBCode</string>
<string name="sk_content_type_mfm">MFM</string>
<string name="sk_settings_content_types">Habilitar el formato de los mensajes</string>
<string name="sk_settings_default_content_type">Contenido por defecto</string>
<string name="sk_settings_content_types_explanation">Permite establecer un tipo de contenido como Markdown al crear una entrada. Ten en cuenta que no todas las instancias lo admiten.</string>
<string name="sk_settings_default_content_type_explanation">Permite preseleccionar un tipo de contenido al crear nuevas entradas, anulando el valor establecido en \"Preferencias de publicación\".</string>
</resources>

View File

@@ -274,4 +274,17 @@
<string name="sk_compact_reblog_reply_line">Ligne boost/réponse compacte</string>
<string name="sk_reply_line_above_avatar">Ligne \"En réponse à\" au-dessus de l\'avatar</string>
<string name="sk_settings_confirm_before_reblog">Confirmer avant de booster</string>
<string name="sk_reacted">a réagi</string>
<string name="sk_reacted_with">a réagi avec %s</string>
<string name="sk_content_type">Type de contenu</string>
<string name="sk_content_type_plain">Texte brut</string>
<string name="sk_content_type_html">HTML</string>
<string name="sk_content_type_markdown">Markdown</string>
<string name="sk_content_type_bbcode">BBCode</string>
<string name="sk_content_type_mfm">MFM</string>
<string name="sk_settings_content_types">Activer la mise en forme du message</string>
<string name="sk_settings_default_content_type_explanation">Cela vous permet de présélectionner un type de contenu lors de la création de nouveaux messages, en remplaçant la valeur définie dans \"Préférences de publication\".</string>
<string name="sk_content_type_unspecified">Non spécifié</string>
<string name="sk_settings_content_types_explanation">Permet de définir un type de contenu comme Markdown lors de la création d\'un message. Gardez à l\'esprit que toutes les instances ne le prennent pas en charge.</string>
<string name="sk_settings_default_content_type">Type de contenu par défaut</string>
</resources>

View File

@@ -273,4 +273,6 @@
<string name="sk_show_thread">Mostrar chío</string>
<string name="sk_compact_reblog_reply_line">Compactar liña de impulso/resposta</string>
<string name="sk_settings_confirm_before_reblog">Confirma antes de impulsar</string>
<string name="sk_reacted_with">Redactado con %s</string>
<string name="sk_reacted">redactado</string>
</resources>

View File

@@ -101,6 +101,8 @@
<string name="confirm_block_domain_title">Արգելափակել տիրույթը</string>
<string name="confirm_block">Հաստատեք %s-ի արգելափակումը</string>
<string name="do_block">Արգելափակել</string>
<string name="do_unblock">Արգելաբացել</string>
<string name="button_blocked">Արգելափակված</string>
<string name="action_vote">Քվեարկել</string>
<string name="tap_to_reveal">Սեղմեք տեսնելու համար</string>
<string name="delete">Ջնջել</string>
@@ -118,7 +120,9 @@
<string name="mentions">Նշումներ</string>
<string name="report_title">Զեկուցել %s-ի մասին</string>
<string name="report_reason_personal">Ինձ դուր չի գալիս</string>
<string name="report_reason_personal_subtitle">Դուք սա չեք ուզում տեսնել</string>
<string name="report_reason_spam">Սպամ է</string>
<string name="report_reason_spam_subtitle">Վնասակար հղումներ, կեղծում կամ կրկնվող պատասխաններ</string>
<string name="report_reason_violation">Խախտում է սերվերի կանոնները</string>
<string name="report_reason_violation_subtitle">Գիտեք, որ այն խախտում է կանոնները</string>
<string name="report_reason_other">Այլ բան է</string>
@@ -157,6 +161,10 @@
<string name="add_image_description">Ավելացնել պատկերի նկարագրություն</string>
<string name="edit_image">Խմբագրել նկարը</string>
<string name="save">Պահպանել</string>
<string name="alt_text_hint">օր․՝ շունը նեղ աչքերով կասկածելի նայում է տեսախցիկին</string>
<string name="visibility_public">Հրապարակային</string>
<string name="visibility_followers_only">Միայն հետեւողներին</string>
<string name="visibility_private">Միայն նշածս մարդկանց</string>
<string name="search_all">Բոլորը</string>
<string name="search_people">Մարդիկ</string>
<string name="recent_searches">Վերջին որոնումներ</string>
@@ -226,6 +234,7 @@
<string name="dismiss">Չեղարկել</string>
<string name="see_new_posts">Նոր գրառումներ</string>
<string name="follows_you">Հետեւում է ձեզ</string>
<string name="current_account">Ընթացիկ հաշիվ</string>
<!-- translators: %,d is a valid placeholder, it formats the number with locale-dependent grouping separators -->
<plurals name="x_followers">
<item quantity="one">%,d հետեւորդ</item>
@@ -241,13 +250,32 @@
</plurals>
<string name="timestamp_via_app">%1$s %2$s-ի միջոցով</string>
<string name="time_now">նոր</string>
<string name="post_info_reblogs">Տարածումներ</string>
<string name="post_info_favorites">Հավանումներ</string>
<string name="edit_history">Խմբագրել պատմությունը</string>
<string name="last_edit_at_x">Վերջին խմբագրում՝ %s</string>
<string name="time_just_now">հենց նոր</string>
<plurals name="x_seconds_ago">
<item quantity="one">%d վայրկյան առաջ</item>
<item quantity="other">%d վայրկյան առաջ</item>
</plurals>
<plurals name="x_minutes_ago">
<item quantity="one">%d րոպե առաջ</item>
<item quantity="other">%d րոպե առաջ</item>
</plurals>
<string name="edit_text_edited">Տեքստը փոփոխվել է</string>
<string name="edit_poll_added">Հարցումն ավելացել է</string>
<string name="edit_poll_edited">Հարցումը խմբագրվել է</string>
<string name="edit_poll_removed">Հարցումը հեռացվել է</string>
<string name="edit_media_added">Մեդիան ավելացվել է</string>
<string name="edit_media_removed">Մեդիան հեռացվել է</string>
<string name="edit_marked_sensitive">Նշվել է որպես դյուրազգաց</string>
<string name="file_size_bytes">%d բայթ</string>
<string name="file_size_kb">%.2f ԿԲ</string>
<string name="file_size_mb">%.2f ՄԲ</string>
<string name="file_size_gb">%.2f ԳԲ</string>
<string name="file_upload_progress">%1$s՝ %2$s-ից</string>
<string name="file_upload_time_remaining">մնացել է %s</string>
<!-- %s is version like 1.2.3 -->
<string name="update_available">%s տարբերակը պատրաստ է ներբեռնման։</string>
<!-- %s is version like 1.2.3 -->
@@ -255,6 +283,7 @@
<!-- %s is file size -->
<string name="download_update">Ներբեռնել (%s)</string>
<string name="install_update">Տեղադրել</string>
<string name="privacy_policy_title">Ձեր գաղտնիությունը</string>
<string name="i_agree">Համաձայն եմ</string>
<string name="empty_list">Ցանկը դատարկ է</string>
<string name="instance_signup_closed">Սպասարկիչը գրանցումներ չի ընդունում։</string>
@@ -274,9 +303,25 @@
<string name="not_accepting_new_members">Չի ընդունում նոր անդամներ</string>
<string name="signup_passwords_dont_match">Գաղտնաբառը չի համապատասխանում</string>
<string name="pick_server_for_me">Ընտրել իմ համար</string>
<string name="privacy_policy_explanation">Կարճ ասած՝ մենք ոչինչ չենք հավաքում։</string>
<!-- %s is server domain -->
<string name="profile_bio">Կենսագրություն</string>
<!-- Shown in a progress dialog when you tap "follow all" -->
<!-- %1$s is server domain, %2$s is email domain. You can reorder these placeholders to fit your language better. -->
<string name="signup_email_domain_blocked">%1$s-ը %2$s-ից գրանցումներ չի ընդունում։ Փորձեք ուրիշը կամ &lt;a&gt;ընտրեք ուրիշ սերվեր&lt;/a&gt;։</string>
<string name="signup_username_taken">Օգտանունը զբաղված է։</string>
<string name="spoiler_show">Ցույց տալ</string>
<string name="spoiler_hide">Թաքցնել</string>
<string name="save_changes">Պահպանել</string>
<string name="profile_timeline">Հոսք</string>
<string name="view_all">Դիտել բոլորը</string>
<string name="profile_endorsed_accounts">Հաշիվներ</string>
<string name="verified_link">Հաստատված հղում</string>
<string name="show">Ցույց տալ</string>
<string name="hide">Թաքցնել</string>
<string name="join_default_server">Միանալ %s-ին</string>
<string name="pick_server">Ընտրել ուրիշ սերվեր</string>
<string name="signup_or_login">կամ</string>
<string name="learn_more">Իմանալ ավելին</string>
<string name="welcome_to_mastodon">Բարի գալուստ Մաստոդոն</string>
<string name="welcome_paragraph1">Մաստոդոնը ապակենտրոնացված սոցցանց է, այսինքն՝ այն չի պատկանում մի ընկերության։ Այն բաղկացած է բազմաթիվ անկախ և կապակցված սերվերներից։</string>

View File

@@ -274,4 +274,17 @@
<string name="sk_show_thread">Tampilkan utasan</string>
<string name="sk_compact_reblog_reply_line">Baris berbagi/balasan</string>
<string name="sk_settings_confirm_before_reblog">Konfirmasi sebelum membagikan ulang</string>
<string name="sk_reacted_with">bereaksi dengan %s</string>
<string name="sk_reacted">bereaksi</string>
<string name="sk_content_type_plain">Teks biasa</string>
<string name="sk_content_type_html">HTML</string>
<string name="sk_content_type_markdown">Markdown</string>
<string name="sk_content_type_bbcode">BBCode</string>
<string name="sk_content_type_mfm">MFM</string>
<string name="sk_settings_content_types">Aktifkan pemformatan kiriman</string>
<string name="sk_settings_default_content_type">Jenis konten bawaan</string>
<string name="sk_settings_default_content_type_explanation">Ini memungkinkan Anda untuk menerapkan jenis konten yang sudah ditentukan saat membuat kiriman baru, menimpa nilai yang ditetapkan dalam “Preferensi kiriman”.</string>
<string name="sk_content_type">Jenis konten</string>
<string name="sk_content_type_unspecified">Tidak ditentukan</string>
<string name="sk_settings_content_types_explanation">Memperbolehkan menetapkan jenis konten seperti Markdown ketika membuat kiriman. Perlu diingat bahwa tidak semua server mendukung ini.</string>
</resources>

View File

@@ -67,8 +67,8 @@
<string name="sk_favorite_as">Aggiungi ai preferiti con un altro account</string>
<string name="sk_favorited_as">Inserito tra i preferiti come %s</string>
<string name="sk_already_favorited">Già aggiunto ai preferiti</string>
<string name="sk_reblog_as">Condividi con un altro account</string>
<string name="sk_already_reblogged">Già condiviso</string>
<string name="sk_reblog_as">Boost con un altro account</string>
<string name="sk_already_reblogged">Già boostato</string>
<string name="sk_settings_profile">Impostazioni del profilo</string>
<string name="sk_settings_posting">Preferenze di pubblicazione</string>
<string name="sk_settings_filters">Configura i filtri</string>
@@ -86,8 +86,8 @@
<string name="sk_clear_all_notifications_confirm">Sei sicuro di voler eliminare tutte le notifiche\?</string>
<string name="sk_loading_fediverse_resource_title">Cercando nel Fediverso</string>
<string name="sk_quote_post">Crea un post riguardo a questo</string>
<string name="sk_undo_reblog">Annulla la condivisione</string>
<string name="sk_reblog_with_visibility">Reblog con visibilità</string>
<string name="sk_undo_reblog">Annulla il boost</string>
<string name="sk_reblog_with_visibility">Boost con visibilità</string>
<string name="sk_copy_link_to_post">Copia il link al post</string>
<string name="sk_open_with_account">Apri con un altro account</string>
<string name="sk_resource_not_found">Non è stato possibile trovare la risorsa</string>
@@ -131,7 +131,7 @@
<string name="sk_loading_resource_on_instance_title">Cercando su %s</string>
<string name="sk_hashtags_you_follow">Hashtag che segui</string>
<string name="sk_already_bookmarked">Già aggiunto ai segnalibri</string>
<string name="sk_reblogged_as">Condivisione eseguita come %s</string>
<string name="sk_reblogged_as">Boost eseguito come %s</string>
<string name="sk_unsent_posts">Post non pubblicati</string>
<string name="sk_confirm_save_draft">Salvare la bozza\?</string>
<string name="sk_confirm_save_changes">Salvare le modifiche\?</string>
@@ -220,7 +220,7 @@
<string name="sk_icon_globe">Mappamondo</string>
<string name="sk_edit_timeline">Modifica timeline</string>
<string name="sk_edit_timelines">Modifica timeline</string>
<string name="sk_notify_update">Modifica un post condiviso</string>
<string name="sk_notify_update">Modifica un post boostato</string>
<string name="sk_notification_type_update">Post modificati</string>
<string name="sk_attach_file">Allega file</string>
<string name="sk_icon_pin">Puntina</string>
@@ -239,7 +239,7 @@
<string name="sk_separator">·</string>
<string name="sk_local_only">Solo istanza locale</string>
<string name="sk_instance_features">Funzionalità dell\'istanza</string>
<string name="sk_settings_support_local_only">Il server supporta solo post locali</string>
<string name="sk_settings_support_local_only">Il server supporta anche post solo locali</string>
<string name="sk_settings_local_only_explanation">La tua istanza deve supportare post solo locali per far funzionare questa opzione. Molte versioni modificate di Mastodon lo fanno, ma Mastodon no.</string>
<string name="sk_settings_glitch_instance">Modalità solo locale di Glitch</string>
<string name="sk_settings_glitch_mode_explanation">Abilita se la tua istanza utilizza Glitch. Non necessario per Hometown o Akkoma.</string>
@@ -261,4 +261,17 @@
<string name="sk_follow_as">Segui con un altro account</string>
<string name="sk_followed_as">Seguito con %s</string>
<string name="sk_settings_hide_fab">Nascondi automaticamente il pulsante Pubblica</string>
<string name="sk_in_reply">In risposta</string>
<string name="sk_quoting_user">Citando %s</string>
<string name="sk_settings_reply_visibility">Visibilità delle risposte</string>
<string name="sk_settings_reply_visibility_all">Tutte le risposte</string>
<string name="sk_settings_reply_visibility_following">Risposte ai miei follower</string>
<string name="sk_settings_reply_visibility_self">Mi risponde</string>
<string name="sk_notification_action_replied">Risposta inviata a %s</string>
<string name="sk_settings_confirm_before_reblog">Conferma prima del boost</string>
<string name="sk_reacted">ha reagito</string>
<string name="sk_show_thread">Mostra discussione</string>
<string name="sk_compact_reblog_reply_line">Linea boost/risposta compatta</string>
<string name="sk_reacted_with">ha reagito con %s</string>
<string name="sk_reply_line_above_avatar">Linea \"In risposta a\" sopra l\'avatar</string>
</resources>

View File

@@ -8,14 +8,14 @@
<string name="error">Fout</string>
<string name="not_a_mastodon_instance">%s lijkt geen Mastodonserver te zijn.</string>
<string name="ok">OK</string>
<string name="preparing_auth">Verificatie aan het voorbereiden…</string>
<string name="preparing_auth">Verificatie voorbereiden…</string>
<string name="finishing_auth">Verificatie afronden…</string>
<string name="user_boosted">%s boostte</string>
<string name="in_reply_to">Als reactie op %s</string>
<string name="notifications">Meldingen</string>
<string name="user_followed_you">volgt jou</string>
<string name="user_sent_follow_request">heeft je een volgverzoek gestuurd</string>
<string name="user_favorited">markeerde als favoriet</string>
<string name="user_sent_follow_request">wil jou graag volgen</string>
<string name="user_favorited">markeerde bericht als favoriet</string>
<string name="notification_boosted">boostte jouw bericht</string>
<string name="poll_ended">poll is beëindigd</string>
<string name="time_seconds">%ds</string>
@@ -47,20 +47,20 @@
<string name="button_follow">Volgen</string>
<string name="button_following">Volgend</string>
<string name="edit_profile">Profiel bewerken</string>
<string name="mention_user">Vermelden</string>
<string name="mention_user">%s vermelden</string>
<string name="share_user">%s delen</string>
<string name="mute_user">Negeren</string>
<string name="unmute_user">Niet langer negeren</string>
<string name="block_user">Blokkeren</string>
<string name="unblock_user">Deblokkeren</string>
<string name="mute_user">%s negeren</string>
<string name="unmute_user">%s niet langer negeren</string>
<string name="block_user">%s blokkeren</string>
<string name="unblock_user">%s deblokkeren</string>
<string name="report_user">%s rapporteren</string>
<string name="block_domain">Blokkeren</string>
<string name="unblock_domain">Deblokkeren</string>
<string name="block_domain">%s blokkeren</string>
<string name="unblock_domain">%s deblokkeren</string>
<plurals name="x_posts">
<item quantity="one">%,d bericht</item>
<item quantity="other">%,d berichten</item>
</plurals>
<string name="profile_joined">Geregistreerd op</string>
<string name="profile_joined">Geregistreerd</string>
<string name="done">Klaar</string>
<string name="loading">Aan het laden…</string>
<string name="field_label">Label</string>
@@ -98,23 +98,23 @@
<item quantity="other">%d dagen resterend</item>
</plurals>
<plurals name="x_voters">
<item quantity="one">%,d persoon</item>
<item quantity="other">%,d mensen</item>
<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">Bevestig om %s te negeren</string>
<string name="confirm_mute">Het negeren van %s bevestigen</string>
<string name="do_mute">Negeren</string>
<string name="confirm_unmute_title">Account niet langer negeren</string>
<string name="confirm_unmute">Bevestig om %s niet langer te negeren</string>
<string name="confirm_unmute">Het niet langer negeren van %s bevestigen</string>
<string name="do_unmute">Niet langer negeren</string>
<string name="confirm_block_title">Account blokkeren</string>
<string name="confirm_block_domain_title">Domein blokkeren</string>
<string name="confirm_block">Bevestig om %s te blokkeren</string>
<string name="confirm_block">Het blokkeren van %s bevestigen</string>
<string name="do_block">Blokkeren</string>
<string name="confirm_unblock_title">Account deblokkeren</string>
<string name="confirm_unblock_domain_title">Domein deblokkeren</string>
<string name="confirm_unblock">Bevestig om %s te deblokkeren</string>
<string name="confirm_unblock">Het deblokkeren van %s bevestigen</string>
<string name="do_unblock">Deblokkeren</string>
<string name="button_muted">Genegeerd</string>
<string name="button_blocked">Geblokkeerd</string>
@@ -175,7 +175,7 @@
<string name="instance_catalog_subtitle">Kies een server gebaseerd op je interesses, regio, of voor algemene doeleinden. Je kunt nog steeds met iedereen in contact komen, ongeacht de server.</string>
<string name="search_communities">Servernaam of URL</string>
<string name="instance_rules_title">Serverregels</string>
<string name="instance_rules_subtitle">Door verder te gaan, ga je akkoord met het volgen van de regels ingesteld door de %s-moderators.</string>
<string name="instance_rules_subtitle">Door verder te gaan, ga je akkoord met het volgen van de regels ingesteld door de %s-moderatoren.</string>
<string name="signup_title">Account registreren</string>
<string name="edit_photo">bewerken</string>
<string name="display_name">Naam</string>
@@ -193,14 +193,14 @@
<string name="category_games">Games</string>
<string name="category_general">Algemeen</string>
<string name="category_journalism">Journalistiek</string>
<string name="category_lgbt">LGBT</string>
<string name="category_lgbt">LHBTQIA+</string>
<string name="category_music">Muziek</string>
<string name="category_regional">Regionaal</string>
<string name="category_tech">Tech</string>
<string name="confirm_email_title">Controleer je Postvak In</string>
<!-- %s is the email address -->
<string name="confirm_email_subtitle">Klik op de link die we je hebben gestuurd om %s te verifiëren. We wachten op je.</string>
<string name="confirm_email_didnt_get">Geen link gekregen?</string>
<string name="confirm_email_didnt_get">Geen verificatielink ontvangen?</string>
<string name="resend">Opnieuw verzenden</string>
<string name="open_email_app">E-mail-app openen</string>
<string name="resent_email">Bevestigingsmail verzonden</string>
@@ -211,7 +211,7 @@
<string name="edit_image">Afbeelding bewerken</string>
<string name="save">Opslaan</string>
<string name="add_alt_text">Alt-tekst toevoegen</string>
<string name="alt_text_subtitle">Alt-tekst beschrijft uw foto\'s voor mensen met weinig of geen zicht. Probeer alleen genoeg details toe te voegen om de context te begrijpen.</string>
<string name="alt_text_subtitle">Alt-tekst beschrijft jouw foto\'s voor blinde of slechtziende mensen. Probeer alleen genoeg details toe te voegen om de context te begrijpen.</string>
<string name="alt_text_hint">bijv.: een hond die met versmalde ogen verdacht rondkijkt naar de camera.</string>
<string name="visibility_public">Openbaar</string>
<string name="visibility_followers_only">Alleen volgers</string>
@@ -240,17 +240,17 @@
<string name="theme_dark">Donker</string>
<string name="theme_true_black">Echt zwart gebruiken</string>
<string name="settings_behavior">Gedrag</string>
<string name="settings_gif">Geanimeerde avatars en emoji\'s afspelen</string>
<string name="settings_gif">Geanimeerde profielfoto\'s en emoji\'s afspelen</string>
<string name="settings_custom_tabs">In-appbrowser gebruiken</string>
<string name="settings_notifications">Meldingen</string>
<string name="notify_me_when">Melding tonen wanneer</string>
<string name="notify_anyone">iedereen</string>
<string name="notify_anyone">iemand</string>
<string name="notify_follower">een volger</string>
<string name="notify_followed">iemand die ik volg</string>
<string name="notify_none">niemand</string>
<string name="notify_favorites">Mijn bericht als favoriet markeert</string>
<string name="notify_follow">Mij volgt</string>
<string name="notify_reblog">Boost mijn bericht</string>
<string name="notify_reblog">Mijn bericht boost</string>
<string name="notify_mention">Mij vermeldt</string>
<string name="settings_boring">De saaie zone</string>
<string name="settings_account">Accountinstellingen</string>
@@ -272,7 +272,7 @@
<string name="new_post">Nieuw bericht</string>
<string name="button_reply">Reageren</string>
<string name="button_reblog">Boosten</string>
<string name="button_favorite">Toevoegen aan favorieten</string>
<string name="button_favorite">Als favoriet markeren</string>
<string name="button_share">Delen</string>
<string name="media_no_description">Media zonder beschrijving</string>
<string name="add_media">Media toevoegen</string>
@@ -286,7 +286,7 @@
<string name="unfollowed_user">%s ontvolgd</string>
<string name="followed_user">Je volgt %s nu</string>
<string name="following_user_requested">Je volgverzoek is aan %s verstuurd</string>
<string name="open_in_browser">Openen in browser</string>
<string name="open_in_browser">In browser openen</string>
<string name="hide_boosts_from_user">Boosts van %s verbergen</string>
<string name="show_boosts_from_user">Boosts van %s tonen</string>
<string name="signup_reason">Waarom wil je je hier registreren?</string>
@@ -309,7 +309,7 @@
<string name="trending_links_info_banner">Dit zijn nieuwsartikelen die populair zijn op jouw Mastodon-server.</string>
<string name="local_timeline_info_banner">Dit zijn de meest recente berichten van mensen die ook op jouw Mastodon-server zitten.</string>
<string name="dismiss">Sluiten</string>
<string name="see_new_posts">Nieuwe berichten bekijken</string>
<string name="see_new_posts">Nieuwe berichten</string>
<string name="load_missing_posts">Resterende berichten laden</string>
<string name="follow_back">Terugvolgen</string>
<string name="button_follow_pending">In afwachting</string>
@@ -383,7 +383,7 @@
<string name="download_update">Downloaden (%s)</string>
<string name="install_update">Installeren</string>
<string name="privacy_policy_title">Jouw privacy</string>
<string name="privacy_policy_subtitle">Hoewel de Mastodon-app geen gegevens verzamelt, kan de server waar je je aanmeldt een ander beleid hebben.\n\nAls je het niet eens bent met het beleid voor %s, kun je teruggaan en een andere server kiezen.</string>
<string name="privacy_policy_subtitle">Hoewel de Mastodon-app geen gegevens verzamelt, kan de server waar je je aanmeldt een ander beleid hebben.\n\nAls je niet akkoord gaat met het beleid voor %s, kun je teruggaan en een andere server kiezen.</string>
<string name="i_agree">Ik ga akkoord</string>
<string name="empty_list">Deze lijst is leeg</string>
<string name="instance_signup_closed">Deze server accepteert geen nieuwe registraties.</string>
@@ -416,10 +416,10 @@
<string name="profile_setup_explanation">Je kunt tot vier profielvelden toevoegen voor alles wat je wilt. Locatie, links, voornaamwoorden de mogelijkheden zijn eindeloos.</string>
<string name="popular_on_mastodon">Populair op Mastodon</string>
<string name="follow_all">Volg iedereen</string>
<string name="server_rules_disagree">Oneens</string>
<string name="server_rules_disagree">Ik ga niet akkoord</string>
<string name="privacy_policy_explanation">TL;DR: We verzamelen of verwerken niets.</string>
<!-- %s is server domain -->
<string name="server_policy_disagree">Oneens met %s</string>
<string name="server_policy_disagree">Niet akkoord met %s</string>
<string name="profile_bio">Bio</string>
<!-- Shown in a progress dialog when you tap "follow all" -->
<string name="sending_follows">Gevolgde gebruikers…</string>
@@ -428,20 +428,21 @@
<string name="signup_username_taken">Deze gebruikersnaam wordt al gebruikt.</string>
<string name="spoiler_show">Alsnog tonen</string>
<string name="spoiler_hide">Opnieuw verbergen</string>
<string name="poll_multiple_choice">Selecteer een of meer</string>
<string name="poll_multiple_choice">Maak een of meerdere keuzes</string>
<string name="save_changes">Wijzigingen opslaan</string>
<string name="profile_featured">Aanbevolen</string>
<string name="profile_timeline">Tijdlijn</string>
<string name="view_all">Alles bekijken</string>
<string name="profile_endorsed_accounts">Accounts</string>
<string name="verified_link">Geverifieerde koppeling</string>
<string name="verified_link">Geverifieerde link</string>
<string name="show">Tonen</string>
<string name="hide">Verbergen</string>
<string name="join_default_server">Deelnemen aan %s</string>
<string name="join_default_server">Registreren op %s</string>
<string name="pick_server">Kies een andere server</string>
<string name="signup_or_login">of</string>
<string name="learn_more">Meer informatie</string>
<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 verbonden met elkaar.</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"><![CDATA[Elk Mastodon account wordt gehost op een server - elk met zijn eigen waarden, regels & admins. Het maakt niet uit welke server je kiest, je kunt mensen op elke server volgen en ermee communiceren.]]></string>
<string name="welcome_paragraph2"><![CDATA[Elk Mastodonaccount wordt op een server gehost - 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>
</resources>

View File

@@ -69,8 +69,8 @@
<string name="sk_already_bookmarked">Zakładka została już zapisana</string>
<string name="sk_favorited_as">Polubiono jako %s</string>
<string name="sk_already_favorited">Już polubiono</string>
<string name="sk_reblogged_as">Zrebloguj jako %s</string>
<string name="sk_already_reblogged">Już zreblogowano</string>
<string name="sk_reblogged_as">Podbite jako %s</string>
<string name="sk_already_reblogged">Już podbito</string>
<string name="sk_reply_as">Odpowiedz innym kontem</string>
<string name="sk_settings_uniform_icon_for_notifications">Identyczna ikona dla wszystkich notyfikacji</string>
<string name="sk_settings_translate_only_opened">Tłumacz tylko otwarte wpisy</string>
@@ -96,8 +96,8 @@
<string name="sk_clear_all_notifications_confirm_action">Usuń wszystkie</string>
<string name="sk_clear_all_notifications_confirm">Czy jesteś pewien że chcesz usunąć wszystkie powiadomienia\?</string>
<string name="sk_loading_fediverse_resource_title">Wyszukiwanie na Fediwersum</string>
<string name="sk_undo_reblog">Cofnij reblog</string>
<string name="sk_reblog_with_visibility">Reblog z widocznością</string>
<string name="sk_undo_reblog">Cofnij podbicie</string>
<string name="sk_reblog_with_visibility">Podbij z widocznością</string>
<string name="sk_quote_post">Wpis o tym</string>
<string name="sk_hashtags_you_follow">Hashtagi które obserwujesz</string>
<string name="sk_copy_link_to_post">Kopiuj link do wpisu</string>
@@ -127,7 +127,7 @@
<string name="sk_compose_no_draft">Nie twórz wersji roboczej</string>
<string name="sk_schedule_or_draft">Zaplanowany wpis lub kopia robocza</string>
<string name="sk_favorite_as">Polub innym kontem</string>
<string name="sk_reblog_as">Już zreblogowano</string>
<string name="sk_reblog_as">Podbij z innego konta</string>
<string name="sk_settings_reduce_motion">Zmniejsz ruch animacji</string>
<string name="sk_mark_as_read">Oznacz jako przeczytane</string>
<string name="sk_settings_about_instance">O instancji</string>
@@ -220,7 +220,7 @@
<string name="sk_icon_headphones">Słuchawki</string>
<string name="sk_icon_human">Człowiek</string>
<string name="sk_icon_globe">Glob</string>
<string name="sk_notify_update">Edytuje reblogowany wpis</string>
<string name="sk_notify_update">Edytuje podbijany wpis</string>
<string name="sk_icon_pin">Pinezka</string>
<string name="sk_remove_follower">Usuń obserwującego</string>
<string name="sk_remove_follower_confirm">Usunąć %s z obserwatorów, poprzez zablokowanie i natychmiastowe odblokowanie ich\?</string>
@@ -270,6 +270,8 @@
<string name="sk_notification_action_replied">Wysłano odpowiedź do %s</string>
<string name="sk_reply_line_above_avatar">Tekst \"W odpowiedzi na\" nad avatarem</string>
<string name="sk_show_thread">Pokaż wątek</string>
<string name="sk_compact_reblog_reply_line">Zmniejsz linię reblogu/odpowiedzi</string>
<string name="sk_settings_confirm_before_reblog">Potwierdź przed reblogowaniem</string>
<string name="sk_compact_reblog_reply_line">Zmniejsz linię podbijania/odpowiedzi</string>
<string name="sk_settings_confirm_before_reblog">Potwierdź przed podbiciem</string>
<string name="sk_reacted_with">zareagował(a) z %s</string>
<string name="sk_reacted">zareagował(a)</string>
</resources>

View File

@@ -2,4 +2,287 @@
<resources>
<string name="sk_app_name">Megalodon</string>
<string name="sk_pinned_posts">Fixado</string>
<string name="sk_filtered">Filtrado: %s</string>
<string name="sk_expand">Expandir</string>
<string name="sk_collapse">Esconder</string>
<string name="sk_settings_collapse_long_posts">Esconder publicações muito grandes</string>
<string name="sk_unfinished_attachments">Reparar anexos\?</string>
<string name="sk_translate_post">Traduzir</string>
<string name="sk_translate_show_original">Mostrar original</string>
<string name="sk_post_language">Idioma: %s</string>
<string name="sk_available_languages">Idiomas disponíveis</string>
<string name="sk_unpinning">A desfixar publicação…</string>
<string name="sk_image_description">Descrição da imagem</string>
<string name="sk_visibility_unlisted">Não listado</string>
<string name="sk_settings_show_replies">Mostrar respostas</string>
<string name="sk_settings_show_boosts">Mostrar partilhas</string>
<string name="sk_settings_load_new_posts">Carregar publicações novas automaticamente</string>
<string name="sk_unpin_post">Desfixar do perfil</string>
<string name="sk_delete_and_redraft">Apagar e reescrever</string>
<string name="sk_confirm_delete_and_redraft_title">Apagar e reescrever publicação</string>
<string name="sk_confirm_delete_and_redraft">De certeza que quer apagar e reescrever a publicação\?</string>
<string name="sk_pin_post">Fixar no perfil</string>
<string name="sk_confirm_pin_post_title">Fixar publicação no perfil</string>
<string name="sk_confirm_pin_post">Queres fixar esta publicação ao teu perfil\?</string>
<string name="sk_pinning">A fixar publicação…</string>
<string name="sk_federated_timeline">Federação</string>
<string name="sk_update_available">Megalodon %s pronto a descarregar.</string>
<string name="sk_follow_requests">Pedidos para seguir</string>
<string name="sk_accept_follow_request">Aceitar pedido para seguir</string>
<string name="sk_example_domain">exemplo.social</string>
<string name="sk_disable_marquee">Desligar deslocamento de texto nas barras de título</string>
<string name="sk_settings_contribute">Contribuir para o Megalodon</string>
<string name="sk_bookmark_as">Guardar com outra conta</string>
<string name="sk_bookmarked_as">Guardado como %s</string>
<string name="sk_already_bookmarked">Já guardado</string>
<string name="sk_favorite_as">Adicionar aos favoritos com outra conta</string>
<string name="sk_settings_profile">Configurar perfil</string>
<string name="sk_settings_filters">Configurar filtros</string>
<string name="sk_settings_auth">Configurações de segurança</string>
<string name="sk_settings_rules">Regras</string>
<string name="sk_settings_about">Sobre a aplicação</string>
<string name="sk_settings_donate">Doar</string>
<string name="sk_tabs_disable_swipe">Desligar deslocação entre separadores</string>
<string name="sk_settings_color_palette">Paleta de cores</string>
<string name="sk_color_palette_material3">Sistema</string>
<string name="sk_color_palette_pink">Rosa</string>
<string name="sk_color_palette_purple">Roxo</string>
<string name="sk_color_palette_green">Verde</string>
<string name="sk_color_palette_blue">Azul</string>
<string name="sk_color_palette_brown">Castanho</string>
<string name="sk_color_palette_red">Vermelho</string>
<string name="sk_color_palette_yellow">Amarelo</string>
<string name="sk_delete_notification_confirm">De certeza que quer apagar esta notificação\?</string>
<string name="sk_enable_delete_notifications">Ligar apagar notificações</string>
<string name="sk_settings_publish_button_text">Texto do botão de publicar</string>
<string name="sk_clear_all_notifications_confirm_action">Apagar tudo</string>
<string name="sk_clear_all_notifications_confirm">De certeza que quer apagar todas as notificações\?</string>
<string name="sk_loading_fediverse_resource_title">A procurar no Fediverso</string>
<string name="sk_reblog_with_visibility">Partilhar com visibilidade</string>
<string name="sk_quote_post">Publicar sobre isto</string>
<string name="sk_open_with_account">Abrir com outra conta</string>
<string name="sk_unsent_posts">Publicações não enviadas</string>
<string name="sk_draft">Rascunho</string>
<string name="sk_schedule">Horário</string>
<string name="sk_confirm_delete_draft_title">Apagar rascunho</string>
<string name="sk_confirm_delete_scheduled_post_title">Apagar publicação agendada</string>
<string name="sk_confirm_delete_scheduled_post">De certeza que quer apagar esta publicação agendada\?</string>
<string name="sk_draft_or_schedule">Rascunho ou horário</string>
<string name="sk_compose_draft">Publicação guardada como rascunho.</string>
<string name="sk_draft_saved">Rascunho guardado</string>
<string name="sk_scheduled_too_soon_title">Horário agendado é demasiado cedo</string>
<string name="sk_compose_scheduled">Agendada para</string>
<string name="sk_confirm_save_changes">Guardar alterações\?</string>
<string name="sk_mark_as_draft">Marcar como rascunho</string>
<string name="sk_schedule_post">Agendar publicação</string>
<string name="sk_compose_no_schedule">Não agendar</string>
<string name="sk_compose_no_draft">Sem rascunho</string>
<string name="sk_content_type_unspecified">Não especificado</string>
<string name="sk_content_type_plain">Texto simples</string>
<string name="sk_content_type_html">HTML</string>
<string name="sk_content_type_markdown">Marcador</string>
<string name="sk_content_type_mfm">MFM</string>
<string name="sk_settings_content_types">Permitir formatação de publicação</string>
<string name="sk_settings_default_content_type">Tipo de conteúdo predefinido</string>
<string name="sk_settings_default_content_type_explanation">Permite pré-selecionar um tipo de conteúdo quando se criam novas publicações, substituindo o valor definido em \"Preferências de publicação\".</string>
<string name="sk_mark_as_read">Marcar como lido</string>
<string name="sk_settings_about_instance">Sobre a instância</string>
<string name="sk_settings_single_notification">Mostrar apenas uma notificação</string>
<string name="sk_create">Criar</string>
<string name="sk_create_list_title">Criar lista</string>
<string name="sk_remove_follower_confirm">Remover %s como seguidor bloqueando e logo a seguir desbloqueando\?</string>
<string name="sk_do_remove_follower">Remover</string>
<string name="sk_remove_follower_success">Seguidor removido com sucesso</string>
<string name="sk_changelog">Registo de mudanças</string>
<string name="sk_alt_text_missing">Pelo menos um anexo não contém descrição.</string>
<string name="sk_publish_anyway">Publicar assim mesmo</string>
<string name="sk_settings_disable_alt_text_reminder">Desligar lembrete para adicionar texto alternativo</string>
<string name="sk_timelines">Linhas do tempo</string>
<string name="sk_icon_cat">Gato</string>
<string name="sk_icon_dog">Cão</string>
<string name="sk_icon_rabbit">Coelho</string>
<string name="sk_icon_turtle">Tartaruga</string>
<string name="sk_icon_balloon">Balão</string>
<string name="sk_icon_image">Imagem</string>
<string name="sk_icon_bot">Robô</string>
<string name="sk_icon_language">Idioma</string>
<string name="sk_icon_location">Localização</string>
<string name="sk_icon_megaphone">Megafone</string>
<string name="sk_icon_microphone">Microfone</string>
<string name="sk_icon_microscope">Microscópio</string>
<string name="sk_icon_keyboard">Teclado</string>
<string name="sk_icon_coffee">Café</string>
<string name="sk_icon_laugh">Riso</string>
<string name="sk_icon_news">Notícias</string>
<string name="sk_no_results">Sem resultados</string>
<string name="sk_save_draft">Guardar rascunho\?</string>
<string name="sk_no_alt_text">Sem texto alternativo disponível</string>
<string name="sk_settings_show_alt_indicator">Indicador de textos alternativos</string>
<string name="sk_settings_show_no_alt_indicator">Indicador para textos alternativos ausentes</string>
<string name="sk_updater_enable_pre_releases">Ligar versões beta</string>
<string name="sk_inline_direct">apenas-mencionados</string>
<string name="sk_separator">.</string>
<string name="sk_instance_features">Recursos da instância</string>
<string name="sk_settings_support_local_only">O servidor só suporta publicações locais</string>
<string name="sk_settings_glitch_instance">Glitch em modo local</string>
<string name="sk_settings_glitch_mode_explanation">Liga isto se a tua instância nativa corre no Glitch. Não é necessário para Hometown ou Akkoma.</string>
<string name="sk_signed_up">inscrito</string>
<string name="sk_reported">reportado</string>
<string name="sk_sign_ups">Inscrições</string>
<string name="sk_notify_poll_results">Resultados do inquérito</string>
<string name="sk_follow_as">Seguir com outra conta</string>
<string name="sk_confirm_unpin_post">Tem a certeza que quer desfixar esta publicação\?</string>
<string name="sk_user_post_notifications_off">Desligar notificações de publicação para %s</string>
<string name="sk_federated_timeline_info_banner">Estas são as publicações mais recentes das pessoas na tua federação.</string>
<string name="sk_list_timelines">Listas</string>
<string name="sk_reject_follow_request">Rejeitar pedido para seguir</string>
<string name="sk_lists_with_user">Listas com %s</string>
<string name="sk_settings_always_reveal_content_warnings">Mostrar sempre avisos de conteúdo</string>
<string name="sk_poll_allow_multiple">Permitir escolhas múltiplas</string>
<string name="sk_translated_using">Traduzido por %s</string>
<string name="sk_clear_recent_languages">Apagar idiomas usados recentemente</string>
<string name="sk_confirm_clear_recent_languages">De certeza que quer apagar os seus idiomas usados recentemente\?</string>
<string name="sk_welcome_title">Bem-vindo/a!</string>
<string name="sk_welcome_text">Saudações do tubarão! Para começar, introduz o nome do domínio da tua instância nativa abaixo.</string>
<string name="sk_settings_posting">Preferências de publicação</string>
<string name="sk_delete_notification">Apagar notificação</string>
<string name="sk_delete_notification_confirm_action">Apagar notificação</string>
<string name="sk_clear_all_notifications">Apagar todas as notificações</string>
<string name="sk_settings_publish_button_text_title">Personalizar o texto do botão de publicar</string>
<string name="sk_settings_translate_only_opened">Traduzir apenas publicações abertas</string>
<string name="sk_settings_translation_availability_note_available">%s suporta tradução!</string>
<string name="sk_settings_translation_availability_note_unavailable">%s não parece suportar tradução.</string>
<string name="sk_loading_resource_on_instance_title">A procurar em %s</string>
<string name="sk_undo_reblog">Desfazer partilha</string>
<string name="sk_hashtags_you_follow">Hastags que segues</string>
<string name="sk_copy_link_to_post">Copiar ligação para publicação</string>
<string name="sk_forward_report_to">Encaminhar para %s</string>
<string name="sk_confirm_delete_draft">De certeza que pretende apagar este rascunho\?</string>
<string name="sk_post_scheduled">Publicação agendada</string>
<string name="sk_scheduled_too_soon">A publicação tem de ser agendada pelo menos 10 minutos no futuro.</string>
<string name="sk_confirm_save_draft">Guardar rascunho\?</string>
<string name="sk_schedule_or_draft">Horário ou rascunho</string>
<string name="sk_settings_reduce_motion">Reduzir movimento em animações</string>
<string name="sk_announcements">Anúncios</string>
<string name="sk_recent_searches_placeholder">Escrever para iniciar a procura</string>
<string name="sk_remove_follower">Remover como seguidor</string>
<string name="sk_alt_text_missing_title">Texto alternativo em falta</string>
<string name="sk_notify_posts_info_banner">Se ligar as notificações de publicação para algumas pessoas, as suas publicações novas aparecerão aqui.</string>
<string name="sk_pin_timeline">Fixar linha do tempo</string>
<string name="sk_icon_city">Cidade</string>
<string name="sk_icon_gauge">Régua</string>
<string name="sk_icon_pin">Pionés</string>
<string name="sk_notification_type_update">Publicações editadas</string>
<string name="sk_searching">À procura…</string>
<string name="sk_save_draft_message">Guardar alterações ou publicar o rascunho agora\?</string>
<string name="sk_settings_see_new_posts_button">Botão \"Ver publicações novas\"</string>
<string name="sk_inline_local_only">apenas-local</string>
<string name="sk_local_only">Apenas instância local</string>
<string name="sk_settings_local_only_explanation">A tua instância nativa tem de suportar publicações locais para isto funcionar. As versões modificadas do Mastodon suportam mas o Mastodon não.</string>
<string name="sk_settings_server_version">Versão do servidor: %s</string>
<string name="sk_settings_hide_interaction">Esconder botões interativos</string>
<string name="sk_settings_prefix_reply_cw_with_re">Adicionar \"re\" a respostas com AC</string>
<string name="sk_in_reply">Em resposta</string>
<string name="sk_content_type">Tipo de conteúdo</string>
<string name="sk_content_type_bbcode">BBCode</string>
<string name="sk_settings_content_types_explanation">Permite configurar um tipo de conteúdo como Markdown na criação de uma publicação. Lembra-te que nem todas as instâncias permitem isto.</string>
<string name="sk_confirm_unpin_post_title">Desfixar publicação do perfil</string>
<string name="sk_quoting_user">Citar %s</string>
<string name="sk_settings_reply_visibility">Visibilidade da resposta</string>
<string name="sk_settings_reply_visibility_all">Todas as respostas</string>
<string name="sk_settings_reply_visibility_following">Respostas para os meus seguidores</string>
<string name="sk_settings_reply_visibility_self">Respostas para mim</string>
<string name="sk_settings_show_interaction_counts">Mostrar número de interações</string>
<string name="sk_settings_app_version">Megalodon %1$s (%2$d)</string>
<string name="sk_mark_media_as_sensitive">Marcar conteúdo como sensível</string>
<string name="sk_user_post_notifications_on">Ligar notificações de publicação para %s</string>
<string name="sk_update_ready">Megalodon %s descarregado e pronto a instalar.</string>
<string name="sk_check_for_update">A verificar atualizações</string>
<string name="sk_no_update_available">Sem atualizações disponíveis</string>
<string name="sk_settings_show_federated_timeline">Mostrar linha do tempo unificada</string>
<string name="sk_notification_type_status">Publicações</string>
<string name="sk_notify_posts">Notificações de publicação</string>
<string name="sk_resource_not_found">Recurso não encontrado</string>
<string name="sk_favorited_as">Adicionado aos favoritos como %s</string>
<string name="sk_already_favorited">Já adicionado aos favoritos</string>
<string name="sk_reblog_as">Partilhar com outra conta</string>
<string name="sk_reply_as">Responder com outra conta</string>
<string name="sk_settings_uniform_icon_for_notifications">Ícone uniforme para todas as notificações</string>
<string name="sk_list_name_hint">Nome da Lista</string>
<string name="sk_list_replies_policy">Mostrar respostas a</string>
<string name="sk_list_replies_policy_list">Membros da lista</string>
<string name="sk_list_replies_policy_followed">Utilizadores seguidos</string>
<string name="sk_list_replies_policy_none">ninguém</string>
<string name="sk_delete_list">Apagar lista</string>
<string name="sk_delete_list_confirm">De certeza que quer apagar a lista \"%s\"\?</string>
<string name="sk_edit_list_title">Editar lista</string>
<string name="sk_your_lists">As tuas listas</string>
<string name="sk_timeline_home">Página principal</string>
<string name="sk_timeline_local">Local</string>
<string name="sk_timeline_federated">Federação</string>
<string name="sk_timeline_posts">Publicações</string>
<string name="sk_timelines_add">Adicionar</string>
<string name="sk_timeline">Linha do tempo</string>
<string name="sk_list">Lista</string>
<string name="sk_hashtag">Hashtag</string>
<string name="sk_unpin_timeline">Desfixar linha do tempo</string>
<string name="sk_pinned_timeline">Fixado à página principal</string>
<string name="sk_unpinned_timeline">Desfixado da página principal</string>
<string name="sk_reply_line_above_avatar">Linha \"Em resposta a\" por cima da foto de perfil</string>
<string name="sk_remove">Remover</string>
<string name="sk_timeline_icon">ícone</string>
<string name="sk_icon_heart">Coração</string>
<string name="sk_icon_star">Estrela</string>
<string name="sk_icon_pi">Pi</string>
<string name="sk_icon_color_palette">Paleta de cores</string>
<string name="sk_icon_academic_cap">Chapéu académico</string>
<string name="sk_icon_tag">Etiqueta</string>
<string name="sk_icon_stethoscope">Estetoscópio</string>
<string name="sk_icon_weather">Meteorologia</string>
<string name="sk_icon_games">Jogos</string>
<string name="sk_icon_code">Código</string>
<string name="sk_icon_light_bulb">Lâmpada</string>
<string name="sk_icon_train">Comboio</string>
<string name="sk_icon_clapper_board">Claquete</string>
<string name="sk_icon_leaves">Folhas</string>
<string name="sk_icon_sport">Desposto</string>
<string name="sk_icon_aperture">Abertura</string>
<string name="sk_icon_music">Música</string>
<string name="sk_icon_people">Pessoas</string>
<string name="sk_icon_health">Saúde</string>
<string name="sk_icon_important">Importante</string>
<string name="sk_icon_chat">Conversas</string>
<string name="sk_icon_shield">Escudo</string>
<string name="sk_icon_book">Livro</string>
<string name="sk_icon_bicycle">Bicicleta</string>
<string name="sk_icon_map">Mapa</string>
<string name="sk_icon_math_formula">Fórmula matemática</string>
<string name="sk_icon_backpack">Mochila</string>
<string name="sk_icon_briefcase">Pasta</string>
<string name="sk_icon_fire">Fogo</string>
<string name="sk_icon_bug">Inseto</string>
<string name="sk_icon_pizza">Pizza</string>
<string name="sk_icon_gavel">Martelo</string>
<string name="sk_icon_headphones">Auscultadores</string>
<string name="sk_icon_human">Humano</string>
<string name="sk_icon_globe">Globo</string>
<string name="sk_edit_timeline">Editar linha do tempo</string>
<string name="sk_edit_timelines">Editar linhas do tempo</string>
<string name="sk_alt_button">ALT</string>
<string name="sk_post_edited">editado</string>
<string name="sk_attach_file">Anexar ficheiro</string>
<string name="sk_notification_action_replied">Resposta enviada a %s</string>
<string name="sk_settings_confirm_before_reblog">Confirmar antes de partilhar</string>
<string name="sk_language_name">%1$s (%2$s)</string>
<string name="sk_reblogged_as">Partilhado como %s</string>
<string name="sk_already_reblogged">Já partilhado</string>
<string name="sk_notify_update">Editar uma publicação partilhada</string>
<string name="sk_compact_reblog_reply_line">Linha compacta partilhar/responder</string>
<string name="sk_reacted_with">reagiu com %s</string>
<string name="sk_reacted">reagiu</string>
<string name="sk_new_reports">Novas denúncias</string>
<string name="sk_unfinished_attachments_message">Alguns anexos ainda não carregaram.</string>
<string name="sk_followed_as">Seguido com %s</string>
<string name="sk_settings_hide_fab">Esconder automaticamente o botão Escrever</string>
<string name="sk_show_thread">Mostrar fio</string>
</resources>

View File

@@ -1,2 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>
<resources>
<string name="sk_app_name">Megalodon</string>
<string name="sk_pinned_posts">Fixado</string>
<string name="sk_delete_and_redraft">Apagar e reescrever</string>
<string name="sk_confirm_delete_and_redraft">Tem a certeza que pretende apagar e reescrever esta publicação\?</string>
<string name="sk_confirm_unpin_post">Tem a certeza que deseja desafixar esta publicação\?</string>
<string name="sk_settings_reply_visibility_all">Todas as respostas</string>
<string name="sk_settings_load_new_posts">Carregar novas publicações automaticamente</string>
<string name="sk_user_post_notifications_off">Desligar as notificações de publicação para %s</string>
<string name="sk_federated_timeline_info_banner">Estas são as publicações mais recentes das pessoas na tua federação.</string>
<string name="sk_confirm_delete_and_redraft_title">Apagar e reescrever publicação</string>
<string name="sk_pin_post">Fixar no perfil</string>
<string name="sk_confirm_pin_post_title">Fixar publicação no perfil</string>
<string name="sk_confirm_pin_post">Deseja fixar esta publicação ao seu perfil\?</string>
<string name="sk_pinning">A fixar a publicação…</string>
<string name="sk_unpin_post">Desafixar do perfil</string>
<string name="sk_confirm_unpin_post_title">Desafixar publicação do perfil</string>
<string name="sk_unpinning">A desafixar publicação…</string>
<string name="sk_image_description">Descrição da imagem</string>
<string name="sk_visibility_unlisted">Não listado</string>
<string name="sk_settings_show_replies">Mostrar respostas</string>
<string name="sk_quoting_user">Citação %s</string>
<string name="sk_settings_reply_visibility">Visibilidade da resposta</string>
<string name="sk_clear_recent_languages">Apagar idiomas usados recentemente</string>
<string name="sk_settings_reply_visibility_following">Respostas aos meus comentários</string>
<string name="sk_settings_reply_visibility_self">Respostas a mim</string>
<string name="sk_settings_show_boosts">Mostrar impulsionamentos</string>
<string name="sk_settings_show_interaction_counts">Mostrar contagem de interações</string>
<string name="sk_settings_app_version">Megalodon v%1$s (%2$d)</string>
<string name="sk_mark_media_as_sensitive">Marcar conteúdo como sensível</string>
<string name="sk_user_post_notifications_on">Ligar as notificações de publicação para %s</string>
<string name="sk_federated_timeline">Federação</string>
<string name="sk_update_available">Megalodon %s pronto a descarregar.</string>
<string name="sk_update_ready">Megalodon %s descarregado e pronto a instalar.</string>
<string name="sk_check_for_update">A verificar atualizações</string>
<string name="sk_no_update_available">Sem atualizações disponíveis</string>
<string name="sk_list_timelines">Listas</string>
<string name="sk_follow_requests">Pedidos para seguir</string>
<string name="sk_accept_follow_request">Aceitar pedido para seguir</string>
<string name="sk_reject_follow_request">Rejeitar pedido para seguir</string>
<string name="sk_lists_with_user">Listas com %s</string>
<string name="sk_settings_always_reveal_content_warnings">Mostrar sempre avisos de conteúdo</string>
</resources>

View File

@@ -472,7 +472,7 @@
<string name="spoiler_hide">Спрятать повторно</string>
<string name="poll_multiple_choice">Выберите один или более</string>
<string name="save_changes">Сохранить изменения</string>
<string name="profile_featured">Возможности</string>
<string name="profile_featured">Избранное</string>
<string name="profile_timeline">Лента</string>
<string name="view_all">Посмотреть все</string>
<string name="profile_endorsed_accounts">Учётные записи</string>
@@ -480,6 +480,7 @@
<string name="show">Показать</string>
<string name="hide">Скрыть</string>
<string name="join_default_server">Присоединиться к %s</string>
<string name="pick_server">Выбрать другой сервер</string>
<string name="signup_or_login">или</string>
<string name="learn_more">Узнать больше</string>
<string name="welcome_to_mastodon">Добро пожаловать в Mastodon</string>

View File

@@ -81,7 +81,7 @@
<string name="sk_clear_all_notifications">Очистить все уведомления</string>
<string name="sk_clear_all_notifications_confirm_action">Удалить все</string>
<string name="sk_clear_all_notifications_confirm">Вы точно хотите удалить все уведомления\?</string>
<string name="sk_undo_reblog">Отменить продвижение поста</string>
<string name="sk_undo_reblog">Отменить продвижение</string>
<string name="sk_reblog_with_visibility">Продвижение с видимостью</string>
<string name="sk_quote_post">Создать публикацию об этом</string>
<string name="sk_copy_link_to_post">Скопировать ссылку на публикацию</string>
@@ -91,14 +91,14 @@
<string name="sk_favorite_as">Добавить в избранное с другого аккаунта</string>
<string name="sk_already_favorited">Уже в избранном</string>
<string name="sk_reblog_as">Продвигать на другом аккаунте</string>
<string name="sk_reblogged_as">Реблог на %s</string>
<string name="sk_reblogged_as">Продвинуть на %s</string>
<string name="sk_reply_as">Ответить с другого аккаунта</string>
<string name="sk_settings_uniform_icon_for_notifications">Единая иконка для всех уведомлений</string>
<string name="sk_loading_fediverse_resource_title">Ищем это в Fediverse</string>
<string name="sk_bookmark_as">Добавить в закладки с другого аккаунта</string>
<string name="sk_bookmarked_as">В закладки как %s</string>
<string name="sk_favorited_as">В избранное как %s</string>
<string name="sk_already_reblogged">Уже реблогнуто</string>
<string name="sk_already_reblogged">Уже продвинуто</string>
<string name="sk_hashtags_you_follow">Хештеги, на которые вы подписаны</string>
<string name="sk_loading_resource_on_instance_title">Просматриваем на %s</string>
<string name="sk_unsent_posts">Неотправленные сообщения</string>
@@ -225,7 +225,7 @@
<string name="sk_icon_shield">Щит</string>
<string name="sk_icon_book">Книга</string>
<string name="sk_attach_file">Прикрепить файл</string>
<string name="sk_notify_update">Изменяет репост</string>
<string name="sk_notify_update">Изменяет продвинутый пост</string>
<string name="sk_searching">Поиск…</string>
<string name="sk_no_results">Нет результатов</string>
<string name="sk_save_draft">Сохранить черновик\?</string>
@@ -250,4 +250,28 @@
<string name="sk_settings_server_version">Версия сервера: %s</string>
<string name="sk_notify_poll_results">Итоги голосования</string>
<string name="sk_settings_local_only_explanation">Для работы этой функции ваш инстанс должен поддерживать локальные публикации. Большинство модифицированных версий Mastodon это поддерживают, но сам Mastodon нет.</string>
<string name="sk_settings_prefix_reply_cw_with_re">Префикс ответа CW с “re:”</string>
<string name="sk_filtered">Отфильтровано: %s</string>
<string name="sk_expand">Развернуть</string>
<string name="sk_collapse">Свернуть</string>
<string name="sk_settings_collapse_long_posts">Сворачивать очень длинные посты</string>
<string name="sk_unfinished_attachments">Исправить вложения\?</string>
<string name="sk_unfinished_attachments_message">Некоторые вложения еще не загрузились.</string>
<string name="sk_quoting_user">Цитирование%s</string>
<string name="sk_settings_reply_visibility">Видимость ответа</string>
<string name="sk_settings_hide_interaction">Скрыть кнопки взаимодействия</string>
<string name="sk_follow_as">Подписаться с другого аккаунта</string>
<string name="sk_followed_as">Подписан с %s</string>
<string name="sk_in_reply">В ответ</string>
<string name="sk_reply_line_above_avatar">строка \"В ответ на\" над аватаром</string>
<string name="sk_settings_hide_fab">Автоматическое скрытие кнопки Составить</string>
<string name="sk_settings_reply_visibility_all">Все ответы</string>
<string name="sk_settings_reply_visibility_following">Ответы на мои подписки</string>
<string name="sk_settings_reply_visibility_self">Ответы мне</string>
<string name="sk_settings_confirm_before_reblog">Подтверждение перед продвижением</string>
<string name="sk_compact_reblog_reply_line">Компактная строка продвижения/ответа</string>
<string name="sk_reacted_with">отреагировал с %s</string>
<string name="sk_reacted">отреагировал</string>
<string name="sk_notification_action_replied">Отправлен ответ на %s</string>
<string name="sk_show_thread">Показать тему</string>
</resources>

View File

@@ -412,4 +412,7 @@
<!-- %1$s is server domain, %2$s is email domain. You can reorder these placeholders to fit your language better. -->
<string name="signup_email_domain_blocked">%1$s tillåter inte registrering från %2$s. Prova en annan eller &lt;a&gt;välj en annan server&lt;/a&gt;.</string>
<string name="signup_username_taken">Det här användarnamnet är redan taget.</string>
<string name="save_changes">Spara ändringar</string>
<string name="signup_or_login">eller</string>
<string name="welcome_to_mastodon">Välkommen till Mastodon</string>
</resources>

View File

@@ -273,4 +273,17 @@
<string name="sk_show_thread">Показати потік</string>
<string name="sk_compact_reblog_reply_line">Компактний рядок для поширеного допису/відповіді</string>
<string name="sk_settings_confirm_before_reblog">Підтверджувати поширення</string>
<string name="sk_reacted">реагує</string>
<string name="sk_reacted_with">реагує з %s</string>
<string name="sk_content_type_unspecified">Не визначено</string>
<string name="sk_content_type_plain">Звичайний текст</string>
<string name="sk_content_type_html">HTML</string>
<string name="sk_content_type_bbcode">BBCode</string>
<string name="sk_content_type_mfm">MFM</string>
<string name="sk_settings_content_types">Увімкнути форматування допису</string>
<string name="sk_settings_default_content_type">Типовий тип вмісту</string>
<string name="sk_content_type">Тип вмісту</string>
<string name="sk_settings_default_content_type_explanation">Це дозволяє вам попередньо вибрати тип вмісту під час написання нових дописів, замінивши значення, встановлене в «Налаштуваннях постингу».</string>
<string name="sk_content_type_markdown">Markdown</string>
<string name="sk_settings_content_types_explanation">Дозволяє налаштувати тип вмісту, наприклад, Markdown, під час написання допису. Зауважте, що не всі сервери підтримують цю функцію.</string>
</resources>

View File

@@ -11,7 +11,7 @@
<string name="preparing_auth">Chuẩn bị xác thực…</string>
<string name="finishing_auth">Hoàn tất xác thực…</string>
<string name="user_boosted">%s đăng lại</string>
<string name="in_reply_to">%s viết tiếp</string>
<string name="in_reply_to">Trả lời %s</string>
<string name="notifications">Thông báo</string>
<string name="user_followed_you">đã theo dõi bạn</string>
<string name="user_sent_follow_request">đã yêu cầu theo dõi bạn</string>
@@ -127,7 +127,7 @@
<item quantity="other">%d người đang thảo luận</item>
</plurals>
<plurals name="discussed_x_times">
<item quantity="other">Đề cập %d lần</item>
<item quantity="other">Chia sẻ %d lượt</item>
</plurals>
<string name="report_title">Báo cáo %s</string>
<string name="report_choose_reason">Có vấn đề gì với tút này?</string>
@@ -150,8 +150,8 @@
<string name="sending_report">Đang gửi báo cáo…</string>
<string name="report_sent_title">Cảm ơn đã báo cáo, chúng tôi sẽ xem xét kỹ.</string>
<string name="report_sent_subtitle">Trong lúc chờ chúng tôi xem xét, bạn có thể áp dụng hành động với @%s.</string>
<string name="unfollow_user">Ngưng theo dõi %s</string>
<string name="unfollow">Ngưng theo dõi</string>
<string name="unfollow_user">Bỏ theo dõi %s</string>
<string name="unfollow">Bỏ theo dõi</string>
<string name="mute_user_explain">Bạn sẽ không thấy tút hoặc lượt đăng lại của họ trên bảng tin. Họ không biết rằng bạn ẩn họ.</string>
<string name="block_user_explain">Họ sẽ không thể theo dõi hoặc đọc tút của bạn, nhưng họ có thể hiểu bạn đã chặn họ.</string>
<string name="report_personal_title">Không muốn xem thứ này?</string>
@@ -223,7 +223,7 @@
<string name="theme_auto">Tự động</string>
<string name="theme_light">Sáng</string>
<string name="theme_dark">Tối</string>
<string name="theme_true_black">Chế độ tối chân thật</string>
<string name="theme_true_black">Chế độ tương phản cao</string>
<string name="settings_behavior">Thao tác</string>
<string name="settings_gif">Ảnh đại diện và emoji động</string>
<string name="settings_custom_tabs">Dùng trình duyệt tích hợp</string>
@@ -268,7 +268,7 @@
<string name="my_profile">Hồ sơ của tôi</string>
<string name="media_viewer">Xem media</string>
<string name="follow_user">Theo dõi %s</string>
<string name="unfollowed_user">Ngưng theo dõi %s</string>
<string name="unfollowed_user">Bỏ theo dõi %s</string>
<string name="followed_user">Bạn đã theo dõi %s</string>
<string name="following_user_requested">Yêu cầu theo dõi %s</string>
<string name="open_in_browser">Mở trong trình duyệt</string>
@@ -317,8 +317,8 @@
</plurals>
<string name="timestamp_via_app">%1$s qua %2$s</string>
<string name="time_now">vừa xong</string>
<string name="post_info_reblogs">Lượt đăng lại</string>
<string name="post_info_favorites">Lượt thích</string>
<string name="post_info_reblogs">Đăng lại</string>
<string name="post_info_favorites">Thích</string>
<string name="edit_history">Lịch sử chỉnh sửa</string>
<string name="last_edit_at_x">Sửa lần cuối %s</string>
<string name="time_just_now">vừa xong</string>
@@ -369,14 +369,14 @@
<string name="text_copied">Đã sao chép vào bộ nhớ tạm</string>
<string name="add_bookmark">Lưu</string>
<string name="remove_bookmark">Bỏ lưu</string>
<string name="bookmarks">Tút đã lưu</string>
<string name="your_favorites">Lượt thích</string>
<string name="bookmarks">Những tút đã lưu</string>
<string name="your_favorites">Những tút đã thích</string>
<string name="login_title">Chào mừng quay trở lại!</string>
<string name="login_subtitle">Đăng nhập với máy chủ nơi bạn tạo tài khoản.</string>
<string name="server_url">URL Máy chủ</string>
<string name="signup_random_server_explain">Chúng tôi sẽ chọn một máy chủ dựa trên ngôn ngữ của bạn nếu bạn tiếp tục mà không lựa chọn.</string>
<string name="server_filter_any_language">Mọi ngôn ngữ</string>
<string name="server_filter_instant_signup">Đăng ký nhanh</string>
<string name="server_filter_instant_signup">Duyệt tự động</string>
<string name="server_filter_manual_review">Duyệt thủ công</string>
<string name="server_filter_any_signup_speed">Mọi hình thức duyệt</string>
<string name="server_filter_region_europe">Châu Âu</string>
@@ -385,7 +385,7 @@
<string name="server_filter_region_africa">Châu Phi</string>
<string name="server_filter_region_asia">Châu Á</string>
<string name="server_filter_region_oceania">Châu Đại Dương</string>
<string name="not_accepting_new_members">Tạm ngưng đăng ký mới</string>
<string name="not_accepting_new_members">Tạm dừng đăng ký mới</string>
<string name="category_special_interests">Sở thích đặc biệt</string>
<string name="signup_passwords_dont_match">Mật khẩu không khớp</string>
<string name="pick_server_for_me">Chọn giúp tôi</string>

View File

@@ -381,6 +381,7 @@
<string name="server_filter_region_africa">非洲</string>
<string name="server_filter_region_asia">亚洲</string>
<string name="server_filter_region_oceania">大洋洲</string>
<string name="not_accepting_new_members">不接受新成员</string>
<string name="signup_passwords_dont_match">两次输入密码不匹配</string>
<string name="pick_server_for_me">帮我挑选</string>
<string name="profile_add_row">添加</string>
@@ -396,9 +397,11 @@
<!-- %1$s is server domain, %2$s is email domain. You can reorder these placeholders to fit your language better. -->
<string name="profile_timeline">时间轴</string>
<string name="profile_endorsed_accounts">帐号</string>
<string name="verified_link">已验证链接</string>
<string name="show">显示</string>
<string name="hide">隐藏</string>
<string name="join_default_server">加入 %s</string>
<string name="pick_server">选择其他服务器</string>
<string name="signup_or_login">或者</string>
<string name="learn_more">了解更多</string>
<string name="welcome_to_mastodon">欢迎来到Mastodon</string>

View File

@@ -30,6 +30,7 @@
<string name="sk_user_post_notifications_off">Turned off post notifications for %s</string>
<string name="sk_federated_timeline">Federation</string>
<string name="sk_federated_timeline_info_banner">These are the most recent posts by the people in your federation.</string>
<string name="sk_bubble_timeline_info_banner">These are the most recent posts by the people in your Akkoma server\'s bubble.</string>
<string name="sk_update_available">Megalodon %s is ready to download.</string>
<string name="sk_update_ready">Megalodon %s is downloaded and ready to install.</string>
<string name="sk_check_for_update">Check for update</string>
@@ -148,6 +149,7 @@
<string name="sk_timeline_home">Home</string>
<string name="sk_timeline_local">Local</string>
<string name="sk_timeline_federated">Federation</string>
<string name="sk_timeline_bubble">Bubble</string>
<string name="sk_recent_searches_placeholder">Type to start searching</string>
<string name="sk_remove_follower">Remove as follower</string>
<string name="sk_remove_follower_confirm">Remove %s as a follower by blocking and immediately unblocking them?</string>

View File

@@ -0,0 +1,5 @@
- Mi piace/salva/rispondi direttamente dalla notifica
- Intestazioni più belle e coerenti per i reblog e le risposte nella timeline
- Punto di notifica (che, in realtà, non carica ancora le notifiche)
- Per utenti di Akkoma: visibilità delle risposte, citazioni, risposte ai thread ordinate...
- Correzione di alcuni crash e piccole modifiche

View File

@@ -0,0 +1,5 @@
- Polubienia / dodawanie zakładek / odpowiadanie bezpośrednio z powiadomienia
- Ładniejsze i bardziej spójne nagłówki dla reblogów i odpowiedzi na osi czasu
- Kropka powiadomień (która w rzeczywistości nie ładuje jeszcze powiadomień)
- Dla użytkowników Akkoma: widoczność odpowiedzi, posortowane odpowiedzi na wątek, cytowanie, itp.
- Naprawienie błędów i inne drobne poprawki

View File

@@ -0,0 +1,4 @@
- Preparar ficheiros para publicar no F-Droid
- Corrigir o atualizador automático
- Voltar a adicionar ícones monocromáticos nos ícones de lançamento
- Substituir ícones errados e não listados no rodapé expandido

View File

@@ -0,0 +1,6 @@
- Tornar possível a abertura da publicação original enquanto se responde (clicando na linha "Em resposta a...")
- Unificar alterações e correções de erros
- Remover o código inutilizado da "App Center"
- Adicionar publicação sem linha do tempo unificada para a Play Store
- Adicionar redireção personalizada para inicio de sessão mais fácil.
- Alterar o link de contribuições

View File

@@ -0,0 +1,4 @@
- Corrigir a má renderização de tags de HTML e permitir a renderização de formatação Markdown
- Inicializar <a href="https://translate.codeberg.org/projects/megalodon">projeto de tradução Weblate</a>
- Adicionar botão de ligar e desligar para a linha do tempo unificada
- As versões 52-54 foram pequenos ajustes para a publicação na Google Play

View File

@@ -0,0 +1,6 @@
- Personalizar a cor to tema por @LucasGGamerM
- Novo texto "megalodon" do logótipo submetido por @LucasGGamerM
- Melhor pesquisa de emojis enquanto se escreve
- Votação ajustada (mostrar o próprio voto, mostrar sempre o botão de votar, não cortar respostas longas)
- Adicionar configuração de notificações push para notificações de publicação
- Correção de erros

View File

@@ -0,0 +1,6 @@
- Adicionar selecionador de idioma
- Adicionar função de tradução
- Melhorar a semântica para votações em inquéritos (botões rádio e caixas de seleção)
- Adicionar opção para permitir votar em mais que uma opção nos inquéritos
- Novo ecrã de início de sessão
- Correções de erros

View File

@@ -0,0 +1,5 @@
- Novas cores de tema: Material You e Red
- Novos tons cinzento escuro para todos os temas
- Ícone de impulsionar mais chamativo
- Animações para botões interativos
- Correções de erros (bloquear em algumas publicações, "Listas com", linguagem pré-definida de publicação

View File

@@ -0,0 +1,16 @@
Megalodon é uma versão modificada da <a href="https://github.com/mastodon/mastodon-android"> App oficial do Mastodon</a> que adiciona recursos importantes que faltam na app original, tais como, a linha do tempo unificada, publicações não listadas e um visualizador da descrição das imagens.
<b>Recursos chave</b>
- <b>Publicação não listada</b>: Publicar sem que a tua publicação apareça nas tendências, hashtags ou em linhas do tempo públicas.
- <b>Linha do tempo unificada</b>: Ver todas as publicações de pessoas noutras vizinhanças do Fediverso a que a tua instância nativa está ligada.
-<b>Linhas do tempo personalizadas</b>: Fixa qualquer lista ou hashtag ao teu separador nativo do Megalodon para simplesmente deslizar entre os teus tópicos e pessoas favoritas.
-<b>Rascunhos e publicações agendadas</b>: Permite a preparação de uma publicação e agendar-la para ser automaticamente publicada num tempo determinado.
- <b>Fixar publicações</b>: Fixa as tuas publicações mais importantes no teu perfil e vê o que os outros têm fixado usando o separador "Fixados".
- <b>Seguir hashtags</b>: Vê publicações de hashtags específicas diretamente na tua linha do tempo nativa seguindo-os simplesmente.
- <b>Responder a pedidos para seguir</b>: Aceitar ou rejeitar pedidos para seguir a partir das tuas notificações ou na lista de pedidos para seguir dedicada a isso.
- <b>Apagar e refazer</b>: O muito adorado recurso que tornou a edição possível sem uma função de editar propriamente dita.
- <b>Selecionar idioma</b>: Seleciona sem esforço nenhum o idioma para cada publicação que fazes para que os filtros e a tradução funcionem corretamente.
- <b>Tradução</b>: Traduz facilmente publicações dentro do próprio Megalodon! Funciona apenas se o recurso estiver disponível no Mastodon Web.
- <b>Indicador da visibilidade de publicação</b>: Ao abrir ou responder a uma públicação um icone de uma mão será apresentado, indicando a visibilidade da publicação.
- <b>Cor dos temas</b>: Caso não gostes do rosa padrão (o tubarão está a julgar-te silenciosamente), a paleta de cores de tema do Moshidon tratam disso por ti.

View File

@@ -0,0 +1 @@
Mastodon para Android, mas é rosa e tem mais recursos

1
metadata/pt/title.txt Normal file
View File

@@ -0,0 +1 @@
Megalodon