From 1ab953d8191f2fb710ff19eefb3a495b93135aad Mon Sep 17 00:00:00 2001 From: sk Date: Thu, 8 Jun 2023 15:03:04 +0200 Subject: [PATCH 01/18] fix spoiler button being hidden while editing closes sk22#553 --- .../org/joinmastodon/android/fragments/ComposeFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 7fce1101b..8ddaebbf8 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/ComposeFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/ComposeFragment.java @@ -848,10 +848,10 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr updateScheduledAt(scheduledAt != null ? scheduledAt : scheduledStatus != null ? scheduledStatus.scheduledAt : null); buildLanguageSelector(languageButton); + if (isInstancePixelfed()) spoilerBtn.setVisibility(View.GONE); if (isInstancePixelfed() || (editingStatus != null && scheduledStatus == null)) { // editing an already published post draftsBtn.setVisibility(View.GONE); - spoilerBtn.setVisibility(View.GONE); } } From 97547f334f16db1000e1399a55b7088953e77be4 Mon Sep 17 00:00:00 2001 From: sk Date: Thu, 8 Jun 2023 15:31:58 +0200 Subject: [PATCH 02/18] returning optionals for the optional god closes sk22#555 --- .../android/ExternalShareActivity.java | 4 +- .../android/ui/utils/UiUtils.java | 75 ++++++++++--------- 2 files changed, 40 insertions(+), 39 deletions(-) diff --git a/mastodon/src/main/java/org/joinmastodon/android/ExternalShareActivity.java b/mastodon/src/main/java/org/joinmastodon/android/ExternalShareActivity.java index 40418d5fe..968d786a3 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ExternalShareActivity.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ExternalShareActivity.java @@ -64,8 +64,8 @@ public class ExternalShareActivity extends FragmentStackActivity{ fediHandle .>map(handle -> UiUtils.lookupAccountHandle(this, accountId, handle, callback)) - .or(() -> Optional.ofNullable( - UiUtils.lookupURL(this, accountId, text.get(), false, callback))) + .or(() -> + UiUtils.lookupURL(this, accountId, text.get(), false, callback)) .ifPresent(req -> req.wrapProgress(this, R.string.loading, true, d -> { UiUtils.transformDialogForLookup(this, accountId, isFediUrl ? text.get() : null, d); 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 e9adca7ec..0c9dd3fa2 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 @@ -1053,43 +1053,43 @@ public class UiUtils { }, null); } - public static void lookupStatus(Context context, Status queryStatus, String targetAccountID, @Nullable String sourceAccountID, Consumer resultConsumer) { - lookup(context, queryStatus, targetAccountID, sourceAccountID, GetSearchResults.Type.STATUSES, resultConsumer, results -> + public static Optional> lookupStatus(Context context, Status queryStatus, String targetAccountID, @Nullable String sourceAccountID, Consumer resultConsumer) { + return lookup(context, queryStatus, targetAccountID, sourceAccountID, GetSearchResults.Type.STATUSES, resultConsumer, results -> !results.statuses.isEmpty() ? Optional.of(results.statuses.get(0)) : Optional.empty() ); } - public static void lookupAccount(Context context, Account queryAccount, String targetAccountID, @Nullable String sourceAccountID, Consumer resultConsumer) { - lookup(context, queryAccount, targetAccountID, sourceAccountID, GetSearchResults.Type.ACCOUNTS, resultConsumer, results -> + public static Optional> lookupAccount(Context context, Account queryAccount, String targetAccountID, @Nullable String sourceAccountID, Consumer resultConsumer) { + return lookup(context, queryAccount, targetAccountID, sourceAccountID, GetSearchResults.Type.ACCOUNTS, resultConsumer, results -> !results.accounts.isEmpty() ? Optional.of(results.accounts.get(0)) : Optional.empty() ); } - public static void lookup(Context context, T query, String targetAccountID, @Nullable String sourceAccountID, @Nullable GetSearchResults.Type type, Consumer resultConsumer, Function> extractResult) { + public static Optional> lookup(Context context, T query, String targetAccountID, @Nullable String sourceAccountID, @Nullable GetSearchResults.Type type, Consumer resultConsumer, Function> extractResult) { if (sourceAccountID != null && targetAccountID.startsWith(sourceAccountID.substring(0, sourceAccountID.indexOf('_')))) { resultConsumer.accept(query); - return; + return Optional.empty(); } - new GetSearchResults(query.getQuery(), type, true).setCallback(new Callback<>() { - @Override - public void onSuccess(SearchResults results) { - Optional result = extractResult.apply(results); - if (result.isPresent()) resultConsumer.accept(result.get()); - else { - Toast.makeText(context, R.string.sk_resource_not_found, Toast.LENGTH_SHORT).show(); - resultConsumer.accept(null); - } - } + return Optional.of(new GetSearchResults(query.getQuery(), type, true).setCallback(new Callback<>() { + @Override + public void onSuccess(SearchResults results) { + Optional result = extractResult.apply(results); + if (result.isPresent()) resultConsumer.accept(result.get()); + else { + Toast.makeText(context, R.string.sk_resource_not_found, Toast.LENGTH_SHORT).show(); + resultConsumer.accept(null); + } + } - @Override - public void onError(ErrorResponse error) { - error.showToast(context); - } - }) + @Override + public void onError(ErrorResponse error) { + error.showToast(context); + } + }) .wrapProgress((Activity) context, R.string.loading, true, d -> transformDialogForLookup(context, targetAccountID, null, d)) - .exec(targetAccountID); + .exec(targetAccountID)); } public static void transformDialogForLookup(Context context, String accountID, @Nullable String url, ProgressDialog dialog) { @@ -1129,13 +1129,13 @@ public class UiUtils { public static void openURL(Context context, String accountID, String url, boolean launchBrowser) { lookupURL(context, accountID, url, launchBrowser, (clazz, args) -> { if (clazz == null) { - if (args.containsKey("error")) Toast.makeText(context, args.getString("error"), Toast.LENGTH_SHORT).show(); + if (args != null && args.containsKey("error")) Toast.makeText(context, args.getString("error"), Toast.LENGTH_SHORT).show(); if (launchBrowser) launchWebBrowser(context, url); return; } Nav.go((Activity) context, clazz, args); - }).wrapProgress((Activity) context, R.string.loading, true, d -> - transformDialogForLookup(context, accountID, url, d)); + }).map(req -> req.wrapProgress((Activity) context, R.string.loading, true, d -> + transformDialogForLookup(context, accountID, url, d))); } public static boolean acctMatches(String accountID, String acct, String queriedUsername, @Nullable String queriedDomain) { @@ -1158,11 +1158,13 @@ public class UiUtils { } } - public static void lookupAccountHandle(Context context, String accountID, String query, BiConsumer, Bundle> go) { - parseFediverseHandle(query).ifPresentOrElse( - handle -> lookupAccountHandle(context, accountID, handle, go), - () -> go.accept(null, null) - ); + public static Optional> lookupAccountHandle(Context context, String accountID, String query, BiConsumer, Bundle> go) { + return parseFediverseHandle(query).map( + handle -> lookupAccountHandle(context, accountID, handle, go)) + .or(() -> { + go.accept(null, null); + return Optional.empty(); + }); } public static MastodonAPIRequest lookupAccountHandle(Context context, String accountID, Pair> queryHandle, BiConsumer, Bundle> go) { String fullHandle = ("@" + queryHandle.first) + (queryHandle.second.map(domain -> "@" + domain).orElse("")); @@ -1190,12 +1192,12 @@ public class UiUtils { }).exec(accountID); } - public static MastodonAPIRequest lookupURL(Context context, String accountID, String url, boolean launchBrowser, BiConsumer, Bundle> go) { + public static Optional> lookupURL(Context context, String accountID, String url, boolean launchBrowser, BiConsumer, Bundle> go) { Uri uri = Uri.parse(url); List path = uri.getPathSegments(); if (accountID != null && "https".equals(uri.getScheme())) { if (path.size() == 2 && path.get(0).matches("^@[a-zA-Z0-9_]+$") && path.get(1).matches("^[0-9]+$") && AccountSessionManager.getInstance().getAccount(accountID).domain.equalsIgnoreCase(uri.getAuthority())) { - return new GetStatusByID(path.get(1)) + return Optional.of(new GetStatusByID(path.get(1)) .setCallback(new Callback<>() { @Override public void onSuccess(Status result) { @@ -1210,9 +1212,9 @@ public class UiUtils { go.accept(null, bundleError(error)); } }) - .exec(accountID); + .exec(accountID)); } else if (looksLikeFediverseUrl(url)) { - return new GetSearchResults(url, null, true) + return Optional.of(new GetSearchResults(url, null, true) .setCallback(new Callback<>() { @Override public void onSuccess(SearchResults results) { @@ -1239,12 +1241,11 @@ public class UiUtils { go.accept(null, bundleError(error)); } }) - .exec(accountID); + .exec(accountID)); } } - if (launchBrowser) launchWebBrowser(context, url); go.accept(null, null); - return null; + return Optional.empty(); } public static void copyText(View v, String text) { From 6f3fd4d45459a1a094d375747f534b836c107eca Mon Sep 17 00:00:00 2001 From: sk Date: Fri, 9 Jun 2023 12:47:32 +0200 Subject: [PATCH 03/18] fix opening browser twice closes sk22#559 --- .../java/org/joinmastodon/android/ExternalShareActivity.java | 2 +- .../main/java/org/joinmastodon/android/ui/utils/UiUtils.java | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/mastodon/src/main/java/org/joinmastodon/android/ExternalShareActivity.java b/mastodon/src/main/java/org/joinmastodon/android/ExternalShareActivity.java index 968d786a3..ce56efb54 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ExternalShareActivity.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ExternalShareActivity.java @@ -65,7 +65,7 @@ public class ExternalShareActivity extends FragmentStackActivity{ .>map(handle -> UiUtils.lookupAccountHandle(this, accountId, handle, callback)) .or(() -> - UiUtils.lookupURL(this, accountId, text.get(), false, callback)) + UiUtils.lookupURL(this, accountId, text.get(), callback)) .ifPresent(req -> req.wrapProgress(this, R.string.loading, true, d -> { UiUtils.transformDialogForLookup(this, accountId, isFediUrl ? text.get() : null, d); 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 0c9dd3fa2..385476a27 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 @@ -1127,7 +1127,7 @@ public class UiUtils { } public static void openURL(Context context, String accountID, String url, boolean launchBrowser) { - lookupURL(context, accountID, url, launchBrowser, (clazz, args) -> { + lookupURL(context, accountID, url, (clazz, args) -> { if (clazz == null) { if (args != null && args.containsKey("error")) Toast.makeText(context, args.getString("error"), Toast.LENGTH_SHORT).show(); if (launchBrowser) launchWebBrowser(context, url); @@ -1192,7 +1192,7 @@ public class UiUtils { }).exec(accountID); } - public static Optional> lookupURL(Context context, String accountID, String url, boolean launchBrowser, BiConsumer, Bundle> go) { + public static Optional> lookupURL(Context context, String accountID, String url, BiConsumer, Bundle> go) { Uri uri = Uri.parse(url); List path = uri.getPathSegments(); if (accountID != null && "https".equals(uri.getScheme())) { @@ -1232,7 +1232,6 @@ public class UiUtils { go.accept(ProfileFragment.class, args); return; } - if (launchBrowser) launchWebBrowser(context, url); go.accept(null, bundleError(context.getString(R.string.sk_resource_not_found))); } From ba7aeb358b7b7d9d2a762dbe8e3db23dd05b2a09 Mon Sep 17 00:00:00 2001 From: sk Date: Fri, 9 Jun 2023 12:50:00 +0200 Subject: [PATCH 04/18] fix thread status not clickable if filter revealed closes sk22#554 --- .../java/org/joinmastodon/android/fragments/ThreadFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 9c5bed3b1..9064475a5 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java @@ -319,7 +319,7 @@ public class ThreadFragment extends StatusListFragment implements ProvidesAssist @Override public boolean isItemEnabled(String id){ - return !id.equals(mainStatus.id); + return !id.equals(mainStatus.id) || !mainStatus.filterRevealed; } @Override From c4238fb19bb7706017c16b4c64219c189126b900 Mon Sep 17 00:00:00 2001 From: sk Date: Fri, 9 Jun 2023 13:27:25 +0200 Subject: [PATCH 05/18] keep revealed states when reloading closes sk22#561 --- .../android/fragments/ThreadFragment.java | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) 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 9064475a5..5826d3470 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java @@ -8,7 +8,6 @@ import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import org.joinmastodon.android.E; -import org.joinmastodon.android.GlobalUserPreferences; import org.joinmastodon.android.R; import org.joinmastodon.android.api.requests.statuses.GetStatusByID; import org.joinmastodon.android.api.requests.statuses.GetStatusContext; @@ -38,6 +37,7 @@ import java.util.Collections; import java.util.Deque; import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; @@ -118,7 +118,10 @@ public class ThreadFragment extends StatusListFragment implements ProvidesAssist @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(); @@ -150,6 +153,18 @@ public class ThreadFragment extends StatusListFragment implements ProvidesAssist adapter.notifyItemRemoved(prependedCount); count--; } + + // restore previous spoiler/filter revealed states when refreshing + if (refreshing && oldData.size() > 0) { + for (Status s : data) { + Status oldStatus = oldData.get(s.id); + if (oldStatus != null) { + s.spoilerRevealed = oldStatus.spoilerRevealed; + s.filterRevealed = oldStatus.filterRevealed; + } + } + } + dataLoaded(); if(refreshing){ refreshDone(); @@ -188,6 +203,10 @@ public class ThreadFragment extends StatusListFragment implements ProvidesAssist protected Object maybeApplyMainStatus() { if (updatedStatus == null || !contextInitiallyRendered) return null; + // restore revealed states for main status because it gets updated after doLoadData + updatedStatus.filterRevealed = mainStatus.filterRevealed; + updatedStatus.spoilerRevealed = mainStatus.spoilerRevealed; + // returning fired event object to facilitate testing Object event; if (updatedStatus.editedAt != null && From 870bfaf08cac0739294760fee17d047c8ee24511 Mon Sep 17 00:00:00 2001 From: sk Date: Fri, 9 Jun 2023 14:50:21 +0200 Subject: [PATCH 06/18] don't use switch for android ids --- .../android/fragments/SettingsFragment.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) 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 fe1d8edea..2e73e7805 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/SettingsFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/SettingsFragment.java @@ -560,14 +560,14 @@ public class SettingsFragment extends MastodonToolbarFragment implements Provide private boolean onContentTypeChanged(MenuItem item, Button btn){ int id = item.getItemId(); - ContentType contentType = switch (id) { - case R.id.content_type_plain -> ContentType.PLAIN; - case R.id.content_type_html -> ContentType.HTML; - case R.id.content_type_markdown -> ContentType.MARKDOWN; - case R.id.content_type_bbcode -> ContentType.BBCODE; - case R.id.content_type_misskey_markdown -> ContentType.MISSKEY_MARKDOWN; - default -> null; - }; + + ContentType contentType = null; + if (id == R.id.content_type_plain) contentType = ContentType.PLAIN; + else if (id == R.id.content_type_html) contentType = ContentType.HTML; + else if (id == R.id.content_type_markdown) contentType = ContentType.MARKDOWN; + else if (id == R.id.content_type_bbcode) contentType = ContentType.BBCODE; + else if (id == R.id.content_type_misskey_markdown) contentType = ContentType.MISSKEY_MARKDOWN; + GlobalUserPreferences.accountsDefaultContentTypes.put(accountID, contentType); GlobalUserPreferences.save(); btn.setText(getContentTypeString(contentType)); From 35bf858a83189ea35e4d6edc7678df19a6ec000e Mon Sep 17 00:00:00 2001 From: sk Date: Fri, 9 Jun 2023 14:54:03 +0200 Subject: [PATCH 07/18] auto-reveal equal spoilers in threads --- .../android/GlobalUserPreferences.java | 9 ++++ .../android/fragments/SettingsFragment.java | 48 +++++++++++++++++-- .../android/fragments/ThreadFragment.java | 21 +++++--- .../ic_fluent_star_off_24_regular.xml | 3 ++ .../res/menu/settings_auto_reveal_spoiler.xml | 12 +++++ mastodon/src/main/res/values/strings_sk.xml | 5 ++ 6 files changed, 87 insertions(+), 11 deletions(-) create mode 100644 mastodon/src/main/res/drawable/ic_fluent_star_off_24_regular.xml create mode 100644 mastodon/src/main/res/menu/settings_auto_reveal_spoiler.xml diff --git a/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java b/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java index 3366f213f..de73cdfc9 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java +++ b/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java @@ -49,6 +49,7 @@ public class GlobalUserPreferences{ public static boolean compactReblogReplyLine; public static boolean confirmBeforeReblog; public static boolean allowRemoteLoading; + public static AutoRevealMode autoRevealEqualSpoilers; public static String publishButtonText; public static ThemePreference theme; public static ColorPreference color; @@ -129,6 +130,7 @@ public class GlobalUserPreferences{ accountsWithContentTypesEnabled=prefs.getStringSet("accountsWithContentTypesEnabled", new HashSet<>()); accountsDefaultContentTypes=fromJson(prefs.getString("accountsDefaultContentTypes", null), accountsDefaultContentTypesType, new HashMap<>()); allowRemoteLoading=prefs.getBoolean("allowRemoteLoading", true); + autoRevealEqualSpoilers=AutoRevealMode.valueOf(prefs.getString("autoRevealEqualSpoilers", AutoRevealMode.THREADS.name())); try { color=ColorPreference.valueOf(prefs.getString("color", ColorPreference.PINK.name())); @@ -179,6 +181,7 @@ public class GlobalUserPreferences{ .putStringSet("accountsWithContentTypesEnabled", accountsWithContentTypesEnabled) .putString("accountsDefaultContentTypes", gson.toJson(accountsDefaultContentTypes)) .putBoolean("allowRemoteLoading", allowRemoteLoading) + .putString("autoRevealEqualSpoilers", autoRevealEqualSpoilers.name()) .apply(); } @@ -198,4 +201,10 @@ public class GlobalUserPreferences{ LIGHT, DARK } + + public enum AutoRevealMode { + NEVER, + THREADS, + DISCUSSIONS + } } 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 2e73e7805..1fbe3c427 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/SettingsFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/SettingsFragment.java @@ -37,6 +37,7 @@ import com.squareup.otto.Subscribe; import org.joinmastodon.android.BuildConfig; 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.MainActivity; import org.joinmastodon.android.MastodonApp; @@ -85,8 +86,8 @@ public class SettingsFragment extends MastodonToolbarFragment implements Provide private ArrayList items=new ArrayList<>(); private ThemeItem themeItem; private NotificationPolicyItem notificationPolicyItem; - private SwitchItem showNewPostsItem, glitchModeItem, compactReblogReplyLineItem; - private ButtonItem defaultContentTypeButtonItem; + private SwitchItem showNewPostsItem, glitchModeItem, compactReblogReplyLineItem, alwaysRevealSpoilersItem; + private ButtonItem defaultContentTypeButtonItem, autoRevealSpoilersItem; private String accountID; private boolean needUpdateNotificationSettings; private boolean needAppRestart; @@ -189,9 +190,18 @@ public class SettingsFragment extends MastodonToolbarFragment implements Provide GlobalUserPreferences.showInteractionCounts=i.checked; GlobalUserPreferences.save(); })); - items.add(new SwitchItem(R.string.sk_settings_always_reveal_content_warnings, R.drawable.ic_fluent_chat_warning_24_regular, GlobalUserPreferences.alwaysExpandContentWarnings, i->{ + items.add(alwaysRevealSpoilersItem = new SwitchItem(R.string.sk_settings_always_reveal_content_warnings, R.drawable.ic_fluent_chat_warning_24_regular, GlobalUserPreferences.alwaysExpandContentWarnings, i->{ GlobalUserPreferences.alwaysExpandContentWarnings=i.checked; GlobalUserPreferences.save(); + if (list.findViewHolderForAdapterPosition(items.indexOf(autoRevealSpoilersItem)) instanceof ButtonViewHolder bvh) bvh.rebind(); + })); + items.add(autoRevealSpoilersItem = new ButtonItem(R.string.sk_settings_auto_reveal_equal_spoilers, R.drawable.ic_fluent_eye_24_regular, b->{ + PopupMenu popupMenu=new PopupMenu(getActivity(), b, Gravity.CENTER_HORIZONTAL); + popupMenu.inflate(R.menu.settings_auto_reveal_spoiler); + popupMenu.setOnMenuItemClickListener(i -> onAutoRevealSpoilerClick(i, b)); + b.setOnTouchListener(popupMenu.getDragToOpenListener()); + b.setOnClickListener(v->popupMenu.show()); + onAutoRevealSpoilerChanged(b); })); items.add(new SwitchItem(R.string.sk_tabs_disable_swipe, R.drawable.ic_fluent_swipe_right_24_regular, GlobalUserPreferences.disableSwipe, i->{ GlobalUserPreferences.disableSwipe=i.checked; @@ -276,7 +286,7 @@ public class SettingsFragment extends MastodonToolbarFragment implements Provide GlobalUserPreferences.collapseLongPosts=i.checked; GlobalUserPreferences.save(); })); - items.add(new SwitchItem(R.string.sk_settings_hide_interaction, R.drawable.ic_fluent_eye_24_regular, GlobalUserPreferences.spectatorMode, i->{ + items.add(new SwitchItem(R.string.sk_settings_hide_interaction, R.drawable.ic_fluent_star_off_24_regular, GlobalUserPreferences.spectatorMode, i->{ GlobalUserPreferences.spectatorMode=i.checked; GlobalUserPreferences.save(); needAppRestart=true; @@ -531,6 +541,36 @@ public class SettingsFragment extends MastodonToolbarFragment implements Provide return true; } + private boolean onAutoRevealSpoilerClick(MenuItem item, Button btn) { + int id = item.getItemId(); + + AutoRevealMode mode = AutoRevealMode.NEVER; + if (id == R.id.auto_reveal_threads) mode = AutoRevealMode.THREADS; + else if (id == R.id.auto_reveal_discussions) mode = AutoRevealMode.DISCUSSIONS; + + GlobalUserPreferences.alwaysExpandContentWarnings = false; + GlobalUserPreferences.autoRevealEqualSpoilers = mode; + GlobalUserPreferences.save(); + onAutoRevealSpoilerChanged(btn); + return true; + } + + private void onAutoRevealSpoilerChanged(Button b) { + if (GlobalUserPreferences.alwaysExpandContentWarnings) { + b.setText(R.string.sk_settings_auto_reveal_always); + } 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; + }); + if (alwaysRevealSpoilersItem.checked != GlobalUserPreferences.alwaysExpandContentWarnings) { + alwaysRevealSpoilersItem.checked = GlobalUserPreferences.alwaysExpandContentWarnings; + if (list.findViewHolderForAdapterPosition(items.indexOf(alwaysRevealSpoilersItem)) instanceof SwitchViewHolder svh) svh.rebind(); + } + } + } + private void onTrueBlackThemeChanged(SwitchItem item){ GlobalUserPreferences.trueBlackTheme=item.checked; GlobalUserPreferences.save(); 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 5826d3470..6ff24b7b7 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java @@ -8,6 +8,8 @@ import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import org.joinmastodon.android.E; +import org.joinmastodon.android.GlobalUserPreferences; +import org.joinmastodon.android.GlobalUserPreferences.AutoRevealMode; import org.joinmastodon.android.R; import org.joinmastodon.android.api.requests.statuses.GetStatusByID; import org.joinmastodon.android.api.requests.statuses.GetStatusContext; @@ -154,13 +156,18 @@ public class ThreadFragment extends StatusListFragment implements ProvidesAssist count--; } - // restore previous spoiler/filter revealed states when refreshing - if (refreshing && oldData.size() > 0) { - for (Status s : data) { - Status oldStatus = oldData.get(s.id); - if (oldStatus != null) { - s.spoilerRevealed = oldStatus.spoilerRevealed; - s.filterRevealed = oldStatus.filterRevealed; + 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; } } } diff --git a/mastodon/src/main/res/drawable/ic_fluent_star_off_24_regular.xml b/mastodon/src/main/res/drawable/ic_fluent_star_off_24_regular.xml new file mode 100644 index 000000000..9e46ebd1b --- /dev/null +++ b/mastodon/src/main/res/drawable/ic_fluent_star_off_24_regular.xml @@ -0,0 +1,3 @@ + + + diff --git a/mastodon/src/main/res/menu/settings_auto_reveal_spoiler.xml b/mastodon/src/main/res/menu/settings_auto_reveal_spoiler.xml new file mode 100644 index 000000000..f6a5e31ed --- /dev/null +++ b/mastodon/src/main/res/menu/settings_auto_reveal_spoiler.xml @@ -0,0 +1,12 @@ + + + + + + \ 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 40dd203a8..05d79c5d2 100644 --- a/mastodon/src/main/res/values/strings_sk.xml +++ b/mastodon/src/main/res/values/strings_sk.xml @@ -297,4 +297,9 @@ 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 \ No newline at end of file From bcb4fac553088942d65e7500302f957c1db7e122 Mon Sep 17 00:00:00 2001 From: Choukajohn Date: Tue, 6 Jun 2023 18:00:34 +0000 Subject: [PATCH 08/18] Translated using Weblate (French) Currently translated at 100.0% (297 of 297 strings) Translation: Megalodon/values Translate-URL: https://translate.codeberg.org/projects/megalodon/values/fr/ --- mastodon/src/main/res/values-fr-rFR/strings_sk.xml | 4 ++++ 1 file changed, 4 insertions(+) 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..86b617339 100644 --- a/mastodon/src/main/res/values-fr-rFR/strings_sk.xml +++ b/mastodon/src/main/res/values-fr-rFR/strings_sk.xml @@ -294,4 +294,8 @@ 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 sur votre instance personnelle. + 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. \ No newline at end of file From a43a396043c9db8287e43b86d3b5b83d346bad85 Mon Sep 17 00:00:00 2001 From: ihor_ck Date: Tue, 6 Jun 2023 20:46:51 +0000 Subject: [PATCH 09/18] Translated using Weblate (Ukrainian) Currently translated at 100.0% (297 of 297 strings) Translation: Megalodon/values Translate-URL: https://translate.codeberg.org/projects/megalodon/values/uk/ --- mastodon/src/main/res/values-uk-rUA/strings_sk.xml | 4 ++++ 1 file changed, 4 insertions(+) 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 From 3b742c43915d4e9be55c02a8c01865ccb4b4396b Mon Sep 17 00:00:00 2001 From: Choukajohn Date: Wed, 7 Jun 2023 23:02:47 +0000 Subject: [PATCH 10/18] Translated using Weblate (French) Currently translated at 100.0% (297 of 297 strings) Translation: Megalodon/values Translate-URL: https://translate.codeberg.org/projects/megalodon/values/fr/ --- mastodon/src/main/res/values-fr-rFR/strings_sk.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 86b617339..e470d0b66 100644 --- a/mastodon/src/main/res/values-fr-rFR/strings_sk.xml +++ b/mastodon/src/main/res/values-fr-rFR/strings_sk.xml @@ -296,6 +296,6 @@ Impossible de l\'ouvrir dans l\'application Charger des informations à partir d\'instances distantes informations distantes indisponibles - Échec du chargement du profil sur votre instance personnelle. + É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. \ No newline at end of file From d43a697df7fa5a3ce7d8258db5757266cd877dfa Mon Sep 17 00:00:00 2001 From: Linerly Date: Thu, 8 Jun 2023 04:32:15 +0000 Subject: [PATCH 11/18] Translated using Weblate (Indonesian) Currently translated at 100.0% (297 of 297 strings) Translation: Megalodon/values Translate-URL: https://translate.codeberg.org/projects/megalodon/values/id/ --- mastodon/src/main/res/values-in-rID/strings_sk.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) 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..c3f5c9593 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,13 @@ 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 \ No newline at end of file From 0825faee5cb77d18d746217c6cef8534cd71d865 Mon Sep 17 00:00:00 2001 From: gicorada Date: Sat, 10 Jun 2023 12:56:34 +0000 Subject: [PATCH 12/18] Translated using Weblate (Italian) Currently translated at 100.0% (297 of 297 strings) Translation: Megalodon/values Translate-URL: https://translate.codeberg.org/projects/megalodon/values/it/ --- .../src/main/res/values-it-rIT/strings_sk.xml | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) 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 9ed722573..4891177d0 100644 --- a/mastodon/src/main/res/values-it-rIT/strings_sk.xml +++ b/mastodon/src/main/res/values-it-rIT/strings_sk.xml @@ -274,4 +274,26 @@ Linea boost/risposta compatta ha reagito con %s Linea \"In risposta a\" sopra l\'avatar + 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 + Markdown + BBCode + MFM + Abilita la formattazione dei post + 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 From 8547ce05ed58ef152f52d72673ffa87bdfb7b00c Mon Sep 17 00:00:00 2001 From: sk Date: Sat, 10 Jun 2023 18:52:01 +0200 Subject: [PATCH 13/18] change auto-reveal cw wording closes sk22#562 --- .../joinmastodon/android/fragments/SettingsFragment.java | 8 ++++---- .../src/main/res/menu/settings_auto_reveal_spoiler.xml | 6 +++--- mastodon/src/main/res/values/strings_sk.xml | 9 ++++----- 3 files changed, 11 insertions(+), 12 deletions(-) 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 1fbe3c427..07940bafa 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/SettingsFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/SettingsFragment.java @@ -557,12 +557,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/res/menu/settings_auto_reveal_spoiler.xml b/mastodon/src/main/res/menu/settings_auto_reveal_spoiler.xml index f6a5e31ed..e6c99f90e 100644 --- a/mastodon/src/main/res/menu/settings_auto_reveal_spoiler.xml +++ b/mastodon/src/main/res/menu/settings_auto_reveal_spoiler.xml @@ -2,11 +2,11 @@ + 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/values/strings_sk.xml b/mastodon/src/main/res/values/strings_sk.xml index 05d79c5d2..3aaacdb09 100644 --- a/mastodon/src/main/res/values/strings_sk.xml +++ b/mastodon/src/main/res/values/strings_sk.xml @@ -297,9 +297,8 @@ 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 equal CWs in replies from + nobody + author + anyone \ No newline at end of file From 90e60aef84cdaee4cebf203ff11d46335219a23d Mon Sep 17 00:00:00 2001 From: sk Date: Sat, 10 Jun 2023 18:52:01 +0200 Subject: [PATCH 14/18] change auto-reveal cw wording closes sk22#562 --- .../joinmastodon/android/fragments/SettingsFragment.java | 8 ++++---- .../src/main/res/menu/settings_auto_reveal_spoiler.xml | 6 +++--- mastodon/src/main/res/values/strings_sk.xml | 9 ++++----- 3 files changed, 11 insertions(+), 12 deletions(-) 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 1fbe3c427..07940bafa 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/SettingsFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/SettingsFragment.java @@ -557,12 +557,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/res/menu/settings_auto_reveal_spoiler.xml b/mastodon/src/main/res/menu/settings_auto_reveal_spoiler.xml index f6a5e31ed..e6c99f90e 100644 --- a/mastodon/src/main/res/menu/settings_auto_reveal_spoiler.xml +++ b/mastodon/src/main/res/menu/settings_auto_reveal_spoiler.xml @@ -2,11 +2,11 @@ + 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/values/strings_sk.xml b/mastodon/src/main/res/values/strings_sk.xml index 05d79c5d2..1142e17c0 100644 --- a/mastodon/src/main/res/values/strings_sk.xml +++ b/mastodon/src/main/res/values/strings_sk.xml @@ -297,9 +297,8 @@ 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 their replies + Nobody + Author + Anyone \ No newline at end of file From 35c8a3d1215b8e9b2db6b81e716e73e29ed7774d Mon Sep 17 00:00:00 2001 From: sk Date: Sat, 10 Jun 2023 18:59:05 +0200 Subject: [PATCH 15/18] change strings --- mastodon/src/main/res/values/strings_sk.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mastodon/src/main/res/values/strings_sk.xml b/mastodon/src/main/res/values/strings_sk.xml index 1142e17c0..7aada80cc 100644 --- a/mastodon/src/main/res/values/strings_sk.xml +++ b/mastodon/src/main/res/values/strings_sk.xml @@ -297,8 +297,8 @@ 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 same CWs in their replies - Nobody - Author - Anyone + Reveal same CWs in replies from + nobody + author + everyone \ No newline at end of file From 7fb0944e66483539ee23480ae87609b915dfc00f Mon Sep 17 00:00:00 2001 From: sk22 Date: Sat, 10 Jun 2023 16:57:49 +0000 Subject: [PATCH 16/18] Translated using Weblate (German) Currently translated at 100.0% (301 of 301 strings) Translation: Megalodon/values Translate-URL: https://translate.codeberg.org/projects/megalodon/values/de/ --- mastodon/src/main/res/values-de-rDE/strings_sk.xml | 4 ++++ 1 file changed, 4 insertions(+) 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 9d2cdcad6..2bb8ab761 100644 --- a/mastodon/src/main/res/values-de-rDE/strings_sk.xml +++ b/mastodon/src/main/res/values-de-rDE/strings_sk.xml @@ -296,4 +296,8 @@ 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. + Gleiche CWs in deren Antworten zeigen + Niemand + Autor*in + Alle \ No newline at end of file From 87c37df370ec24aeea0d2dbaeb29468aa4fb5808 Mon Sep 17 00:00:00 2001 From: sk Date: Sat, 10 Jun 2023 20:57:01 +0200 Subject: [PATCH 17/18] insert replied directly below status closes sk22#558 --- .../android/fragments/ThreadFragment.java | 56 ++++++++++++++++++- .../ui/displayitems/StatusDisplayItem.java | 27 +++++---- 2 files changed, 69 insertions(+), 14 deletions(-) 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 6ff24b7b7..24f2286d8 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java @@ -337,10 +337,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/ui/displayitems/StatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java index b1bd67d3a..f0f0fc6a0 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){ From 573ff754980efc370102ceaf709a280dd2d97ecd Mon Sep 17 00:00:00 2001 From: sk Date: Sat, 10 Jun 2023 21:32:41 +0200 Subject: [PATCH 18/18] update ancestor when deleting post --- .../android/fragments/StatusListFragment.java | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) 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 838ace548..ea34851c7 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/StatusListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/StatusListFragment.java @@ -164,13 +164,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;