diff --git a/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java b/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java index 40c61e4b4..6f9d4a83b 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java +++ b/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java @@ -53,6 +53,7 @@ public class GlobalUserPreferences{ public static boolean confirmBeforeReblog; public static boolean replyLineAboveHeader; public static boolean swapBookmarkWithBoostAction; + public static boolean loadRemoteAccountFollowers; public static String publishButtonText; public static ThemePreference theme; public static ColorPreference color; @@ -120,6 +121,7 @@ public class GlobalUserPreferences{ compactReblogReplyLine=prefs.getBoolean("compactReblogReplyLine", true); confirmBeforeReblog=prefs.getBoolean("confirmBeforeReblog", false); swapBookmarkWithBoostAction=prefs.getBoolean("swapBookmarkWithBoostAction", false); + loadRemoteAccountFollowers=prefs.getBoolean("loadRemoteAccountFollowers", true); publishButtonText=prefs.getString("publishButtonText", ""); theme=ThemePreference.values()[prefs.getInt("theme", 0)]; recentLanguages=fromJson(prefs.getString("recentLanguages", "{}"), recentLanguagesType, new HashMap<>()); @@ -178,6 +180,7 @@ public class GlobalUserPreferences{ .putBoolean("replyLineAboveHeader", replyLineAboveHeader) .putBoolean("confirmBeforeReblog", confirmBeforeReblog) .putBoolean("swapBookmarkWithBoostAction", swapBookmarkWithBoostAction) + .putBoolean("loadRemoteAccountFollowers", loadRemoteAccountFollowers) .putInt("theme", theme.ordinal()) .putString("color", color.name()) .putString("recentLanguages", gson.toJson(recentLanguages)) diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/BaseAccountListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/BaseAccountListFragment.java index 4a247b0bf..357540ab5 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/BaseAccountListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/BaseAccountListFragment.java @@ -74,6 +74,8 @@ public abstract class BaseAccountListFragment extends RecyclerFragment d, boolean more){ + if (getActivity() == null) + return; if(refreshing){ relationships.clear(); } @@ -267,6 +269,15 @@ public abstract class BaseAccountListFragment extends RecyclerFragment { + Bundle args=new Bundle(); + args.putString("account", accountID); + args.putParcelable("profileAccount", Parcels.wrap(account)); + Nav.go(getActivity(), ProfileFragment.class, args); + }); + return; + } Bundle args=new Bundle(); args.putString("account", accountID); args.putParcelable("profileAccount", Parcels.wrap(item.account)); diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/FollowerListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/FollowerListFragment.java index 1a7b3c8e2..9914af9c5 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/FollowerListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/FollowerListFragment.java @@ -12,6 +12,7 @@ public class FollowerListFragment extends AccountRelatedAccountListFragment{ @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); + targetAccount = account; setSubtitle(getResources().getQuantityString(R.plurals.x_followers, (int)(account.followersCount%1000), account.followersCount)); } @@ -19,4 +20,9 @@ public class FollowerListFragment extends AccountRelatedAccountListFragment{ public HeaderPaginationRequest onCreateRequest(String maxID, int count){ return new GetAccountFollowers(account.id, maxID, count); } + + @Override + public HeaderPaginationRequest onCreateRemoteRequest(String id, String maxID, int count){ + return new GetAccountFollowers(id, maxID, count); + } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/FollowingListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/FollowingListFragment.java index 83351e751..33ca43734 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/FollowingListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/FollowingListFragment.java @@ -12,6 +12,7 @@ public class FollowingListFragment extends AccountRelatedAccountListFragment{ @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); + targetAccount = account; setSubtitle(getResources().getQuantityString(R.plurals.x_following, (int)(account.followingCount%1000), account.followingCount)); } @@ -19,4 +20,9 @@ public class FollowingListFragment extends AccountRelatedAccountListFragment{ public HeaderPaginationRequest onCreateRequest(String maxID, int count){ return new GetAccountFollowing(account.id, maxID, count); } + + @Override + public HeaderPaginationRequest onCreateRemoteRequest(String id, String maxID, int count){ + return new GetAccountFollowing(id, maxID, count); + } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/PaginatedAccountListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/PaginatedAccountListFragment.java index 5b34019f1..76ec7e7d1 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/PaginatedAccountListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/PaginatedAccountListFragment.java @@ -1,20 +1,52 @@ package org.joinmastodon.android.fragments.account_list; +import android.net.Uri; + +import org.joinmastodon.android.GlobalUserPreferences; import org.joinmastodon.android.api.requests.HeaderPaginationRequest; +import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.model.Account; import org.joinmastodon.android.model.HeaderPaginationList; +import org.joinmastodon.android.ui.utils.UiUtils; import java.util.stream.Collectors; +import me.grishka.appkit.api.Callback; +import me.grishka.appkit.api.ErrorResponse; import me.grishka.appkit.api.SimpleCallback; public abstract class PaginatedAccountListFragment extends BaseAccountListFragment{ private String nextMaxID; + protected Account targetAccount; + public abstract HeaderPaginationRequest onCreateRequest(String maxID, int count); + public abstract HeaderPaginationRequest onCreateRemoteRequest(String id, String maxID, int count); + @Override protected void doLoadData(int offset, int count){ + if (shouldLoadRemote()) { + UiUtils.lookupRemoteAccount(getContext(), targetAccount, accountID, null, account -> { + if(account != null){ + loadRemoteFollower(offset, count, account); + } else { + loadFollower(offset, count); + } + }); + } else { + loadFollower(offset, count); + } + } + + private boolean shouldLoadRemote() { + if (!GlobalUserPreferences.loadRemoteAccountFollowers && (this instanceof FollowingListFragment || this instanceof FollowerListFragment)) { + return false; + } + return targetAccount != null && targetAccount.getDomain() != null; + } + + void loadFollower(int offset, int count) { currentRequest=onCreateRequest(offset==0 ? null : nextMaxID, count) .setCallback(new SimpleCallback<>(this){ @Override @@ -23,13 +55,42 @@ public abstract class PaginatedAccountListFragment extends BaseAccountListFragme nextMaxID=result.nextPageUri.getQueryParameter("max_id"); else nextMaxID=null; - if (getActivity() == null) return; onDataLoaded(result.stream().map(AccountItem::new).collect(Collectors.toList()), nextMaxID!=null); } }) .exec(accountID); } + private void loadRemoteFollower(int offset, int count, Account account) { + String ownDomain = AccountSessionManager.getInstance().getLastActiveAccount().domain; + currentRequest=onCreateRemoteRequest(account.id, offset==0 ? null : nextMaxID, count) + .setCallback(new Callback<>(){ + @Override + public void onSuccess(HeaderPaginationList result){ + if(result.nextPageUri!=null) + nextMaxID=result.nextPageUri.getQueryParameter("max_id"); + else + nextMaxID=null; + result.stream().forEach(remoteAccount -> { + remoteAccount.reloadWhenClicked = true; + if (remoteAccount.getDomain() == null) { + remoteAccount.acct += "@" + Uri.parse(remoteAccount.url).getHost(); + } else if (remoteAccount.getDomain().equals(ownDomain)) { + remoteAccount.acct = remoteAccount.username; + } + }); + onDataLoaded(result.stream().map(AccountItem::new).collect(Collectors.toList()), nextMaxID!=null); + } + + @Override + public void onError(ErrorResponse error) { + error.showToast(getContext()); + loadFollower(offset, count); + } + }) + .execNoAuth(targetAccount.getDomain()); + } + @Override public void onResume(){ super.onResume(); diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/StatusFavoritesListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/StatusFavoritesListFragment.java index f62e40ac5..9e8f16430 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/StatusFavoritesListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/StatusFavoritesListFragment.java @@ -18,4 +18,9 @@ public class StatusFavoritesListFragment extends StatusRelatedAccountListFragmen public HeaderPaginationRequest onCreateRequest(String maxID, int count){ return new GetStatusFavorites(status.id, maxID, count); } + + @Override + public HeaderPaginationRequest onCreateRemoteRequest(String id, String maxID, int count) { + return null; + } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/StatusReblogsListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/StatusReblogsListFragment.java index 6d494e198..229e64a13 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/StatusReblogsListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/StatusReblogsListFragment.java @@ -18,4 +18,9 @@ public class StatusReblogsListFragment extends StatusRelatedAccountListFragment{ public HeaderPaginationRequest onCreateRequest(String maxID, int count){ return new GetStatusReblogs(status.id, maxID, count); } + + @Override + public HeaderPaginationRequest onCreateRemoteRequest(String id, String maxID, int count) { + return null; + } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/model/Account.java b/mastodon/src/main/java/org/joinmastodon/android/model/Account.java index b4424e0a6..61db2914e 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/model/Account.java +++ b/mastodon/src/main/java/org/joinmastodon/android/model/Account.java @@ -134,8 +134,9 @@ public class Account extends BaseModel implements Searchable{ public Instant muteExpiresAt; public List roles; + public boolean reloadWhenClicked; - @Override + @Override public String getQuery() { return url; } 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 55aaaccc6..e7e367379 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,20 @@ public class UiUtils { return; } - new GetSearchResults(query.getQuery(), type, false).setCallback(new Callback<>() { + Pattern patternForQuery = Pattern.compile("https?:\\/\\/[^\\/]+\\/@(\\w+)"); + Matcher matcherForQuery = patternForQuery.matcher(query.getQuery()); + String trimmedQuery = null; + + if(matcherForQuery.find()){ + trimmedQuery = matcherForQuery.group(1); + } + + if(trimmedQuery == null){ + return; + } + + String finalDomain = domain; + new GetSearchResults(trimmedQuery, type, false).setCallback(new Callback<>() { @Override public void onSuccess(SearchResults results) { Optional result = extractResult.apply(results); @@ -1144,7 +1157,7 @@ public class UiUtils { } }) .wrapProgress((Activity)context, R.string.loading, true, - d -> transformDialogForLookup(context, targetAccountID, null, d)) + d -> transformDialogForLookup(context, targetAccountID, null, d, finalDomain)) .execNoAuth(domain); } @@ -1152,9 +1165,13 @@ public class UiUtils { openURL(context, accountID, url, true); } - private static void transformDialogForLookup(Context context, String accountID, @Nullable String url, ProgressDialog dialog) { + private static void transformDialogForLookup(Context context, String accountID, @Nullable String url, ProgressDialog dialog){ + transformDialogForLookup(context, accountID, url, dialog, null); + } + + private static void transformDialogForLookup(Context context, String accountID, @Nullable String url, ProgressDialog dialog, @Nullable String instanceName) { if (accountID != null) { - dialog.setTitle(context.getString(R.string.sk_loading_resource_on_instance_title, getInstanceName(accountID))); + dialog.setTitle(context.getString(R.string.sk_loading_resource_on_instance_title, instanceName != null ? instanceName : getInstanceName(accountID))); } else { dialog.setTitle(R.string.sk_loading_fediverse_resource_title); }