diff --git a/img/ic_fluent_animal_cat_24_regular.svg b/img/ic_fluent_animal_cat_24_regular.svg
new file mode 100644
index 000000000..83c0f5290
--- /dev/null
+++ b/img/ic_fluent_animal_cat_24_regular.svg
@@ -0,0 +1,9 @@
+
+
+
+
\ No newline at end of file
diff --git a/mastodon/proguard-rules.pro b/mastodon/proguard-rules.pro
index 0274f1794..cacc1cdb0 100644
--- a/mastodon/proguard-rules.pro
+++ b/mastodon/proguard-rules.pro
@@ -53,3 +53,36 @@
-keep interface org.parceler.Parcel
-keep @org.parceler.Parcel class * { *; }
-keep class **$$Parcelable { *; }
+
+##---------------Begin: proguard configuration for Gson ----------
+# Gson uses generic type information stored in a class file when working with fields. Proguard
+# removes such information by default, so configure it to keep all of it.
+-keepattributes Signature
+
+# For using GSON @Expose annotation
+-keepattributes *Annotation*
+
+# Gson specific classes
+-dontwarn sun.misc.**
+#-keep class com.google.gson.stream.** { *; }
+
+# Application classes that will be serialized/deserialized over Gson
+-keep class com.google.gson.examples.android.model.** { ; }
+
+# Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,
+# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
+-keep class * extends com.google.gson.TypeAdapter
+-keep class * implements com.google.gson.TypeAdapterFactory
+-keep class * implements com.google.gson.JsonSerializer
+-keep class * implements com.google.gson.JsonDeserializer
+
+# Prevent R8 from leaving Data object members always null
+-keepclassmembers,allowobfuscation class * {
+ @com.google.gson.annotations.SerializedName ;
+}
+
+# Retain generic signatures of TypeToken and its subclasses with R8 version 3.0 and higher.
+-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken
+-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken
+
+##---------------End: proguard configuration for Gson ----------
diff --git a/mastodon/src/main/java/org/joinmastodon/android/ExternalShareActivity.java b/mastodon/src/main/java/org/joinmastodon/android/ExternalShareActivity.java
index 2b655db19..c94a91d9e 100644
--- a/mastodon/src/main/java/org/joinmastodon/android/ExternalShareActivity.java
+++ b/mastodon/src/main/java/org/joinmastodon/android/ExternalShareActivity.java
@@ -69,7 +69,7 @@ public class ExternalShareActivity extends FragmentStackActivity{
.ifPresent(req ->
req.wrapProgress(this, R.string.loading, true, d -> {
UiUtils.transformDialogForLookup(this, accountId, isFediUrl ? text.get() : null, d);
- d.setOnDismissListener((ev) -> finish());
+ d.setOnDismissListener((x) -> finish());
}));
} else {
openComposeFragment(accountId);
diff --git a/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java b/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java
index e946c2846..53be8a16d 100644
--- a/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java
+++ b/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java
@@ -43,7 +43,7 @@ public class GlobalUserPreferences{
public static boolean showAltIndicator;
public static boolean showNoAltIndicator;
public static boolean enablePreReleases;
- public static boolean prefixRepliesWithRe;
+ public static PrefixRepliesMode prefixReplies;
public static boolean bottomEncoding;
public static boolean collapseLongPosts;
public static boolean spectatorMode;
@@ -57,14 +57,12 @@ public class GlobalUserPreferences{
public static boolean loadRemoteAccountFollowers;
public static boolean mentionRebloggerAutomatically;
public static boolean allowRemoteLoading;
+ public static boolean forwardReportDefault;
public static AutoRevealMode autoRevealEqualSpoilers;
public static String publishButtonText;
public static ThemePreference theme;
public static ColorPreference color;
- private final static Type recentLanguagesType = new TypeToken>>() {}.getType();
- private final static Type pinnedTimelinesType = new TypeToken>>() {}.getType();
- private final static Type accountsDefaultContentTypesType = new TypeToken>() {}.getType();
public static Map> recentLanguages;
public static Map> pinnedTimelines;
public static Set accountsWithLocalOnlySupport;
@@ -72,6 +70,10 @@ public class GlobalUserPreferences{
public static Set accountsWithContentTypesEnabled;
public static Map accountsDefaultContentTypes;
+ private final static Type recentLanguagesType = new TypeToken>>() {}.getType();
+ private final static Type pinnedTimelinesType = new TypeToken>>() {}.getType();
+ private final static Type accountsDefaultContentTypesType = new TypeToken>() {}.getType();
+
private final static Type recentEmojisType = new TypeToken>() {}.getType();
public static Map recentEmojis;
@@ -126,7 +128,7 @@ public class GlobalUserPreferences{
showAltIndicator=prefs.getBoolean("showAltIndicator", true);
showNoAltIndicator=prefs.getBoolean("showNoAltIndicator", true);
enablePreReleases=prefs.getBoolean("enablePreReleases", false);
- prefixRepliesWithRe=prefs.getBoolean("prefixRepliesWithRe", false);
+ prefixReplies=PrefixRepliesMode.valueOf(prefs.getString("prefixReplies", PrefixRepliesMode.NEVER.name()));
bottomEncoding=prefs.getBoolean("bottomEncoding", false);
collapseLongPosts=prefs.getBoolean("collapseLongPosts", true);
spectatorMode=prefs.getBoolean("spectatorMode", false);
@@ -153,6 +155,16 @@ public class GlobalUserPreferences{
accountsDefaultContentTypes=fromJson(prefs.getString("accountsDefaultContentTypes", null), accountsDefaultContentTypesType, new HashMap<>());
allowRemoteLoading=prefs.getBoolean("allowRemoteLoading", true);
autoRevealEqualSpoilers=AutoRevealMode.valueOf(prefs.getString("autoRevealEqualSpoilers", AutoRevealMode.THREADS.name()));
+ forwardReportDefault=prefs.getBoolean("forwardReportDefault", true);
+
+ if (prefs.contains("prefixRepliesWithRe")) {
+ prefixReplies = prefs.getBoolean("prefixRepliesWithRe", false)
+ ? PrefixRepliesMode.TO_OTHERS : PrefixRepliesMode.NEVER;
+ prefs.edit()
+ .putString("prefixReplies", prefixReplies.name())
+ .remove("prefixRepliesWithRe")
+ .apply();
+ }
try {
if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){
@@ -179,6 +191,8 @@ public class GlobalUserPreferences{
.putBoolean("alwaysExpandContentWarnings", alwaysExpandContentWarnings)
.putBoolean("disableMarquee", disableMarquee)
.putBoolean("disableSwipe", disableSwipe)
+ .putBoolean("enableDeleteNotifications", enableDeleteNotifications)
+ .putBoolean("translateButtonOpenedOnly", translateButtonOpenedOnly)
.putBoolean("showDividers", showDividers)
.putBoolean("relocatePublishButton", relocatePublishButton)
.putBoolean("uniformNotificationIcon", uniformNotificationIcon)
@@ -189,7 +203,7 @@ public class GlobalUserPreferences{
.putBoolean("showAltIndicator", showAltIndicator)
.putBoolean("showNoAltIndicator", showNoAltIndicator)
.putBoolean("enablePreReleases", enablePreReleases)
- .putBoolean("prefixRepliesWithRe", prefixRepliesWithRe)
+ .putString("prefixReplies", prefixReplies.name())
.putBoolean("collapseLongPosts", collapseLongPosts)
.putBoolean("spectatorMode", spectatorMode)
.putBoolean("autoHideFab", autoHideFab)
@@ -216,6 +230,7 @@ public class GlobalUserPreferences{
.putString("accountsDefaultContentTypes", gson.toJson(accountsDefaultContentTypes))
.putBoolean("allowRemoteLoading", allowRemoteLoading)
.putString("autoRevealEqualSpoilers", autoRevealEqualSpoilers.name())
+ .putBoolean("forwardReportDefault", forwardReportDefault)
.apply();
}
@@ -242,4 +257,10 @@ public class GlobalUserPreferences{
THREADS,
DISCUSSIONS
}
+
+ public enum PrefixRepliesMode {
+ NEVER,
+ ALWAYS,
+ TO_OTHERS
+ }
}
diff --git a/mastodon/src/main/java/org/joinmastodon/android/PushNotificationReceiver.java b/mastodon/src/main/java/org/joinmastodon/android/PushNotificationReceiver.java
index 564a266bb..d4514fa9c 100644
--- a/mastodon/src/main/java/org/joinmastodon/android/PushNotificationReceiver.java
+++ b/mastodon/src/main/java/org/joinmastodon/android/PushNotificationReceiver.java
@@ -320,7 +320,11 @@ public class PushNotificationReceiver extends BroadcastReceiver{
req.language = preferences.postingDefaultLanguage;
req.visibility = preferences.postingDefaultVisibility;
req.inReplyToId = notification.status.id;
- if(!notification.status.spoilerText.isEmpty() && GlobalUserPreferences.prefixRepliesWithRe && !notification.status.spoilerText.startsWith("re: ")){
+
+ if (!notification.status.spoilerText.isEmpty() &&
+ (GlobalUserPreferences.prefixReplies == ALWAYS
+ || (GlobalUserPreferences.prefixReplies == TO_OTHERS && !ownID.equals(notification.status.account.id)))
+ && !notification.status.spoilerText.startsWith("re: ")) {
req.spoilerText = "re: " + notification.status.spoilerText;
}
diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/AnnouncementsFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/AnnouncementsFragment.java
index 1b6b8ce2a..430c1205b 100644
--- a/mastodon/src/main/java/org/joinmastodon/android/fragments/AnnouncementsFragment.java
+++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/AnnouncementsFragment.java
@@ -94,12 +94,15 @@ public class AnnouncementsFragment extends BaseStatusListFragment
@Override
public void onSuccess(List result){
if (getActivity() == null) return;
- List unread = result.stream().filter(a -> !a.read).collect(toList());
- List read = result.stream().filter(a -> a.read).collect(toList());
- onDataLoaded(unread, true);
- onDataLoaded(read, false);
- if (unread.isEmpty()) setResult(true, null);
- else unreadIDs = unread.stream().map(a -> a.id).collect(toList());
+
+ // get unread items first
+ List data = result.stream().filter(a -> !a.read).collect(toList());
+ if (data.isEmpty()) setResult(true, null);
+ else unreadIDs = data.stream().map(a -> a.id).collect(toList());
+
+ // append read items at the end
+ data.addAll(result.stream().filter(a -> a.read).collect(toList()));
+ onDataLoaded(data, false);
}
})
.exec(accountID);
diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/ComposeFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/ComposeFragment.java
index 8026fd4ea..807b7382e 100644
--- a/mastodon/src/main/java/org/joinmastodon/android/fragments/ComposeFragment.java
+++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/ComposeFragment.java
@@ -1,5 +1,6 @@
package org.joinmastodon.android.fragments;
+import static org.joinmastodon.android.GlobalUserPreferences.PrefixRepliesMode.*;
import static org.joinmastodon.android.GlobalUserPreferences.recentLanguages;
import static org.joinmastodon.android.api.requests.statuses.CreateStatus.DRAFTS_AFTER_INSTANT;
import static org.joinmastodon.android.api.requests.statuses.CreateStatus.getDraftInstant;
@@ -806,9 +807,11 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
if(!TextUtils.isEmpty(status.spoilerText)){
hasSpoiler=true;
spoilerEdit.setVisibility(View.VISIBLE);
- if(GlobalUserPreferences.prefixRepliesWithRe && !status.spoilerText.startsWith("re: ")){
+ if ((GlobalUserPreferences.prefixReplies == ALWAYS
+ || (GlobalUserPreferences.prefixReplies == TO_OTHERS && !ownID.equals(status.account.id)))
+ && !status.spoilerText.startsWith("re: ")) {
spoilerEdit.setText("re: " + status.spoilerText);
- }else{
+ } else {
spoilerEdit.setText(status.spoilerText);
}
spoilerBtn.setSelected(true);
diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/FollowRequestsListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/FollowRequestsListFragment.java
index 9f144634d..17e9ce0de 100644
--- a/mastodon/src/main/java/org/joinmastodon/android/fragments/FollowRequestsListFragment.java
+++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/FollowRequestsListFragment.java
@@ -255,6 +255,10 @@ public class FollowRequestsListFragment extends RecyclerFragment filterPosts(List items) {
- // This is the function I must use to solve the filters thing for real
- return items.stream().filter(i ->
- (GlobalUserPreferences.showReplies || i.inReplyToId == null) &&
- (GlobalUserPreferences.showBoosts || i.reblog == null)
- ).collect(Collectors.toList());
+ return items.stream().filter(this::typeFilterPredicate).collect(Collectors.toList());
}
@Override
@@ -107,24 +103,24 @@ public class HomeTimelineFragment extends StatusListFragment {
@Override
protected void onHidden(){
super.onHidden();
-// if(!data.isEmpty()){
-// String topPostID=displayItems.get(list.getChildAdapterPosition(list.getChildAt(0))-getMainAdapterOffset()).parentID;
-// if(!topPostID.equals(lastSavedMarkerID)){
-// lastSavedMarkerID=topPostID;
-// new SaveMarkers(topPostID, null)
-// .setCallback(new Callback<>(){
-// @Override
-// public void onSuccess(SaveMarkers.Response result){
-// }
-//
-// @Override
-// public void onError(ErrorResponse error){
-// lastSavedMarkerID=null;
-// }
-// })
-// .exec(accountID);
-// }
-// }
+ if(!data.isEmpty()){
+ String topPostID=displayItems.get(Math.max(0, list.getChildAdapterPosition(list.getChildAt(0))-getMainAdapterOffset())).parentID;
+ if(!topPostID.equals(lastSavedMarkerID)){
+ lastSavedMarkerID=topPostID;
+ new SaveMarkers(topPostID, null)
+ .setCallback(new Callback<>(){
+ @Override
+ public void onSuccess(SaveMarkers.Response result){
+ }
+
+ @Override
+ public void onError(ErrorResponse error){
+ lastSavedMarkerID=null;
+ }
+ })
+ .exec(accountID);
+ }
+ }
}
public void onStatusCreated(StatusCreatedEvent ev){
@@ -238,7 +234,7 @@ public class HomeTimelineFragment extends StatusListFragment {
for(Status s:result){
if(idsBelowGap.contains(s.id))
break;
- if(filterPredicate.test(s)){
+ if(typeFilterPredicate(s) && filterPredicate.test(s)){
targetList.addAll(buildDisplayItems(s));
insertedPosts.add(s);
}
diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/PinnedPostsListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/PinnedPostsListFragment.java
new file mode 100644
index 000000000..a091e5d42
--- /dev/null
+++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/PinnedPostsListFragment.java
@@ -0,0 +1,52 @@
+package org.joinmastodon.android.fragments;
+
+import android.net.Uri;
+import android.os.Bundle;
+
+import org.joinmastodon.android.R;
+import org.joinmastodon.android.api.requests.accounts.GetAccountStatuses;
+import org.joinmastodon.android.model.Account;
+import org.joinmastodon.android.model.Filter;
+import org.joinmastodon.android.model.Status;
+import org.parceler.Parcels;
+
+import java.util.List;
+
+import me.grishka.appkit.api.SimpleCallback;
+
+public class PinnedPostsListFragment extends StatusListFragment{
+ private Account account;
+
+ public PinnedPostsListFragment() {
+ setListLayoutId(R.layout.recycler_fragment_no_refresh);
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState){
+ super.onCreate(savedInstanceState);
+ account=Parcels.unwrap(getArguments().getParcelable("profileAccount"));
+ setTitle(R.string.posts);
+ loadData();
+ }
+
+ @Override
+ protected void doLoadData(int offset, int count){
+ new GetAccountStatuses(account.id, null, null, 100, GetAccountStatuses.Filter.PINNED)
+ .setCallback(new SimpleCallback<>(this){
+ @Override
+ public void onSuccess(List result){
+ onDataLoaded(result, false);
+ }
+ }).exec(accountID);
+ }
+
+ @Override
+ protected Filter.FilterContext getFilterContext() {
+ return Filter.FilterContext.ACCOUNT;
+ }
+
+ @Override
+ public Uri getWebUri(Uri.Builder base) {
+ return Uri.parse(account.url);
+ }
+}
diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/ProfileFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/ProfileFragment.java
index 684078214..787efd74b 100644
--- a/mastodon/src/main/java/org/joinmastodon/android/fragments/ProfileFragment.java
+++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/ProfileFragment.java
@@ -134,7 +134,8 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
private ProgressBarButton actionButton, notifyButton;
private ViewPager2 pager;
private NestedRecyclerScrollView scrollView;
- private AccountTimelineFragment postsFragment, postsWithRepliesFragment, pinnedPostsFragment, mediaFragment;
+ private AccountTimelineFragment postsFragment, postsWithRepliesFragment, mediaFragment;
+ private PinnedPostsListFragment pinnedPostsFragment;
// private ProfileAboutFragment aboutFragment;
private TabLayout tabbar;
private SwipeRefreshLayout refreshLayout;
@@ -515,8 +516,14 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
if(postsFragment==null){
postsFragment=AccountTimelineFragment.newInstance(accountID, account, GetAccountStatuses.Filter.DEFAULT, true);
postsWithRepliesFragment=AccountTimelineFragment.newInstance(accountID, account, GetAccountStatuses.Filter.INCLUDE_REPLIES, false);
- pinnedPostsFragment=AccountTimelineFragment.newInstance(accountID, account, GetAccountStatuses.Filter.PINNED, false);
mediaFragment=AccountTimelineFragment.newInstance(accountID, account, GetAccountStatuses.Filter.MEDIA, false);
+
+ Bundle args=new Bundle();
+ args.putString("account", accountID);
+ args.putParcelable("profileAccount", Parcels.wrap(account));
+ args.putBoolean("__is_tab", true);
+ pinnedPostsFragment=new PinnedPostsListFragment();
+ pinnedPostsFragment.setArguments(args);
// aboutFragment=new ProfileAboutFragment();
setFields(fields);
}
@@ -675,6 +682,9 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
followingLabel.setText(getResources().getQuantityString(R.plurals.following, (int)Math.min(999, account.followingCount)));
postsLabel.setText(getResources().getQuantityString(R.plurals.posts, (int)Math.min(999, account.statusesCount)));
+ if (account.followersCount < 0) followersBtn.setVisibility(View.GONE);
+ if (account.followingCount < 0) followingBtn.setVisibility(View.GONE);
+
UiUtils.loadCustomEmojiInTextView(name);
UiUtils.loadCustomEmojiInTextView(bio);
diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/SettingsFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/SettingsFragment.java
index 29e2150e7..0c9a06829 100644
--- a/mastodon/src/main/java/org/joinmastodon/android/fragments/SettingsFragment.java
+++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/SettingsFragment.java
@@ -39,6 +39,7 @@ import org.joinmastodon.android.E;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.GlobalUserPreferences.AutoRevealMode;
import org.joinmastodon.android.GlobalUserPreferences.ColorPreference;
+import org.joinmastodon.android.GlobalUserPreferences.PrefixRepliesMode;
import org.joinmastodon.android.MainActivity;
import org.joinmastodon.android.MastodonApp;
import org.joinmastodon.android.R;
@@ -221,14 +222,27 @@ public class SettingsFragment extends MastodonToolbarFragment implements Provide
GlobalUserPreferences.keepOnlyLatestNotification=i.checked;
GlobalUserPreferences.save();
}));
- items.add(new SwitchItem(R.string.sk_settings_prefix_reply_cw_with_re, R.drawable.ic_fluent_arrow_reply_24_regular, GlobalUserPreferences.prefixRepliesWithRe, i->{
- GlobalUserPreferences.prefixRepliesWithRe=i.checked;
+ items.add(new ButtonItem(R.string.sk_settings_prefix_reply_cw_with_re, R.drawable.ic_fluent_arrow_reply_24_regular, b->{
+ PopupMenu popupMenu=new PopupMenu(getActivity(), b, Gravity.CENTER_HORIZONTAL);
+ popupMenu.inflate(R.menu.settings_prefix_reply_mode);
+ popupMenu.setOnMenuItemClickListener(i -> onPrefixRepliesClick(i, b));
+ b.setOnTouchListener(popupMenu.getDragToOpenListener());
+ b.setOnClickListener(v->popupMenu.show());
+ b.setText(switch(GlobalUserPreferences.prefixReplies){
+ case TO_OTHERS -> R.string.sk_settings_prefix_replies_to_others;
+ case ALWAYS -> R.string.sk_settings_prefix_replies_always;
+ default -> R.string.sk_settings_prefix_replies_never;
+ });
GlobalUserPreferences.save();
}));
items.add(new SwitchItem(R.string.sk_settings_confirm_before_reblog, R.drawable.ic_fluent_checkmark_circle_24_regular, GlobalUserPreferences.confirmBeforeReblog, i->{
GlobalUserPreferences.confirmBeforeReblog=i.checked;
GlobalUserPreferences.save();
}));
+ items.add(new SwitchItem(R.string.sk_settings_forward_report_default, R.drawable.ic_fluent_arrow_forward_24_regular, GlobalUserPreferences.forwardReportDefault, i->{
+ GlobalUserPreferences.forwardReportDefault=i.checked;
+ GlobalUserPreferences.save();
+ }));
items.add(new SwitchItem(R.string.sk_settings_allow_remote_loading, R.drawable.ic_fluent_communication_24_regular, GlobalUserPreferences.allowRemoteLoading, i->{
GlobalUserPreferences.allowRemoteLoading=i.checked;
GlobalUserPreferences.save();
@@ -541,6 +555,22 @@ public class SettingsFragment extends MastodonToolbarFragment implements Provide
return true;
}
+ private boolean onPrefixRepliesClick(MenuItem item, Button btn) {
+ int id = item.getItemId();
+ PrefixRepliesMode mode = PrefixRepliesMode.NEVER;
+ if (id == R.id.prefix_replies_always) mode = PrefixRepliesMode.ALWAYS;
+ else if (id == R.id.prefix_replies_to_others) mode = PrefixRepliesMode.TO_OTHERS;
+ GlobalUserPreferences.prefixReplies = mode;
+
+ btn.setText(switch(GlobalUserPreferences.prefixReplies){
+ case TO_OTHERS -> R.string.sk_settings_prefix_replies_to_others;
+ case ALWAYS -> R.string.sk_settings_prefix_replies_always;
+ default -> R.string.sk_settings_prefix_replies_never;
+ });
+
+ return true;
+ }
+
private boolean onAutoRevealSpoilerClick(MenuItem item, Button btn) {
int id = item.getItemId();
@@ -557,12 +587,12 @@ public class SettingsFragment extends MastodonToolbarFragment implements Provide
private void onAutoRevealSpoilerChanged(Button b) {
if (GlobalUserPreferences.alwaysExpandContentWarnings) {
- b.setText(R.string.sk_settings_auto_reveal_always);
+ b.setText(R.string.sk_settings_auto_reveal_anyone);
} else {
b.setText(switch(GlobalUserPreferences.autoRevealEqualSpoilers){
- case THREADS -> R.string.sk_settings_auto_reveal_threads;
- case DISCUSSIONS -> R.string.sk_settings_auto_reveal_discussions;
- default -> R.string.sk_settings_auto_reveal_never;
+ case THREADS -> R.string.sk_settings_auto_reveal_author;
+ case DISCUSSIONS -> R.string.sk_settings_auto_reveal_anyone;
+ default -> R.string.sk_settings_auto_reveal_nobody;
});
if (alwaysRevealSpoilersItem.checked != GlobalUserPreferences.alwaysExpandContentWarnings) {
alwaysRevealSpoilersItem.checked = GlobalUserPreferences.alwaysExpandContentWarnings;
diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/StatusListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/StatusListFragment.java
index a42094caa..e0bcd3d32 100644
--- a/mastodon/src/main/java/org/joinmastodon/android/fragments/StatusListFragment.java
+++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/StatusListFragment.java
@@ -178,13 +178,29 @@ public abstract class StatusListFragment extends BaseStatusListFragment
protected void removeStatus(Status status){
data.remove(status);
preloadedData.remove(status);
- int index=-1;
+ int index=-1, ancestorFirstIndex = -1, ancestorLastIndex = -1;
for(int i=0;i= 0 && ancestorLastIndex == index - 1) {
+ for (int i = ancestorFirstIndex; i <= ancestorLastIndex; i++) {
+ StatusDisplayItem item = displayItems.get(i);
+ // update ancestor to have no descendant anymore
+ if (item.parentID.equals(status.inReplyToId)) item.hasDescendantNeighbor = false;
+ }
+ adapter.notifyItemRangeChanged(ancestorFirstIndex, ancestorLastIndex - ancestorFirstIndex + 1);
+ }
+
if(index==-1)
return;
int lastIndex;
diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java
index a4fd08152..063b4fb04 100644
--- a/mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java
+++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java
@@ -52,7 +52,8 @@ import me.grishka.appkit.utils.V;
public class ThreadFragment extends StatusListFragment implements ProvidesAssistContent {
protected Status mainStatus, updatedStatus;
private final HashMap ancestryMap = new HashMap<>();
- protected boolean contextInitiallyRendered;
+ private StatusContext result;
+ protected boolean contextInitiallyRendered, transitionFinished;
@Override
public void onCreate(Bundle savedInstanceState){
@@ -105,13 +106,20 @@ public class ThreadFragment extends StatusListFragment implements ProvidesAssist
footer.hideCounts=true;
}
}
+
for (int deleteThisItem : deleteTheseItems) itemsToModify.remove(deleteThisItem);
if(s.id.equals(mainStatus.id)) {
- items.add(new ExtendedFooterStatusDisplayItem(s.id, this, getAccountID(), s.getContentStatus()));
+ items.add(new ExtendedFooterStatusDisplayItem(s.id, this, accountID, s.getContentStatus()));
}
return items;
}
+ @Override
+ public void onTransitionFinished() {
+ transitionFinished = true;
+ maybeApplyContext();
+ }
+
@Override
protected void doLoadData(int offset, int count){
if (refreshing) loadMainStatus();
@@ -119,72 +127,8 @@ public class ThreadFragment extends StatusListFragment implements ProvidesAssist
.setCallback(new SimpleCallback<>(this){
@Override
public void onSuccess(StatusContext result){
- if (getContext() == null) return;
- Map oldData = null;
- if(refreshing){
- oldData = new HashMap<>(data.size());
- for (Status s : data) oldData.put(s.id, s);
- data.clear();
- ancestryMap.clear();
- displayItems.clear();
- data.add(mainStatus);
- onAppendItems(Collections.singletonList(mainStatus));
- }
-
- // TODO: figure out how this code works
- if(isInstanceAkkoma()) sortStatusContext(mainStatus, result);
-
- result.descendants=filterStatuses(result.descendants);
- result.ancestors=filterStatuses(result.ancestors);
-
- for (NeighborAncestryInfo i : mapNeighborhoodAncestry(mainStatus, result)) {
- ancestryMap.put(i.status.id, i);
- }
-
- if(footerProgress!=null)
- footerProgress.setVisibility(View.GONE);
- data.addAll(result.descendants);
- int prevCount=displayItems.size();
- onAppendItems(result.descendants);
- int count=displayItems.size();
- if(!refreshing)
- adapter.notifyItemRangeInserted(prevCount, count-prevCount);
- int prependedCount = prependItems(result.ancestors, !refreshing);
- if (prependedCount > 0 && displayItems.get(prependedCount) instanceof ReblogOrReplyLineStatusDisplayItem) {
- displayItems.remove(prependedCount);
- adapter.notifyItemRemoved(prependedCount);
- count--;
- }
-
- for (Status s : data) {
- Status oldStatus = oldData == null ? null : oldData.get(s.id);
- // restore previous spoiler/filter revealed states when refreshing
- if (oldStatus != null) {
- s.spoilerRevealed = oldStatus.spoilerRevealed;
- s.filterRevealed = oldStatus.filterRevealed;
- } else if (GlobalUserPreferences.autoRevealEqualSpoilers != AutoRevealMode.NEVER &&
- s.spoilerText != null &&
- s.spoilerText.equals(mainStatus.spoilerText) &&
- mainStatus.spoilerRevealed) {
- if (GlobalUserPreferences.autoRevealEqualSpoilers == AutoRevealMode.DISCUSSIONS || Objects.equals(mainStatus.account.id, s.account.id)) {
- s.spoilerRevealed = true;
- }
- }
- }
-
- dataLoaded();
- if(refreshing){
- refreshDone();
- adapter.notifyDataSetChanged();
- }
- list.scrollToPosition(displayItems.size()-count);
-
- // no animation is going to happen, so proceeding to apply right now
- if (data.size() == 1) {
- contextInitiallyRendered = true;
- // for the case that the main status has already finished loading
- maybeApplyMainStatus();
- }
+ ThreadFragment.this.result = result;
+ maybeApplyContext();
}
})
.exec(accountID);
@@ -207,6 +151,77 @@ public class ThreadFragment extends StatusListFragment implements ProvidesAssist
}).exec(accountID);
}
+ protected void maybeApplyContext() {
+ if (!transitionFinished || result == null || getContext() == null) return;
+ Map oldData = null;
+ if(refreshing){
+ oldData = new HashMap<>(data.size());
+ for (Status s : data) oldData.put(s.id, s);
+ data.clear();
+ ancestryMap.clear();
+ displayItems.clear();
+ data.add(mainStatus);
+ onAppendItems(Collections.singletonList(mainStatus));
+ }
+
+ // TODO: figure out how this code works
+ if (isInstanceAkkoma()) sortStatusContext(mainStatus, result);
+
+ result.descendants=filterStatuses(result.descendants);
+ result.ancestors=filterStatuses(result.ancestors);
+
+ for (NeighborAncestryInfo i : mapNeighborhoodAncestry(mainStatus, result)) {
+ ancestryMap.put(i.status.id, i);
+ }
+
+ if(footerProgress!=null)
+ footerProgress.setVisibility(View.GONE);
+ data.addAll(result.descendants);
+ int prevCount=displayItems.size();
+ onAppendItems(result.descendants);
+ int count=displayItems.size();
+ if(!refreshing)
+ adapter.notifyItemRangeInserted(prevCount, count-prevCount);
+ int prependedCount = prependItems(result.ancestors, !refreshing);
+ if (prependedCount > 0 && displayItems.get(prependedCount) instanceof ReblogOrReplyLineStatusDisplayItem) {
+ displayItems.remove(prependedCount);
+ adapter.notifyItemRemoved(prependedCount);
+ count--;
+ }
+
+ for (Status s : data) {
+ Status oldStatus = oldData == null ? null : oldData.get(s.id);
+ // restore previous spoiler/filter revealed states when refreshing
+ if (oldStatus != null) {
+ s.spoilerRevealed = oldStatus.spoilerRevealed;
+ s.filterRevealed = oldStatus.filterRevealed;
+ } else if (GlobalUserPreferences.autoRevealEqualSpoilers != AutoRevealMode.NEVER &&
+ s.spoilerText != null &&
+ s.spoilerText.equals(mainStatus.spoilerText) &&
+ mainStatus.spoilerRevealed) {
+ if (GlobalUserPreferences.autoRevealEqualSpoilers == AutoRevealMode.DISCUSSIONS || Objects.equals(mainStatus.account.id, s.account.id)) {
+ s.spoilerRevealed = true;
+ }
+ }
+ }
+
+ dataLoaded();
+ if(refreshing){
+ refreshDone();
+ adapter.notifyDataSetChanged();
+ }
+ list.scrollToPosition(displayItems.size()-count);
+
+ // no animation is going to happen, so proceeding to apply right now
+ if (data.size() == 1) {
+ contextInitiallyRendered = true;
+ // for the case that the main status has already finished loading
+ maybeApplyMainStatus();
+ }
+
+ result = null;
+ }
+
protected Object maybeApplyMainStatus() {
if (updatedStatus == null || !contextInitiallyRendered) return null;
@@ -337,10 +352,60 @@ public class ThreadFragment extends StatusListFragment implements ProvidesAssist
}
protected void onStatusCreated(StatusCreatedEvent ev){
- if(ev.status.inReplyToId!=null && getStatusByID(ev.status.inReplyToId)!=null){
- data.add(ev.status);
- onAppendItems(Collections.singletonList(ev.status));
+ if (ev.status.inReplyToId == null) return;
+ Status repliedToStatus = getStatusByID(ev.status.inReplyToId);
+ if (repliedToStatus == null) return;
+ NeighborAncestryInfo ancestry = ancestryMap.get(repliedToStatus.id);
+
+ int nextDisplayItemsIndex = -1, indexOfPreviousDisplayItem = -1;
+
+ for (int i = 0; i < displayItems.size(); i++) {
+ StatusDisplayItem item = displayItems.get(i);
+ if (repliedToStatus.id.equals(item.parentID)) {
+ // saving the replied-to status' display items index to eventually reach the last one
+ indexOfPreviousDisplayItem = i;
+ item.hasDescendantNeighbor = true;
+ } else if (indexOfPreviousDisplayItem >= 0 && nextDisplayItemsIndex == -1) {
+ // previous display item was the replied-to status' display items
+ nextDisplayItemsIndex = i;
+ // nothing left to do if there's no other reply to that status
+ if (ancestry.descendantNeighbor == null) break;
+ }
+ if (ancestry.descendantNeighbor != null && item.parentID.equals(ancestry.descendantNeighbor.id)) {
+ // existing reply shall no longer have the replied-to status as its neighbor
+ item.hasAncestoringNeighbor = false;
+ }
}
+
+ // fall back to inserting the item at the end
+ nextDisplayItemsIndex = nextDisplayItemsIndex >= 0 ? nextDisplayItemsIndex : displayItems.size();
+ int nextDataIndex = data.indexOf(repliedToStatus) + 1;
+
+ // if replied-to status already has another reply...
+ if (ancestry.descendantNeighbor != null) {
+ // update the reply's ancestry to remove its ancestoring neighbor (as we did above)
+ ancestryMap.get(ancestry.descendantNeighbor.id).ancestoringNeighbor = null;
+ // make sure the existing reply has a reply line
+ if (nextDataIndex < data.size() &&
+ !(displayItems.get(nextDisplayItemsIndex) instanceof ReblogOrReplyLineStatusDisplayItem)) {
+ Status nextStatus = data.get(nextDataIndex);
+ if (!nextStatus.account.id.equals(repliedToStatus.account.id)) {
+ // create reply line manually since we're not building that status' items
+ displayItems.add(nextDisplayItemsIndex, StatusDisplayItem.buildReplyLine(
+ this, nextStatus, accountID, nextStatus, repliedToStatus.account, false
+ ));
+ }
+ }
+ }
+
+ // update replied-to status' ancestry
+ ancestry.descendantNeighbor = ev.status;
+
+ // add ancestry for newly created status before building its display items
+ ancestryMap.put(ev.status.id, new NeighborAncestryInfo(ev.status, null, repliedToStatus));
+ displayItems.addAll(nextDisplayItemsIndex, buildDisplayItems(ev.status));
+ data.add(nextDataIndex, ev.status);
+ adapter.notifyDataSetChanged();
}
@Override
diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/DiscoverAccountsFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/DiscoverAccountsFragment.java
index d5fb1dd5d..a9ca42509 100644
--- a/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/DiscoverAccountsFragment.java
+++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/DiscoverAccountsFragment.java
@@ -244,6 +244,10 @@ public class DiscoverAccountsFragment extends RecyclerFragment other.getPrivacy();
}
+ public boolean isReblogPermitted(boolean isOwnStatus){
+ return (this == StatusPrivacy.PUBLIC ||
+ this == StatusPrivacy.UNLISTED ||
+ this == StatusPrivacy.LOCAL ||
+ (this == StatusPrivacy.PRIVATE && isOwnStatus));
+ }
+
public int getPrivacy() {
return privacy;
}
diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/PhotoLayoutHelper.java b/mastodon/src/main/java/org/joinmastodon/android/ui/PhotoLayoutHelper.java
index fe3accc4f..86e1962ce 100644
--- a/mastodon/src/main/java/org/joinmastodon/android/ui/PhotoLayoutHelper.java
+++ b/mastodon/src/main/java/org/joinmastodon/android/ui/PhotoLayoutHelper.java
@@ -10,153 +10,170 @@ import java.util.List;
import androidx.annotation.NonNull;
+import me.grishka.appkit.utils.V;
+
public class PhotoLayoutHelper{
public static final int MAX_WIDTH=1000;
- public static final int MAX_HEIGHT=1910;
+ public static final int MAX_HEIGHT=1700;
+ public static final float GAP=1.5f;
+
+ // 2 * margin + close button height - gap. i don't know if the gap subtraction is correct
+ public static final int MIN_HEIGHT = Math.round(V.dp(2 * 12) + V.dp(40) - GAP);
@NonNull
public static TiledLayoutResult processThumbs(List thumbs){
- int _maxW=MAX_WIDTH;
- int _maxH=MAX_HEIGHT;
+ float maxRatio=MAX_WIDTH/(float)MAX_HEIGHT;
TiledLayoutResult result=new TiledLayoutResult();
if(thumbs.size()==1){
Attachment att=thumbs.get(0);
result.rowSizes=result.columnSizes=new int[]{1};
- if(att.getWidth()>att.getHeight()){
- result.width=_maxW;
- result.height=Math.round(att.getHeight()/(float)att.getWidth()*_maxW);
+ float ratio=att.getWidth()/(float) att.getHeight();
+ if(ratio>maxRatio){
+ result.width=MAX_WIDTH;
+ result.height=Math.max(MIN_HEIGHT, Math.round(att.getHeight()/(float)att.getWidth()*MAX_WIDTH));
}else{
- result.height=_maxH;
- result.width=Math.round(att.getWidth()/(float)att.getHeight()*_maxH);
+ result.height=MAX_HEIGHT;
+ result.width=MAX_WIDTH;//Math.round(att.getWidth()/(float)att.getHeight()*MAX_HEIGHT);
}
- result.tiles=new TiledLayoutResult.Tile[]{new TiledLayoutResult.Tile(1, 1, result.width, result.height, 0, 0)};
+ result.tiles=new TiledLayoutResult.Tile[]{new TiledLayoutResult.Tile(1, 1, 0, 0)};
+ return result;
}else if(thumbs.size()==0){
throw new IllegalArgumentException("Empty thumbs array");
}
- String orients="";
- ArrayList ratios=new ArrayList();
+ ArrayList ratios=new ArrayList<>();
int cnt=thumbs.size();
+ boolean allAreWide=true, allAreSquare=true;
for(Attachment thumb : thumbs){
-// float ratio=thumb.isSizeKnown() ? thumb.getWidth()/(float) thumb.getHeight() : 1f;
- float ratio=thumb.getWidth()/(float) thumb.getHeight();
- char orient=ratio>1.2 ? 'w' : (ratio<0.8 ? 'n' : 'q');
- orients+=orient;
+ float ratio=Math.max(0.45f, thumb.getWidth()/(float) thumb.getHeight());
+ if(ratio<=1.2f){
+ allAreWide=false;
+ if(ratio<0.8f)
+ allAreSquare=false;
+ }else{
+ allAreSquare=false;
+ }
ratios.add(ratio);
}
float avgRatio=!ratios.isEmpty() ? sum(ratios)/ratios.size() : 1.0f;
- float maxW, maxH, marginW=0, marginH=0;
- maxW=_maxW;
- maxH=_maxH;
-
- float maxRatio=maxW/maxH;
-
if(cnt==2){
- if(orients.equals("ww") && avgRatio>1.4*maxRatio && (ratios.get(1)-ratios.get(0))<0.2){ // two wide photos, one above the other
- float h=Math.min(maxW/ratios.get(0), Math.min(maxW/ratios.get(1), (maxH-marginH)/2.0f));
+ if(allAreWide && avgRatio>1.4*maxRatio && (ratios.get(1)-ratios.get(0))<0.2){ // two wide photos, one above the other
+ float h=Math.max(Math.min(MAX_WIDTH/ratios.get(0), Math.min(MAX_WIDTH/ratios.get(1), (MAX_HEIGHT-GAP)/2.0f)), MIN_HEIGHT/2f);
- result.width=Math.round(maxW);
- result.height=Math.round(h*2+marginH);
+ result.width=MAX_WIDTH;
+ result.height=Math.round(h*2+GAP);
result.columnSizes=new int[]{result.width};
result.rowSizes=new int[]{Math.round(h), Math.round(h)};
result.tiles=new TiledLayoutResult.Tile[]{
- new TiledLayoutResult.Tile(1, 1, maxW, h, 0, 0),
- new TiledLayoutResult.Tile(1, 1, maxW, h, 0, 1)
+ new TiledLayoutResult.Tile(1, 1, 0, 0),
+ new TiledLayoutResult.Tile(1, 1, 0, 1)
};
- }else if(orients.equals("ww") || orients.equals("qq")){ // next to each other, same ratio
- float w=((maxW-marginW)/2);
- float h=Math.min(w/ratios.get(0), Math.min(w/ratios.get(1), maxH));
+ }else if(allAreWide || allAreSquare){ // next to each other, same ratio
+ float w=((MAX_WIDTH-GAP)/2);
+ float h=Math.max(Math.min(w/ratios.get(0), Math.min(w/ratios.get(1), MAX_HEIGHT)), MIN_HEIGHT);
- result.width=Math.round(maxW);
+ result.width=MAX_WIDTH;
result.height=Math.round(h);
- result.columnSizes=new int[]{Math.round(w), _maxW-Math.round(w)};
+ result.columnSizes=new int[]{Math.round(w), MAX_WIDTH-Math.round(w)};
result.rowSizes=new int[]{Math.round(h)};
result.tiles=new TiledLayoutResult.Tile[]{
- new TiledLayoutResult.Tile(1, 1, w, h, 0, 0),
- new TiledLayoutResult.Tile(1, 1, w, h, 1, 0)
+ new TiledLayoutResult.Tile(1, 1, 0, 0),
+ new TiledLayoutResult.Tile(1, 1, 1, 0)
};
}else{ // next to each other, different ratios
- float w0=((maxW-marginW)/ratios.get(1)/(1/ratios.get(0)+1/ratios.get(1)));
- float w1=(maxW-w0-marginW);
- float h=Math.min(maxH, Math.min(w0/ratios.get(0), w1/ratios.get(1)));
+ float w0=((MAX_WIDTH-GAP)/ratios.get(1)/(1/ratios.get(0)+1/ratios.get(1)));
+ float w1=(MAX_WIDTH-w0-GAP);
+ float h=Math.max(Math.min(MAX_HEIGHT, Math.min(w0/ratios.get(0), w1/ratios.get(1))), MIN_HEIGHT);
result.columnSizes=new int[]{Math.round(w0), Math.round(w1)};
result.rowSizes=new int[]{Math.round(h)};
- result.width=Math.round(w0+w1+marginW);
+ result.width=Math.round(w0+w1+GAP);
result.height=Math.round(h);
result.tiles=new TiledLayoutResult.Tile[]{
- new TiledLayoutResult.Tile(1, 1, w0, h, 0, 0),
- new TiledLayoutResult.Tile(1, 1, w1, h, 1, 0)
+ new TiledLayoutResult.Tile(1, 1, 0, 0),
+ new TiledLayoutResult.Tile(1, 1, 1, 0)
};
}
}else if(cnt==3){
- if(/*(ratios.get(0) > 1.2 * maxRatio || avgRatio > 1.5 * maxRatio) &&*/ orients.equals("www") || true){ // 2nd and 3rd photos are on the next line
- float hCover=Math.min(maxW/ratios.get(0), (maxH-marginH)*0.66f);
- float w2=((maxW-marginW)/2);
- float h=Math.min(maxH-hCover-marginH, Math.min(w2/ratios.get(1), w2/ratios.get(2)));
- result.width=Math.round(maxW);
- result.height=Math.round(hCover+h+marginH);
- result.columnSizes=new int[]{Math.round(w2), _maxW-Math.round(w2)};
+ if((ratios.get(0) > 1.2 * maxRatio || avgRatio > 1.5 * maxRatio) || allAreWide){ // 2nd and 3rd photos are on the next line
+ float hCover=Math.min(MAX_WIDTH/ratios.get(0), (MAX_HEIGHT-GAP)*0.66f);
+ float w2=((MAX_WIDTH-GAP)/2);
+ float h=Math.min(MAX_HEIGHT-hCover-GAP, Math.min(w2/ratios.get(1), w2/ratios.get(2)));
+ if(hCover+h 1.2 * maxRatio || avgRatio > 1.5 * maxRatio) &&*/ orients.equals("wwww") || true /* temporary fix */){ // 2nd, 3rd and 4th photos are on the next line
- float hCover=Math.min(maxW/ratios.get(0), (maxH-marginH)*0.66f);
- float h=(maxW-2*marginW)/(ratios.get(1)+ratios.get(2)+ratios.get(3));
+ if((ratios.get(0) > 1.2 * maxRatio || avgRatio > 1.5 * maxRatio) || allAreWide){ // 2nd, 3rd and 4th photos are on the next line
+ float hCover=Math.min(MAX_WIDTH/ratios.get(0), (MAX_HEIGHT-GAP)*0.66f);
+ float h=(MAX_WIDTH-2*GAP)/(ratios.get(1)+ratios.get(2)+ratios.get(3));
float w0=h*ratios.get(1);
float w1=h*ratios.get(2);
float w2=h*ratios.get(3);
- h=Math.min(maxH-hCover-marginH, h);
- result.width=Math.round(maxW);
- result.height=Math.round(hCover+h+marginH);
- result.columnSizes=new int[]{Math.round(w0), Math.round(w1), _maxW-Math.round(w0)-Math.round(w1)};
+ h=Math.min(MAX_HEIGHT-hCover-GAP, h);
+ if(hCover+h tries=new HashMap<>();
// One line
- int firstLine, secondLine, thirdLine;
- tries.put(new int[]{firstLine=cnt}, new float[]{calculateMultiThumbsHeight(ratiosCropped, maxW, marginW)});
+ int firstLine, secondLine;
+ tries.put(new int[]{cnt}, new float[]{calculateMultiThumbsHeight(ratiosCropped, MAX_WIDTH, GAP)});
// Two lines
for(firstLine=1; firstLine<=cnt-1; firstLine++){
- tries.put(new int[]{firstLine, secondLine=cnt-firstLine}, new float[]{
- calculateMultiThumbsHeight(ratiosCropped.subList(0, firstLine), maxW, marginW),
- calculateMultiThumbsHeight(ratiosCropped.subList(firstLine, ratiosCropped.size()), maxW, marginW)
+ tries.put(new int[]{firstLine, cnt-firstLine}, new float[]{
+ calculateMultiThumbsHeight(ratiosCropped.subList(0, firstLine), MAX_WIDTH, GAP),
+ calculateMultiThumbsHeight(ratiosCropped.subList(firstLine, ratiosCropped.size()), MAX_WIDTH, GAP)
}
);
}
@@ -189,23 +206,24 @@ public class PhotoLayoutHelper{
// Three lines
for(firstLine=1; firstLine<=cnt-2; firstLine++){
for(secondLine=1; secondLine<=cnt-firstLine-1; secondLine++){
- tries.put(new int[]{firstLine, secondLine, thirdLine=cnt-firstLine-secondLine}, new float[]{
- calculateMultiThumbsHeight(ratiosCropped.subList(0, firstLine), maxW, marginW),
- calculateMultiThumbsHeight(ratiosCropped.subList(firstLine, firstLine+secondLine), maxW, marginW),
- calculateMultiThumbsHeight(ratiosCropped.subList(firstLine+secondLine, ratiosCropped.size()), maxW, marginW)
+ tries.put(new int[]{firstLine, secondLine, cnt-firstLine-secondLine}, new float[]{
+ calculateMultiThumbsHeight(ratiosCropped.subList(0, firstLine), MAX_WIDTH, GAP),
+ calculateMultiThumbsHeight(ratiosCropped.subList(firstLine, firstLine+secondLine), MAX_WIDTH, GAP),
+ calculateMultiThumbsHeight(ratiosCropped.subList(firstLine+secondLine, ratiosCropped.size()), MAX_WIDTH, GAP)
}
);
}
}
- // Looking for minimum difference between thumbs block height and maxH (may probably be little over)
+ // Looking for minimum difference between thumbs block height and maxHeight (may probably be little over)
+ final int realMaxHeight=Math.min(MAX_HEIGHT, MAX_WIDTH);
int[] optConf=null;
float optDiff=0;
for(int[] conf : tries.keySet()){
float[] heights=tries.get(conf);
- float confH=marginH*(heights.length-1);
+ float confH=GAP*(heights.length-1);
for(float h : heights) confH+=h;
- float confDiff=Math.abs(confH-maxH);
+ float confDiff=Math.abs(confH-realMaxHeight);
if(conf.length>1){
if(conf[0]>conf[1] || conf.length>2 && conf[1]>conf[2]){
confDiff*=1.1;
@@ -222,7 +240,7 @@ public class PhotoLayoutHelper{
float[] optHeights=tries.get(optConf);
int k=0;
- result.width=Math.round(maxW);
+ result.width=MAX_WIDTH;
result.rowSizes=new int[optHeights.length];
result.tiles=new TiledLayoutResult.Tile[thumbs.size()];
float totalHeight=0f;
@@ -240,11 +258,11 @@ public class PhotoLayoutHelper{
ArrayList row=new ArrayList<>();
for(int j=0; j0; i--){
@@ -276,7 +294,7 @@ public class PhotoLayoutHelper{
columnOffset+=tile.colSpan;
}
}
- result.height=Math.round(totalHeight+marginH*(optHeights.length-1));
+ result.height=Math.round(totalHeight+GAP*(optHeights.length-1));
}
return result;
@@ -310,19 +328,19 @@ public class PhotoLayoutHelper{
}
public static class Tile{
- public int colSpan, rowSpan, width, height, startCol, startRow;
+ public int colSpan, rowSpan, startCol, startRow;
+ public int width;
- public Tile(int colSpan, int rowSpan, int width, int height, int startCol, int startRow){
+ public Tile(int colSpan, int rowSpan, int startCol, int startRow){
this.colSpan=colSpan;
this.rowSpan=rowSpan;
- this.width=width;
- this.height=height;
this.startCol=startCol;
this.startRow=startRow;
}
- public Tile(int colSpan, int rowSpan, float width, float height, int startCol, int startRow){
- this(colSpan, rowSpan, Math.round(width), Math.round(height), startCol, startRow);
+ public Tile(int colSpan, int rowSpan, int startCol, int startRow, int width){
+ this(colSpan, rowSpan, startCol, startRow);
+ this.width=width;
}
@Override
@@ -330,8 +348,8 @@ public class PhotoLayoutHelper{
return "Tile{"+
"colSpan="+colSpan+
", rowSpan="+rowSpan+
- ", width="+width+
- ", height="+height+
+ ", startCol="+startCol+
+ ", startRow="+startRow+
'}';
}
}
diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/AccountCardStatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/AccountCardStatusDisplayItem.java
index 5561c07ae..5defaa937 100644
--- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/AccountCardStatusDisplayItem.java
+++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/AccountCardStatusDisplayItem.java
@@ -133,6 +133,10 @@ public class AccountCardStatusDisplayItem extends StatusDisplayItem{
followersLabel.setText(item.parentFragment.getResources().getQuantityString(R.plurals.followers, (int)Math.min(999, item.account.followersCount)));
followingLabel.setText(item.parentFragment.getResources().getQuantityString(R.plurals.following, (int)Math.min(999, item.account.followingCount)));
postsLabel.setText(item.parentFragment.getResources().getQuantityString(R.plurals.posts, (int)Math.min(999, item.account.statusesCount)));
+ followersCount.setVisibility(item.account.followersCount < 0 ? View.GONE : View.VISIBLE);
+ followersLabel.setVisibility(item.account.followersCount < 0 ? View.GONE : View.VISIBLE);
+ followingCount.setVisibility(item.account.followingCount < 0 ? View.GONE : View.VISIBLE);
+ followingLabel.setVisibility(item.account.followingCount < 0 ? View.GONE : View.VISIBLE);
relationship=item.parentFragment.getRelationship(item.account.id);
if(item.notification.type == Notification.Type.FOLLOW_REQUEST && (relationship == null || !relationship.followedBy)){
actionWrap.setVisibility(View.GONE);
diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/ExtendedFooterStatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/ExtendedFooterStatusDisplayItem.java
index b87602c29..643705bce 100644
--- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/ExtendedFooterStatusDisplayItem.java
+++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/ExtendedFooterStatusDisplayItem.java
@@ -76,10 +76,8 @@ public class ExtendedFooterStatusDisplayItem extends StatusDisplayItem{
public void onBind(ExtendedFooterStatusDisplayItem item){
Status s=item.status;
favorites.setText(context.getResources().getQuantityString(R.plurals.x_favorites, (int)(s.favouritesCount%1000), s.favouritesCount));
-
reblogs.setText(context.getResources().getQuantityString(R.plurals.x_reblogs, (int) (s.reblogsCount % 1000), s.reblogsCount));
- if (!s.canBeBoosted(item.accountID))
- reblogs.setVisibility(View.GONE);
+ reblogs.setVisibility(s.isReblogPermitted(item.accountID) ? View.VISIBLE : View.GONE);
if(s.editedAt!=null){
editHistory.setVisibility(View.VISIBLE);
@@ -88,7 +86,7 @@ public class ExtendedFooterStatusDisplayItem extends StatusDisplayItem{
editHistory.setVisibility(View.GONE);
}
String timeStr=item.status.createdAt != null ? TIME_FORMATTER.format(item.status.createdAt.atZone(ZoneId.systemDefault())) : null;
-
+
if (item.status.application!=null && !TextUtils.isEmpty(item.status.application.name)) {
time.setText(timeStr != null ? item.parentFragment.getString(R.string.timestamp_via_app, timeStr, "") : "");
applicationName.setText(item.status.application.name);
@@ -143,4 +141,4 @@ public class ExtendedFooterStatusDisplayItem extends StatusDisplayItem{
Nav.go(item.parentFragment.getActivity(), StatusEditHistoryFragment.class, args);
}
}
-}
\ No newline at end of file
+}
diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/FooterStatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/FooterStatusDisplayItem.java
index bf08ad654..9f45de6fe 100644
--- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/FooterStatusDisplayItem.java
+++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/FooterStatusDisplayItem.java
@@ -147,8 +147,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
boost.setSelected(item.status.reblogged);
favorite.setSelected(item.status.favourited);
bookmark.setSelected(item.status.bookmarked);
- boost.setEnabled(item.status.visibility==StatusPrivacy.PUBLIC || item.status.visibility==StatusPrivacy.UNLISTED || item.status.visibility==StatusPrivacy.LOCAL
- || (item.status.visibility==StatusPrivacy.PRIVATE && item.status.account.id.equals(AccountSessionManager.getInstance().getAccount(item.accountID).self.id)));
+ boost.setEnabled(item.status.isReblogPermitted(item.accountID));
int nextPos = getAbsoluteAdapterPosition() + 1;
boolean nextIsWarning = item.parentFragment.getDisplayItems().size() > nextPos &&
@@ -187,9 +186,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
} else if (action == MotionEvent.ACTION_DOWN) {
longClickPerformed = false;
touchingView = v;
- // 28dp to center in middle of icon, because:
- // (icon width = 24dp) / 2 + (paddingStart = 8dp) + (paddingHorizontal = 8dp)
- v.setPivotX(UiUtils.sp(v.getContext(), 28));
+ v.setPivotX(V.sp(28));
v.animate().scaleX(0.85f).scaleY(0.85f).setInterpolator(CubicBezierInterpolator.DEFAULT).setDuration(75).start();
if (disabled) return true;
v.postDelayed(longClickRunnable, ViewConfiguration.getLongPressTimeout());
diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/HeaderStatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/HeaderStatusDisplayItem.java
index 78295c5a8..1a9e75f3c 100644
--- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/HeaderStatusDisplayItem.java
+++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/HeaderStatusDisplayItem.java
@@ -425,6 +425,9 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
else collapseBtnIcon.animate().scaleY(item.status.textExpanded ? -1 : 1).start();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) collapseBtn.setTooltipText(collapseText);
}
+
+ itemView.setPaddingRelative(itemView.getPaddingStart(), itemView.getPaddingTop(),
+ item.inset ? V.dp(10) : V.dp(4), itemView.getPaddingBottom());
}
@Override
diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/MediaGridStatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/MediaGridStatusDisplayItem.java
index 984efddb4..5195b67b4 100644
--- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/MediaGridStatusDisplayItem.java
+++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/MediaGridStatusDisplayItem.java
@@ -10,6 +10,7 @@ import android.app.Activity;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
+import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
@@ -25,7 +26,9 @@ import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.ui.PhotoLayoutHelper;
import org.joinmastodon.android.ui.photoviewer.PhotoViewerHost;
import org.joinmastodon.android.ui.utils.MediaAttachmentViewController;
+import org.joinmastodon.android.ui.utils.UiUtils;
import org.joinmastodon.android.ui.views.FrameLayoutThatOnlyMeasuresFirstChild;
+import org.joinmastodon.android.ui.views.MaxWidthFrameLayout;
import org.joinmastodon.android.ui.views.MediaGridLayout;
import org.joinmastodon.android.utils.TypedObjectPool;
@@ -88,6 +91,7 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
private final View.OnClickListener clickListener=this::onViewClick, altTextClickListener=this::onAltTextClick;
private final ArrayList controllers=new ArrayList<>();
+ private final MaxWidthFrameLayout overlays;
private final FrameLayout altTextWrapper;
private final TextView altTextButton;
private final ImageView noAltTextButton;
@@ -105,8 +109,13 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
wrapper=(FrameLayout)itemView;
layout=new MediaGridLayout(activity);
wrapper.addView(layout);
+ wrapper.setClipToPadding(false);
- activity.getLayoutInflater().inflate(R.layout.overlay_image_alt_text, wrapper);
+ overlays=new MaxWidthFrameLayout(activity);
+ overlays.setMaxWidth(UiUtils.MAX_WIDTH);
+ wrapper.addView(overlays, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER_HORIZONTAL));
+
+ activity.getLayoutInflater().inflate(R.layout.overlay_image_alt_text, overlays);
altTextWrapper=findViewById(R.id.alt_text_wrapper);
altTextButton=findViewById(R.id.alt_button);
noAltTextButton=findViewById(R.id.no_alt_button);
@@ -215,7 +224,7 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
int[] loc={0, 0};
v.getLocationInWindow(loc);
int btnL=loc[0], btnT=loc[1];
- wrapper.getLocationInWindow(loc);
+ overlays.getLocationInWindow(loc);
btnL-=loc[0];
btnT-=loc[1];
@@ -278,7 +287,7 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
int[] loc={0, 0};
btn.getLocationInWindow(loc);
int btnL=loc[0], btnT=loc[1];
- wrapper.getLocationInWindow(loc);
+ overlays.getLocationInWindow(loc);
btnL-=loc[0];
btnT-=loc[1];
diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java
index 9795ca26b..e07aeb69a 100644
--- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java
+++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java
@@ -105,6 +105,21 @@ public abstract class StatusDisplayItem{
return buildItems(fragment, status, accountID, parentObject, knownAccounts, inset, addFooter, notification, false, filterContext);
}
+ public static ReblogOrReplyLineStatusDisplayItem buildReplyLine(BaseStatusListFragment> fragment, Status status, String accountID, DisplayItemsParent parent, Account account, boolean threadReply) {
+ String parentID = parent.getID();
+ String text = threadReply ? fragment.getString(R.string.sk_show_thread)
+ : account == null ? fragment.getString(R.string.sk_in_reply)
+ : GlobalUserPreferences.compactReblogReplyLine && status.reblog != null ? account.displayName
+ : fragment.getString(R.string.in_reply_to, account.displayName);
+ String fullText = threadReply ? fragment.getString(R.string.sk_show_thread)
+ : account == null ? fragment.getString(R.string.sk_in_reply)
+ : fragment.getString(R.string.in_reply_to, account.displayName);
+ return new ReblogOrReplyLineStatusDisplayItem(
+ parentID, fragment, text, account == null ? List.of() : account.emojis,
+ R.drawable.ic_fluent_arrow_reply_20sp_filled, null, null, fullText
+ );
+ }
+
public static ArrayList buildItems(BaseStatusListFragment> fragment, Status status, String accountID, DisplayItemsParent parentObject, Map knownAccounts, boolean inset, boolean addFooter, Notification notification, boolean disableTranslate, Filter.FilterContext filterContext){
String parentID=parentObject.getID();
ArrayList items=new ArrayList<>();
@@ -120,17 +135,7 @@ public abstract class StatusDisplayItem{
if(statusForContent.inReplyToAccountId!=null && !(threadReply && fragment instanceof ThreadFragment)){
Account account = knownAccounts.get(statusForContent.inReplyToAccountId);
- String text = threadReply ? fragment.getString(R.string.sk_show_thread)
- : account == null ? fragment.getString(R.string.sk_in_reply)
- : GlobalUserPreferences.compactReblogReplyLine && status.reblog != null ? account.displayName
- : fragment.getString(R.string.in_reply_to, account.displayName);
- String fullText = threadReply ? fragment.getString(R.string.sk_show_thread)
- : account == null ? fragment.getString(R.string.sk_in_reply)
- : fragment.getString(R.string.in_reply_to, account.displayName);
- replyLine = new ReblogOrReplyLineStatusDisplayItem(
- parentID, fragment, text, account == null ? List.of() : account.emojis,
- R.drawable.ic_fluent_arrow_reply_20sp_filled, null, null, fullText
- );
+ replyLine = buildReplyLine(fragment, status, accountID, parentObject, account, threadReply);
}
if(status.reblog!=null){
diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java b/mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java
index c3b5243ed..12427c134 100644
--- a/mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java
+++ b/mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java
@@ -1307,7 +1307,7 @@ public class UiUtils {
go.accept(ProfileFragment.class, args);
return;
}
- go.accept(null, bundleError(context.getString(R.string.sk_resource_not_found)));
+ go.accept(null, null);
}
@Override
@@ -1499,16 +1499,6 @@ public class UiUtils {
}
}
- /**
- * Scale the input value according to the device's scaled display density
- * @param sp Input value in scale-independent pixels (sp)
- * @return Scaled value in physical pixels (px)
- */
- public static int sp(Context context, float sp){
- // TODO: replace with V.sp in next AppKit version
- return Math.round(sp*context.getApplicationContext().getResources().getDisplayMetrics().scaledDensity);
- }
-
/**
* Wraps a View.OnClickListener to filter multiple clicks in succession.
* Useful for buttons that perform some action that changes their state asynchronously.
diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/views/MediaGridLayout.java b/mastodon/src/main/java/org/joinmastodon/android/ui/views/MediaGridLayout.java
index 7d6c49624..4f9cbbed6 100644
--- a/mastodon/src/main/java/org/joinmastodon/android/ui/views/MediaGridLayout.java
+++ b/mastodon/src/main/java/org/joinmastodon/android/ui/views/MediaGridLayout.java
@@ -13,7 +13,7 @@ import me.grishka.appkit.utils.V;
public class MediaGridLayout extends ViewGroup{
private static final String TAG="MediaGridLayout";
- private static final int GAP=1; // dp
+ private static final int GAP=2; // dp
private PhotoLayoutHelper.TiledLayoutResult tiledLayout;
private int[] columnStarts=new int[10], columnEnds=new int[10], rowStarts=new int[10], rowEnds=new int[10];
@@ -37,6 +37,9 @@ public class MediaGridLayout extends ViewGroup{
}
int width=Math.min(UiUtils.MAX_WIDTH, MeasureSpec.getSize(widthMeasureSpec));
int height=Math.round(width*(tiledLayout.height/(float)PhotoLayoutHelper.MAX_WIDTH));
+ if(tiledLayout.widthUiUtils.MAX_WIDTH){
- xOffset=(r-l)/2-UiUtils.MAX_WIDTH/2;
+ if(r-l>maxWidth){
+ xOffset=(r-l)/2-maxWidth/2;
}
for(int i=0;i allLanguages;
public static final MastodonLanguage ENGLISH = new MastodonLanguage("en", "English", "English");
diff --git a/mastodon/src/main/res/layout/display_item_header.xml b/mastodon/src/main/res/layout/display_item_header.xml
index c46261022..eccf9cc48 100644
--- a/mastodon/src/main/res/layout/display_item_header.xml
+++ b/mastodon/src/main/res/layout/display_item_header.xml
@@ -6,79 +6,79 @@
android:paddingEnd="4dp"
android:paddingStart="16dp">
-
-
-
-
-
-
-
-
-
+ android:layout_alignParentEnd="true">
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
-
@@ -127,7 +127,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
- android:layout_toStartOf="@id/unread_indicator"
+ android:layout_toStartOf="@id/buttons"
android:layout_toEndOf="@id/avatar"
android:layout_alignBottom="@id/avatar"
android:layoutDirection="locale"
diff --git a/mastodon/src/main/res/layout/overlay_image_alt_text.xml b/mastodon/src/main/res/layout/overlay_image_alt_text.xml
index 713926ea8..ff7ed747d 100644
--- a/mastodon/src/main/res/layout/overlay_image_alt_text.xml
+++ b/mastodon/src/main/res/layout/overlay_image_alt_text.xml
@@ -43,7 +43,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
- android:layout_marginEnd="40dp">
+ android:layout_marginEnd="40dp"
+ android:minWidth="40dp">
+ android:title="@string/sk_settings_auto_reveal_nobody" />
+ android:title="@string/sk_settings_auto_reveal_author" />
+ android:title="@string/sk_settings_auto_reveal_anyone" />
\ No newline at end of file
diff --git a/mastodon/src/main/res/menu/settings_prefix_reply_mode.xml b/mastodon/src/main/res/menu/settings_prefix_reply_mode.xml
new file mode 100644
index 000000000..5ecccbeee
--- /dev/null
+++ b/mastodon/src/main/res/menu/settings_prefix_reply_mode.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mastodon/src/main/res/values-ar-rDZ/strings_sk.xml b/mastodon/src/main/res/values-ar-rDZ/strings_sk.xml
deleted file mode 100644
index 3668745aa..000000000
--- a/mastodon/src/main/res/values-ar-rDZ/strings_sk.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
- هل أنت متأكد أنك تريد حذف وإعادة صياغة هذا المنشور؟
- غير مدرج
- القوائم
- طلبات المتابعة
- مدبّس
- حذف وإعادة الصياغة
- حذف وإعادة صياغة الرسالة
- تدبيس على الصفحة الشخصية
- تدبيس الرسالة على الصفحة الشخصية
- إظهار الخيط الفديرالي
- المساهمة في Megalodon
- قبول طلب المتابعة
- رفض طلب المتابعة
- قوائم بها %s
-
\ No newline at end of file
diff --git a/mastodon/src/main/res/values-ar-rSA/strings_sk.xml b/mastodon/src/main/res/values-ar-rSA/strings_sk.xml
deleted file mode 100644
index 045e125f3..000000000
--- a/mastodon/src/main/res/values-ar-rSA/strings_sk.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/mastodon/src/main/res/values-ar/strings_sk.xml b/mastodon/src/main/res/values-ar/strings_sk.xml
index c8aea7a8d..f4183214f 100644
--- a/mastodon/src/main/res/values-ar/strings_sk.xml
+++ b/mastodon/src/main/res/values-ar/strings_sk.xml
@@ -2,7 +2,16 @@
هل أنت متأكد أنك تريد حذف وإعادة صياغة هذا المنشور؟
تثبيت في الملف الشخصي
- مثبت
+ المُثَبَّتَة
حذف وإعادة صياغة
حذف وإعادة صياغة المنشور
+ غير مدرج
+ القوائم
+ طلبات المتابعة
+ تدبيس الرسالة على الصفحة الشخصية
+ إظهار الخيط الفديرالي
+ المساهمة في Megalodon
+ قبول طلب المتابعة
+ رفض طلب المتابعة
+ قوائم بها %s
\ No newline at end of file
diff --git a/mastodon/src/main/res/values-de-rDE/strings_sk.xml b/mastodon/src/main/res/values-de-rDE/strings_sk.xml
index 6563b2f26..0842a28e0 100644
--- a/mastodon/src/main/res/values-de-rDE/strings_sk.xml
+++ b/mastodon/src/main/res/values-de-rDE/strings_sk.xml
@@ -101,7 +101,7 @@
Bereits geteilt
Antworten mit anderem Konto
Einheitliches Icon für alle Benachrichtigungen
- Weiterleiten zu %s
+ Weiterleiten an %s
Nicht gesendete Beiträge
Entwurf
Planen
@@ -250,7 +250,7 @@
“Neue Beiträge anzeigen”-Button
Server-Version: %s
Umfrage-Ergebnisse
- CWs beim Antworten “re:” voranstellen
+ Voranstellen von „re:“ an CWs in Antworten an
Gefiltert: %s
Erweitern
Einklappen
@@ -296,4 +296,12 @@
keine Remote-Infos abrufbar
Konnte das Profil via %s nicht laden
Für vollständigere Auflistung von Follower*innen, Likes und Boosts können die Informationen von der Ursprungs-Instanz geladen werden.
+ Zeigen von gleichen CWs in Antworten von
+ niemandem
+ Autor*in
+ allen
+ andere
+ alle
+ niemanden
+ Standardwert „Meldung weiterleiten“-Schalter
\ No newline at end of file
diff --git a/mastodon/src/main/res/values-es-rES/strings_sk.xml b/mastodon/src/main/res/values-es-rES/strings_sk.xml
index c0a685e9a..db33576db 100644
--- a/mastodon/src/main/res/values-es-rES/strings_sk.xml
+++ b/mastodon/src/main/res/values-es-rES/strings_sk.xml
@@ -245,9 +245,9 @@
Glitch modo sólo local
Habilita esta opción si tu instancia local funciona con Glitch. No es necesario para Hometown o Akkoma.
registrado
- reportado
+ denunciado
Registro de usuarios
- Nuevos informes
+ Nuevas denuncias
Versión de servidor: %s
Resultado de encuestas
Filtrado: %s
@@ -256,7 +256,7 @@
Minimizar publicaciones largas
¿Corregir adjuntos\?
Algunos adjuntos no han terminado de subirse.
- Añadir \"re:\" a respuestas a Advertencias de Contenido
+ Añadir \"re:\" a Advertencias de Contenido para
Modo espectador
Ocultar los botones de interacción
Seguir desde otra cuenta
@@ -286,10 +286,23 @@
Contenido por defecto
Permite establecer un tipo de contenido como Markdown al crear una entrada. Ten en cuenta que no todas las instancias lo admiten.
Permite preseleccionar un tipo de contenido al crear nuevas entradas, anulando el valor establecido en \"Preferencias de publicación\".
- Estas son las publicaciones más recientes de la gente en tu servidor de Akkoma.
+ Estas son las publicaciones más recientes de la red seleccionadas por los administradores de tu instancia.
Burbuja
Información de la instancia temporalmente no disponible
Compartir o abrir con una cuenta
Abrir en la app
Compartir con una cuenta
+ Mostrar CW iguales en las respuestas de
+ nadie
+ autor
+ todos
+ No se pudo abrir en la aplicación
+ no hay información remota disponible
+ No se pudo cargar el perfil a través de %s
+ Cargar la información desde las instancias remotas
+ Intenta obtener listas más precisas de seguidores, Me gusta y promociones cargando la información desde la instancia de origen.
+ Todas
+ Ninguna
+ A otros
+ \"Reenviar denuncia\" activado por defecto
\ No newline at end of file
diff --git a/mastodon/src/main/res/values-fa-rIR/strings.xml b/mastodon/src/main/res/values-fa-rIR/strings.xml
index f09140ec9..332e8c711 100644
--- a/mastodon/src/main/res/values-fa-rIR/strings.xml
+++ b/mastodon/src/main/res/values-fa-rIR/strings.xml
@@ -12,51 +12,85 @@
در پاسخ به %s
اعلانها
شما را دنبال میکند
- یک درخواست دنبال کردن برای شما ارسال کرد
+ یک درخواست پیگیری برای شما ارسال کرد
فرستهتان را پسندید
+ فرستهٔ شما را تقویت کرد
نظرسنجی به پایان رسید
%dثانیه
%dدقیقه
%dساعت
%dروز
- اشتراکگذاری
+ همرسانی
تنظیمات
انتشار
پیشنویس کنار گذاشته شود؟
صرفنظر کردن
لغو
- پستها
- پستها و پاسخها
+
+ - پیگیرنده
+ - پیگیرندگان
+
+
+ - فرسته
+ - فرستهها
+
+ فرستهها
+ فرستهها و پاسخها
رسانه
درباره
- فالو
+ پیگیری
+ ویرایش نمایه
اشتراکگذاری %s
بیصدا %s
+ ناخموشی %s
مسدود %s
رفع مسدودیت %s
+ گزارش کردن %s
عضو شد
انجام شد
درحال بارگذاری…
برچسب
محتوا
درحال ذخیرهسازی…
+ پایانیافته
+ خموشی حساب
بیصدا
+ لغو خموشی حساب
+ ناخموشی
+ مسدود کردن حساب
+ مسدود کردن دامنهٔ
مسدود
+ رفع مسدودی حساب
+ رفع مسدودیت دامنهٔ
+ رفع مسدودیت
+ خموش
+ مسدود شده
رأی
حذف
- حذف پست
+ حذف فرسته
پخش
توقف
+ خروج
+ افزودن حساب
جستجو
- هشتگها
+ برچسبها
اخبار
برای شما
همه
گزارش کردن %s
من این را دوست ندارم
این هرزنامه است
+ درحال ارسال گزارش…
+ پینگرفتن
بازگشت
+ قوانین کارساز
+ ایجاد حساب
ویرایش
+ نام
+ نام کاربری
+ رایانامه
+ گذرواژه
+ تأیید گذرواژه
فعالیت
همه
هنر
@@ -68,34 +102,118 @@
فناوری
ارسال دوباره
+ بارگذاری مجدد
+ ویرایش تصویر
ذخیره
عمومی
+ فقط پیگیرندگان
همه
افراد
بعدی
علاقهمندیها
+ تقویتها
نظرسنجیها
انتخاب حساب
خودکار
روشن
تاریک
- پست جدید
+ فرسته جدید
پاسخ
+ تقویت
برگزیده
اشتراکگذاری
+ افزودن رسانه
+ افزودن نظرسنجی
ایموجی
+ نمایه من
+ پیگیری %s
+ پینگرفتن %s
+ بازکردن در مرورگر
پاککردن
- دانلود
+ بارگیری
+ باز کردن تنظیمات
+ پرونده ذخیره شد
+ درحال بارگیری…
+ اجتماع
+ پیگیرتان است
+
+ - %,d پسندیده
+ - %,d پسندیدهها
+
اکنون
+ تقویتها
+ علاقهمندیها
+ آخرین ویرایش %s
همين الان
+
+ - %d ثانیه پیش
+ - %d ثانیه پیش
+
+
+ - %d دقیقه پیش
+ - %d دقیقه پیش
+
+ فرستهٔ اصلی
+ متن ویرایش شد
+ هشدار محتوا افزوده شد
+ هشدار محتوا ویرایش شد
+ هشدار محتوا برداشته شد
+ نظرسنجی اضافه شد
+ نظرسنجی ویرایش شد
+ نظرسنجی برداشته شد
+ رسانه اضافه شد
+ رسانه برداشته شد
+ فرسته ویرایش شد
ویرایش
+ بارگذاری ناموفق بود
+ %d بایت
+ %.2f کیلوبایت
+ %.2f مگابایت
+ %.2f گیگابایت
+ در حال پردازش…
+ ماستودون برای اندروید %s آماده بارگیری است.
+ ماستودون برای اندروید %s بارگیری شده و آماده نصب است.
+ بارگیری (%s)
نصب
+ حریم خصوصی شما
موافقم
+ در تختهگیره رونوشت شد
+ نشانک
+ برداشتن نشانک
+ نشانکها
+ علاقهمندی های شما
+ هر زبانی
+ اروپا
+ آمریکای شمالی
+ آمریکای جنوبی
+ آفریقا
+ آسیا
+ اقیانوسیه
+ افزودن سطر
+ تنظیم نمایه
+ محبوب در ماستودون
+ پیگیری همه
+ دربارهٔ شما
+ به هرصورت نشان داده شود
+ نهفتن دوباره
+ یک یا چند مورد را انتخاب کنید
+ ذخیرهٔ تغییرات
+ خط زمانی
+ مشاهده همه
+ حسابها
+ پیوند تأییدشده
+ نمایش
+ نهفتن
+ %s پیوست
+ انتخاب کارسازی دیگر
+ یا
+ بیشتر بیاموزید
+ به ماستودون خوش آمدید
diff --git a/mastodon/src/main/res/values-fa/strings_sk.xml b/mastodon/src/main/res/values-fa/strings_sk.xml
new file mode 100644
index 000000000..9a1a43bbe
--- /dev/null
+++ b/mastodon/src/main/res/values-fa/strings_sk.xml
@@ -0,0 +1,73 @@
+
+
+ سنجاق شده
+ سنجاق فرسته به نمایه
+ مگالودون
+ سنجاق به نمایه
+ درحال سنجاق کردن فرسته…
+ برداشتن سنجاق از نمایه
+ برداشتن سنجاق فرسته از نمایه
+ درحال برداشتن سنجاق فرسته…
+ توضیحات تصویر
+ فهرست نشده
+ نمایش پاسخها
+ سیاههها
+ فرستهها
+ بهروزرسانی موجود نیست
+ همه پاسخها
+ علامتگذاری رسانه به عنوان حساس
+ مگالودون %s آماده بارگیری است.
+ درخواستهای پیگیری
+ پذیرفتن درخواست پیگیری
+ رد درخواست پیگیری
+ اعلانهای فرسته
+ سامانه
+ صورتی
+ بنفش
+ سبز
+ آبی
+ قهوهای
+ قرمز
+ زرد
+ ترجمه
+ زبان: %s
+ زبان های موجود
+ خوش آمدید!
+ %1$s (%2$s)
+ تنظیم نمایه
+ پیکربندی پالایه
+ تنظیمات امنیتی
+ درباره کاره
+ اعانه
+ پاکسازی همه اعلانات
+ حذف همه
+ متن دکمه انتشار
+ سفارشیسازی متن دکمه انتشار
+ برگردان تقویت
+ قوانین
+ بستن
+ باز کردن
+ نتایج نظرسنجی
+ نسخه کارساز: %s
+ حالت فقط محلی Glitch
+ فقط محلی
+ به کار انداختن پیش انتشار
+ ذخیره پیش نویس؟
+ بدون نتیجه
+ درحال جستجو…
+ پیوست پرونده
+ ویرایش شده
+ مارکدون
+ HTML
+ متن ساده
+ بررسی برای بهروزرسانی
+ کارساز از فرسته فقط محلی پشتیبانی میکند
+ نمایش تقویتها
+ فرستههای ویرایش شده
+ مگالودون %s بارگیری شده و آماده نصب است.
+ اجازه انتخاب های متعدد
+ باز کردن با حساب دیگر
+ حذف پیش نویس
+ پیشنویس
+ پیش نویس ذخیره شد
+
\ No newline at end of file
diff --git a/mastodon/src/main/res/values-fr-rFR/strings_sk.xml b/mastodon/src/main/res/values-fr-rFR/strings_sk.xml
index 5f8a8baad..ad02d688d 100644
--- a/mastodon/src/main/res/values-fr-rFR/strings_sk.xml
+++ b/mastodon/src/main/res/values-fr-rFR/strings_sk.xml
@@ -254,7 +254,7 @@
Développer
Réduire
Réduire les messages très longs
- Préfixe \"re :\" lors d\'une réponse avec AC
+ Préfixe les AC avec \"re :\" sur les réponses à
Filtré : %s
Corriger les pièces jointes \?
Certaines pièces jointes n\'ont pas fini de se télécharger.
@@ -294,4 +294,16 @@
Bulle
Informations sur l\'instance temporairement indisponibles
Impossible de l\'ouvrir dans l\'application
+ Charger des informations à partir d\'instances distantes
+ informations distantes indisponibles
+ Échec du chargement du profil via %s
+ Essayez de récupérer des listes plus précises pour les abonnés, les likes et les boosts en chargeant les informations à partir de l\'instance d\'origine.
+ Révéler les AC identiques dans les réponses de
+ personne
+ auteur
+ tout le monde
+ tout le monde
+ personne
+ autres
+ \"Transférer le rapport\" par défaut
\ No newline at end of file
diff --git a/mastodon/src/main/res/values-hr-rHR/strings_sk.xml b/mastodon/src/main/res/values-hr-rHR/strings_sk.xml
index 1865b164d..9e6dbd414 100644
--- a/mastodon/src/main/res/values-hr-rHR/strings_sk.xml
+++ b/mastodon/src/main/res/values-hr-rHR/strings_sk.xml
@@ -181,7 +181,7 @@
Vaša početna instanca mora podržavati isključivo-lokalno objavljivanje da bi ovo radilo. Većina modificiranih verzija Mastodona to radi, ali Mastodon ne.
Sakrij gumbe za interakciju
Automatski sakrij gumb \"Nova objava\"
- "Citiranje %"
+ Citiranje %s
Vidljivost odgovora
Svi odgovori
Odgovori onima koje pratim
diff --git a/mastodon/src/main/res/values-in-rID/strings.xml b/mastodon/src/main/res/values-in-rID/strings.xml
index 24b13b587..66acd5d86 100644
--- a/mastodon/src/main/res/values-in-rID/strings.xml
+++ b/mastodon/src/main/res/values-in-rID/strings.xml
@@ -10,7 +10,7 @@
Oke
Menyiapkan untuk autentikasi…
Menyelesaikan autentikasi…
- %s di-boost-kan
+ %s membagikan
Membalas ke %s
Notifikasi
mengikuti Anda
@@ -417,6 +417,7 @@
Tampilkan
Sembunyikan
Gabung %s
+ Cari server lain
atau
Pelajari lebih lanjut
Selamat datang di Mastodon
diff --git a/mastodon/src/main/res/values-in-rID/strings_sk.xml b/mastodon/src/main/res/values-in-rID/strings_sk.xml
index e7caf9de2..32a6e2498 100644
--- a/mastodon/src/main/res/values-in-rID/strings_sk.xml
+++ b/mastodon/src/main/res/values-in-rID/strings_sk.xml
@@ -289,8 +289,17 @@
Memperbolehkan menetapkan jenis konten seperti Markdown ketika membuat kiriman. Perlu diingat bahwa tidak semua server mendukung ini.
Buka dalam aplikasi
Bagikan dengan akun
- Ini adalah kiriman yamg paling terkini oleh orang-orang dalam gelembung server Akkoma Anda.
+ Ini adalah kiriman yang paling terkini dari jaringan dikurasikan oleh admin server Anda.
Gelembung
Info server sementara tidak tersedia
Bagikan atau buka dengan akun
+ info jarak jauh tidak tersedia
+ Muat info dari server jarak jauh
+ Coba mendapatkan pendaftaran akurat untuk pengikut cr
+ Gagal memuat profil melalui %s
+ Tidak dapat buka dalam aplikasi
+ Tampilkan peringatan konten yang sama dari
+ bukan siapa pun
+ pembuat
+ semuanya
\ No newline at end of file
diff --git a/mastodon/src/main/res/values-it-rIT/strings_sk.xml b/mastodon/src/main/res/values-it-rIT/strings_sk.xml
index 2b221b6ad..4891177d0 100644
--- a/mastodon/src/main/res/values-it-rIT/strings_sk.xml
+++ b/mastodon/src/main/res/values-it-rIT/strings_sk.xml
@@ -153,7 +153,7 @@
Timeline
Post
Aggiungi
- Linea temporale
+ Timeline
Lista
Hashtag
Fissa timeline
@@ -274,8 +274,17 @@
Linea boost/risposta compatta
ha reagito con %s
Linea \"In risposta a\" sopra l\'avatar
- Tasto \"Mostra nuovi post\"
+ Questi sono i post più recenti della rete, curati dagli amministratori della tua istanza.
+ Permette di impostare un tipo di contenuto, come Markdown, quando si crea un post. Tieni presente che non tutte le istanze lo supportano.
+ Impossibile aprire nell\'app
+ Condividi con l\'account
+ Condividi o apri con l\'account
+ Informazioni remote non disponibili
+ Impossibile caricare il profilo tramite %s
+ Carica informazioni da istanze remote
+ Cerca di ottenere elenchi più accurati di follower, like e boost caricando le informazioni dall\'istanza di origine.
Tipo di contenuto
+ Bolla
Non specificato
Testo semplice
HTML
@@ -283,7 +292,8 @@
BBCode
MFM
Abilita la formattazione dei post
- Permette di impostare un tipo di contenuto, come Markdown, quando si crea un post. Tieni presente che non tutte le istanze lo supportano.
Tipo di contenuto predefinito
Ti permette di preselezionare un tipo di contenuto quando si creano nuovi post, sovrascrivendo il valore impostato in \"Preferenze di pubblicazione\".
+ Informazioni sull\'istanza temporaneamente non disponibili
+ Apri nell\'app
\ No newline at end of file
diff --git a/mastodon/src/main/res/values-nl-rNL/strings_sk.xml b/mastodon/src/main/res/values-nl-rNL/strings_sk.xml
index 5a3c2beac..d59f1ce05 100644
--- a/mastodon/src/main/res/values-nl-rNL/strings_sk.xml
+++ b/mastodon/src/main/res/values-nl-rNL/strings_sk.xml
@@ -254,4 +254,9 @@
Quoting %s
Zichtbaarheid reactie
Alle reacties
+ iedereen
+ auteur
+ niemand
+ niemand
+ iedereen
\ No newline at end of file
diff --git a/mastodon/src/main/res/values-pt/strings_sk.xml b/mastodon/src/main/res/values-pt/strings_sk.xml
deleted file mode 100644
index a93f10998..000000000
--- a/mastodon/src/main/res/values-pt/strings_sk.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
- Megalodon
- Fixado
- Apagar e reescrever
- Tem a certeza que pretende apagar e reescrever esta publicação\?
- Tem a certeza que deseja desafixar esta publicação\?
- Todas as respostas
- Carregar novas publicações automaticamente
- Desligar as notificações de publicação para %s
- Estas são as publicações mais recentes das pessoas na tua federação.
- Apagar e reescrever publicação
- Fixar no perfil
- Fixar publicação no perfil
- Deseja fixar esta publicação ao seu perfil\?
- A fixar a publicação…
- Desafixar do perfil
- Desafixar publicação do perfil
- A desafixar publicação…
- Descrição da imagem
- Não listado
- Mostrar respostas
- Citação %s
- Visibilidade da resposta
- Apagar idiomas usados recentemente
- Respostas aos meus comentários
- Respostas a mim
- Mostrar impulsionamentos
- Mostrar contagem de interações
- Megalodon v%1$s (%2$d)
- Marcar conteúdo como sensível
- Ligar as notificações de publicação para %s
- Federação
- Megalodon %s pronto a descarregar.
- Megalodon %s descarregado e pronto a instalar.
- A verificar atualizações
- Sem atualizações disponíveis
- Listas
- Pedidos para seguir
- Aceitar pedido para seguir
- Rejeitar pedido para seguir
- Listas com %s
- Mostrar sempre avisos de conteúdo
-
\ No newline at end of file
diff --git a/mastodon/src/main/res/values-ru-rRU/strings_sk.xml b/mastodon/src/main/res/values-ru-rRU/strings_sk.xml
index cca8e5e13..58e8b1c55 100644
--- a/mastodon/src/main/res/values-ru-rRU/strings_sk.xml
+++ b/mastodon/src/main/res/values-ru-rRU/strings_sk.xml
@@ -257,7 +257,7 @@
Сворачивать очень длинные посты
Исправить вложения\?
Некоторые вложения еще не загрузились.
- Цитирование%s
+ Цитирование %s
Видимость ответа
Скрыть кнопки взаимодействия
Подписаться с другого аккаунта
diff --git a/mastodon/src/main/res/values-sv-rSE/strings.xml b/mastodon/src/main/res/values-sv-rSE/strings.xml
index 0cef3870d..fec9dd86e 100644
--- a/mastodon/src/main/res/values-sv-rSE/strings.xml
+++ b/mastodon/src/main/res/values-sv-rSE/strings.xml
@@ -269,6 +269,7 @@
Dölj innehåll
Nytt inlägg
Svara
+ Boosta
Favoritmarkera
Dela
Media utan beskrivning
@@ -428,5 +429,7 @@
eller
Läs mer
Välkommen till Mastodon
+ Mastodon är ett decentraliserat socialt nätverk, vilket innebär att inget enskilt företag kontrollerar det. Det består av många oberoende servrar, alla sammankopplade.
Vad är servrar?
+
diff --git a/mastodon/src/main/res/values-uk-rUA/strings_sk.xml b/mastodon/src/main/res/values-uk-rUA/strings_sk.xml
index 95cd0823c..7b0f65318 100644
--- a/mastodon/src/main/res/values-uk-rUA/strings_sk.xml
+++ b/mastodon/src/main/res/values-uk-rUA/strings_sk.xml
@@ -293,4 +293,8 @@
Сервер тимчасово недоступний
Поділитися або відкрити за допомогою облікового запису
Не вдалося відкрити в застосунку
+ віддалена інформація недоступна
+ Завантажити інформацію з віддалених серверів
+ Спробуйте отримати точніші списки підписників, вподобань і поширень, завантаживши інформацію з джерела.
+ Не вдалося завантажити профіль на ваш домашній сервер.
\ No newline at end of file
diff --git a/mastodon/src/main/res/values/strings_sk.xml b/mastodon/src/main/res/values/strings_sk.xml
index 3e2b78556..e9a8a42e2 100644
--- a/mastodon/src/main/res/values/strings_sk.xml
+++ b/mastodon/src/main/res/values/strings_sk.xml
@@ -260,7 +260,7 @@
New reports
Server version: %s
Poll results
- Prefix reply CW with “re:”
+ Prefix CW with “re:” on replies to
Filtered: %s
Expand
Collapse
@@ -297,9 +297,12 @@
Failed loading the profile via %s
Load info from remote instances
Try fetching more accurate listings for followers, likes and boosts by loading the information from the instance of origin.
- Reveal equal CWs in threads
- Never
- Same author
- Discussions
- Always
+ Reveal same CWs in replies from
+ nobody
+ author
+ everyone
+ everyone
+ nobody
+ others
+ “Forward report” switch default
\ No newline at end of file
diff --git a/metadata/ar_DZ/full_description.txt b/metadata/ar/full_description.txt
similarity index 100%
rename from metadata/ar_DZ/full_description.txt
rename to metadata/ar/full_description.txt
diff --git a/metadata/ar_DZ/short_description.txt b/metadata/ar/short_description.txt
similarity index 100%
rename from metadata/ar_DZ/short_description.txt
rename to metadata/ar/short_description.txt
diff --git a/metadata/pt/title.txt b/metadata/my/title.txt
similarity index 100%
rename from metadata/pt/title.txt
rename to metadata/my/title.txt
diff --git a/metadata/pt/changelogs/50.txt b/metadata/pt-PT/changelogs/50.txt
similarity index 100%
rename from metadata/pt/changelogs/50.txt
rename to metadata/pt-PT/changelogs/50.txt
diff --git a/metadata/pt/changelogs/51.txt b/metadata/pt-PT/changelogs/51.txt
similarity index 100%
rename from metadata/pt/changelogs/51.txt
rename to metadata/pt-PT/changelogs/51.txt
diff --git a/metadata/pt/changelogs/55.txt b/metadata/pt-PT/changelogs/55.txt
similarity index 100%
rename from metadata/pt/changelogs/55.txt
rename to metadata/pt-PT/changelogs/55.txt
diff --git a/metadata/pt/changelogs/56.txt b/metadata/pt-PT/changelogs/56.txt
similarity index 100%
rename from metadata/pt/changelogs/56.txt
rename to metadata/pt-PT/changelogs/56.txt
diff --git a/metadata/pt/changelogs/59.txt b/metadata/pt/changelogs/59.txt
deleted file mode 100644
index 5587ab982..000000000
--- a/metadata/pt/changelogs/59.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-- 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
diff --git a/metadata/pt/changelogs/61.txt b/metadata/pt/changelogs/61.txt
deleted file mode 100644
index 21edf48da..000000000
--- a/metadata/pt/changelogs/61.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-- 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
diff --git a/metadata/pt/full_description.txt b/metadata/pt/full_description.txt
deleted file mode 100644
index 2485c5fc7..000000000
--- a/metadata/pt/full_description.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-Megalodon é uma versão modificada da App oficial do Mastodon 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.
-
-Recursos chave
-
-- Publicação não listada : Publicar sem que a tua publicação apareça nas tendências, hashtags ou em linhas do tempo públicas.
-- Linha do tempo unificada : Ver todas as publicações de pessoas noutras vizinhanças do Fediverso a que a tua instância nativa está ligada.
--Linhas do tempo personalizadas : Fixa qualquer lista ou hashtag ao teu separador nativo do Megalodon para simplesmente deslizar entre os teus tópicos e pessoas favoritas.
--Rascunhos e publicações agendadas : Permite a preparação de uma publicação e agendar-la para ser automaticamente publicada num tempo determinado.
-- Fixar publicações : Fixa as tuas publicações mais importantes no teu perfil e vê o que os outros têm fixado usando o separador "Fixados".
-- Seguir hashtags : Vê publicações de hashtags específicas diretamente na tua linha do tempo nativa seguindo-os simplesmente.
-- Responder a pedidos para seguir : Aceitar ou rejeitar pedidos para seguir a partir das tuas notificações ou na lista de pedidos para seguir dedicada a isso.
-- Apagar e refazer : O muito adorado recurso que tornou a edição possível sem uma função de editar propriamente dita.
-- Selecionar idioma : Seleciona sem esforço nenhum o idioma para cada publicação que fazes para que os filtros e a tradução funcionem corretamente.
-- Tradução : Traduz facilmente publicações dentro do próprio Megalodon! Funciona apenas se o recurso estiver disponível no Mastodon Web.
-- Indicador da visibilidade de publicação : Ao abrir ou responder a uma públicação um icone de uma mão será apresentado, indicando a visibilidade da publicação.
-- Cor dos temas : 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.
diff --git a/metadata/pt/short_description.txt b/metadata/pt/short_description.txt
deleted file mode 100644
index 96fbaa6fe..000000000
--- a/metadata/pt/short_description.txt
+++ /dev/null
@@ -1 +0,0 @@
-Mastodon para Android, mas é rosa e tem mais recursos