From 86c332a326171658e723db417febd479e77a5122 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sat, 19 Nov 2022 12:08:31 +0100 Subject: [PATCH 1/5] put values --- .../java/app/fedilab/android/activities/ProfileActivity.java | 3 +++ app/src/main/java/app/fedilab/android/helper/Helper.java | 1 + 2 files changed, 4 insertions(+) diff --git a/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java b/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java index 4a153799..22285dd9 100644 --- a/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java @@ -115,6 +115,7 @@ public class ProfileActivity extends BaseActivity { private String account_id; private String mention_str; private WellKnownNodeinfo.NodeInfo nodeInfo; + private boolean checkRemotely; private final BroadcastReceiver broadcast_data = new BroadcastReceiver() { @Override @@ -141,10 +142,12 @@ public class ProfileActivity extends BaseActivity { ActionBar actionBar = getSupportActionBar(); Bundle b = getIntent().getExtras(); binding.accountFollow.setEnabled(false); + checkRemotely = false; if (b != null) { account = (Account) b.getSerializable(Helper.ARG_ACCOUNT); account_id = b.getString(Helper.ARG_USER_ID, null); mention_str = b.getString(Helper.ARG_MENTION, null); + checkRemotely = b.getBoolean(Helper.ARG_CHECK_REMOTELY, false); } postponeEnterTransition(); diff --git a/app/src/main/java/app/fedilab/android/helper/Helper.java b/app/src/main/java/app/fedilab/android/helper/Helper.java index f9003667..1fb8f2e0 100644 --- a/app/src/main/java/app/fedilab/android/helper/Helper.java +++ b/app/src/main/java/app/fedilab/android/helper/Helper.java @@ -272,6 +272,7 @@ public class Helper { public static final String ARG_SHOW_PINNED = "ARG_SHOW_PINNED"; public static final String ARG_SHOW_MEDIA_ONY = "ARG_SHOW_MEDIA_ONY"; public static final String ARG_MENTION = "ARG_MENTION"; + public static final String ARG_CHECK_REMOTELY = "ARG_CHECK_REMOTELY"; public static final String ARG_USER_ID = "ARG_USER_ID"; public static final String ARG_MEDIA_ARRAY = "ARG_MEDIA_ARRAY"; public static final String ARG_VISIBILITY = "ARG_VISIBILITY"; From a57659bd69e61efe186f1f1f268e747c5a58aeca Mon Sep 17 00:00:00 2001 From: Thomas Date: Sat, 19 Nov 2022 16:44:23 +0100 Subject: [PATCH 2/5] Comment #477 - Add logic for visiting remote profiles --- .../android/activities/ProfileActivity.java | 5 +- .../android/helper/CrossActionHelper.java | 36 ++++++++++ .../timeline/FragmentMastodonTimeline.java | 65 +++++++++++++++++-- .../timeline/FragmentProfileTimeline.java | 5 +- .../FedilabProfilePageAdapter.java | 7 +- .../FedilabProfileTLPageAdapter.java | 6 +- 6 files changed, 113 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java b/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java index 22285dd9..9f0b497e 100644 --- a/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java @@ -142,13 +142,14 @@ public class ProfileActivity extends BaseActivity { ActionBar actionBar = getSupportActionBar(); Bundle b = getIntent().getExtras(); binding.accountFollow.setEnabled(false); - checkRemotely = false; + checkRemotely = true; if (b != null) { account = (Account) b.getSerializable(Helper.ARG_ACCOUNT); account_id = b.getString(Helper.ARG_USER_ID, null); mention_str = b.getString(Helper.ARG_MENTION, null); checkRemotely = b.getBoolean(Helper.ARG_CHECK_REMOTELY, false); } + checkRemotely = true; postponeEnterTransition(); //Remove title @@ -242,7 +243,7 @@ public class ProfileActivity extends BaseActivity { binding.accountTabLayout.clearOnTabSelectedListeners(); binding.accountTabLayout.removeAllTabs(); //Tablayout for timelines/following/followers - FedilabProfileTLPageAdapter fedilabProfileTLPageAdapter = new FedilabProfileTLPageAdapter(getSupportFragmentManager(), account); + FedilabProfileTLPageAdapter fedilabProfileTLPageAdapter = new FedilabProfileTLPageAdapter(getSupportFragmentManager(), account, checkRemotely); binding.accountTabLayout.addTab(binding.accountTabLayout.newTab().setText(getString(R.string.status_cnt, Helper.withSuffix(account.statuses_count)))); binding.accountTabLayout.addTab(binding.accountTabLayout.newTab().setText(getString(R.string.following_cnt, Helper.withSuffix(account.following_count)))); binding.accountTabLayout.addTab(binding.accountTabLayout.newTab().setText(getString(R.string.followers_cnt, Helper.withSuffix(account.followers_count)))); diff --git a/app/src/main/java/app/fedilab/android/helper/CrossActionHelper.java b/app/src/main/java/app/fedilab/android/helper/CrossActionHelper.java index 5e279050..40e62117 100644 --- a/app/src/main/java/app/fedilab/android/helper/CrossActionHelper.java +++ b/app/src/main/java/app/fedilab/android/helper/CrossActionHelper.java @@ -439,6 +439,42 @@ public class CrossActionHelper { } + /** + * Fetch and federate the remote status + */ + public static void fetchAccountInRemoteInstance(@NonNull Context context, String acct, String instance, Callback callback) { + + MastodonSearchService mastodonSearchService = init(context, instance); + new Thread(() -> { + Call resultsCall = mastodonSearchService.search(null, acct, null, "accounts", null, null, null, null, null, null, 1); + Results results = null; + if (resultsCall != null) { + try { + Response resultsResponse = resultsCall.execute(); + if (resultsResponse.isSuccessful()) { + results = resultsResponse.body(); + if (results != null) { + if (results.accounts == null) { + results.accounts = new ArrayList<>(); + } + } + } + } catch (IOException e) { + e.printStackTrace(); + } + } + Handler mainHandler = new Handler(Looper.getMainLooper()); + Results finalResults = results; + Runnable myRunnable = () -> { + if (finalResults != null && finalResults.accounts != null && finalResults.accounts.size() > 0) { + callback.federatedAccount(finalResults.accounts.get(0)); + } + }; + mainHandler.post(myRunnable); + + }).start(); + } + public enum TypeOfCrossAction { FOLLOW_ACTION, UNFOLLOW_ACTION, diff --git a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java index 8d3eebcb..c3487f4b 100644 --- a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java +++ b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java @@ -45,6 +45,7 @@ import java.util.List; import app.fedilab.android.BaseMainActivity; import app.fedilab.android.R; +import app.fedilab.android.activities.MainActivity; import app.fedilab.android.client.entities.api.Account; import app.fedilab.android.client.entities.api.Attachment; import app.fedilab.android.client.entities.api.Pagination; @@ -57,6 +58,7 @@ import app.fedilab.android.client.entities.app.TagTimeline; import app.fedilab.android.client.entities.app.Timeline; import app.fedilab.android.databinding.FragmentPaginationBinding; import app.fedilab.android.exception.DBException; +import app.fedilab.android.helper.CrossActionHelper; import app.fedilab.android.helper.Helper; import app.fedilab.android.helper.MastodonHelper; import app.fedilab.android.helper.ThemeHelper; @@ -81,6 +83,9 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. private StatusAdapter statusAdapter; private Timeline.TimeLineEnum timelineType; private List timelineStatuses; + private boolean checkRemotely; + private String accountIDInRemoteInstance; + //Handle actions that can be done in other fragments private final BroadcastReceiver receive_action = new BroadcastReceiver() { @Override @@ -307,6 +312,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. tagTimeline = (TagTimeline) getArguments().getSerializable(Helper.ARG_TAG_TIMELINE); accountTimeline = (Account) getArguments().getSerializable(Helper.ARG_ACCOUNT); exclude_replies = !getArguments().getBoolean(Helper.ARG_SHOW_REPLIES, true); + checkRemotely = getArguments().getBoolean(Helper.ARG_CHECK_REMOTELY, false); show_pinned = getArguments().getBoolean(Helper.ARG_SHOW_PINNED, false); exclude_reblogs = !getArguments().getBoolean(Helper.ARG_SHOW_REBLOGS, true); media_only = getArguments().getBoolean(Helper.ARG_SHOW_MEDIA_ONY, false); @@ -314,6 +320,13 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. minified = getArguments().getBoolean(Helper.ARG_MINIFIED, false); statusReport = (Status) getArguments().getSerializable(Helper.ARG_STATUS_REPORT); } + //When visiting a profile without being authenticated + if (checkRemotely) { + String[] acctArray = accountTimeline.acct.split("@"); + if (acctArray.length > 1) { + remoteInstance = acctArray[1]; + } + } if (tagTimeline != null) { ident = "@T@" + tagTimeline.name; if (tagTimeline.isART) { @@ -321,7 +334,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. } } else if (list_id != null) { ident = "@l@" + list_id; - } else if (remoteInstance != null) { + } else if (remoteInstance != null && !checkRemotely) { if (pinnedTimeline.remoteInstance.type == RemoteInstance.InstanceType.NITTER) { ident = "@R@" + pinnedTimeline.remoteInstance.host; } else { @@ -915,10 +928,52 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. } else if (timelineType == Timeline.TimeLineEnum.TAG || timelineType == Timeline.TimeLineEnum.ART) { //TAG TIMELINE routeCommon(direction, fetchingMissing, statusToUpdate); } else if (timelineType == Timeline.TimeLineEnum.ACCOUNT_TIMELINE) { //PROFILE TIMELINES - if (direction == null) { + String tempToken; + String tempInstance; + String accountId = null; + if (checkRemotely) { + tempToken = null; + tempInstance = remoteInstance; + accountId = accountIDInRemoteInstance; + if (accountIDInRemoteInstance == null) { + CrossActionHelper.fetchAccountInRemoteInstance(requireActivity(), accountTimeline.acct, tempInstance, new CrossActionHelper.Callback() { + @Override + public void federatedStatus(Status status) { + } + + @Override + public void federatedAccount(Account account) { + if (account != null) { + accountIDInRemoteInstance = account.id; + accountsVM.getAccountStatuses(tempInstance, null, accountIDInRemoteInstance, null, null, null, null, null, false, true, MastodonHelper.statusesPerCall(requireActivity())) + .observe(getViewLifecycleOwner(), pinnedStatuses -> accountsVM.getAccountStatuses(tempInstance, null, accountIDInRemoteInstance, null, null, null, exclude_replies, exclude_reblogs, media_only, false, MastodonHelper.statusesPerCall(requireActivity())) + .observe(getViewLifecycleOwner(), otherStatuses -> { + if (otherStatuses != null && otherStatuses.statuses != null && pinnedStatuses != null && pinnedStatuses.statuses != null) { + for (Status status : pinnedStatuses.statuses) { + status.pinned = true; + } + otherStatuses.statuses.addAll(0, pinnedStatuses.statuses); + initializeStatusesCommonView(otherStatuses); + } + })); + } + } + }); + } else { + accountId = accountIDInRemoteInstance; + } + } else { + tempToken = MainActivity.currentToken; + tempInstance = currentInstance; + accountId = accountTimeline.id; + } + if (accountId == null) { + accountId = accountTimeline.id; + } + if (direction == null && !checkRemotely) { if (show_pinned) { //Fetch pinned statuses to display them at the top - accountsVM.getAccountStatuses(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, accountTimeline.id, null, null, null, null, null, false, true, MastodonHelper.statusesPerCall(requireActivity())) + accountsVM.getAccountStatuses(currentInstance, MainActivity.currentToken, accountId, null, null, null, null, null, false, true, MastodonHelper.statusesPerCall(requireActivity())) .observe(getViewLifecycleOwner(), pinnedStatuses -> accountsVM.getAccountStatuses(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, accountTimeline.id, null, null, null, exclude_replies, exclude_reblogs, media_only, false, MastodonHelper.statusesPerCall(requireActivity())) .observe(getViewLifecycleOwner(), otherStatuses -> { if (otherStatuses != null && otherStatuses.statuses != null && pinnedStatuses != null && pinnedStatuses.statuses != null) { @@ -930,11 +985,11 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. } })); } else { - accountsVM.getAccountStatuses(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, accountTimeline.id, null, null, null, exclude_replies, exclude_reblogs, media_only, false, MastodonHelper.statusesPerCall(requireActivity())) + accountsVM.getAccountStatuses(tempInstance, tempToken, accountId, null, null, null, exclude_replies, exclude_reblogs, media_only, false, MastodonHelper.statusesPerCall(requireActivity())) .observe(getViewLifecycleOwner(), this::initializeStatusesCommonView); } } else if (direction == DIRECTION.BOTTOM) { - accountsVM.getAccountStatuses(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, accountTimeline.id, max_id, null, null, exclude_replies, exclude_reblogs, media_only, false, MastodonHelper.statusesPerCall(requireActivity())) + accountsVM.getAccountStatuses(tempInstance, tempToken, accountId, max_id, null, null, exclude_replies, exclude_reblogs, media_only, false, MastodonHelper.statusesPerCall(requireActivity())) .observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, false)); } else { flagLoading = false; diff --git a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentProfileTimeline.java b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentProfileTimeline.java index 3ab5978a..03c76339 100644 --- a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentProfileTimeline.java +++ b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentProfileTimeline.java @@ -37,12 +37,13 @@ public class FragmentProfileTimeline extends Fragment { private Account account; private FragmentProfileTimelinesBinding binding; - + private boolean checkRemotely; public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (getArguments() != null) { account = (Account) getArguments().getSerializable(Helper.ARG_ACCOUNT); + checkRemotely = getArguments().getBoolean(Helper.ARG_CHECK_REMOTELY, false); } binding = FragmentProfileTimelinesBinding.inflate(inflater, container, false); return binding.getRoot(); @@ -57,7 +58,7 @@ public class FragmentProfileTimeline extends Fragment { binding.tabLayout.addTab(binding.tabLayout.newTab().setText(getString(R.string.media))); binding.tabLayout.setTabTextColors(ThemeHelper.getAttColor(requireActivity(), R.attr.mTextColor), ContextCompat.getColor(requireActivity(), R.color.cyanea_accent_dark_reference)); binding.tabLayout.setTabIconTint(ThemeHelper.getColorStateList(requireActivity())); - binding.viewpager.setAdapter(new FedilabProfilePageAdapter(getChildFragmentManager(), account)); + binding.viewpager.setAdapter(new FedilabProfilePageAdapter(getChildFragmentManager(), account, checkRemotely)); binding.viewpager.setOffscreenPageLimit(3); binding.viewpager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(binding.tabLayout)); binding.tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { diff --git a/app/src/main/java/app/fedilab/android/ui/pageadapter/FedilabProfilePageAdapter.java b/app/src/main/java/app/fedilab/android/ui/pageadapter/FedilabProfilePageAdapter.java index 39369fb2..372f7659 100644 --- a/app/src/main/java/app/fedilab/android/ui/pageadapter/FedilabProfilePageAdapter.java +++ b/app/src/main/java/app/fedilab/android/ui/pageadapter/FedilabProfilePageAdapter.java @@ -31,10 +31,12 @@ import app.fedilab.android.ui.fragment.timeline.FragmentMastodonTimeline; public class FedilabProfilePageAdapter extends FragmentStatePagerAdapter { private final Account account; private Fragment mCurrentFragment; + private final boolean checkRemotely; - public FedilabProfilePageAdapter(FragmentManager fm, Account account) { + public FedilabProfilePageAdapter(FragmentManager fm, Account account, boolean remotely) { super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); this.account = account; + this.checkRemotely = remotely; } public Fragment getCurrentFragment() { @@ -62,6 +64,7 @@ public class FedilabProfilePageAdapter extends FragmentStatePagerAdapter { bundle.putBoolean(Helper.ARG_SHOW_PINNED, true); bundle.putBoolean(Helper.ARG_SHOW_REPLIES, false); bundle.putBoolean(Helper.ARG_SHOW_REBLOGS, true); + bundle.putBoolean(Helper.ARG_CHECK_REMOTELY, checkRemotely); fragmentProfileTimeline.setArguments(bundle); return fragmentProfileTimeline; case 1: @@ -71,11 +74,13 @@ public class FedilabProfilePageAdapter extends FragmentStatePagerAdapter { bundle.putBoolean(Helper.ARG_SHOW_PINNED, false); bundle.putBoolean(Helper.ARG_SHOW_REPLIES, true); bundle.putBoolean(Helper.ARG_SHOW_REBLOGS, false); + bundle.putBoolean(Helper.ARG_CHECK_REMOTELY, checkRemotely); fragmentProfileTimeline.setArguments(bundle); return fragmentProfileTimeline; case 2: FragmentMediaProfile fragmentMediaProfile = new FragmentMediaProfile(); bundle.putSerializable(Helper.ARG_ACCOUNT, account); + bundle.putBoolean(Helper.ARG_CHECK_REMOTELY, checkRemotely); fragmentMediaProfile.setArguments(bundle); return fragmentMediaProfile; default: diff --git a/app/src/main/java/app/fedilab/android/ui/pageadapter/FedilabProfileTLPageAdapter.java b/app/src/main/java/app/fedilab/android/ui/pageadapter/FedilabProfileTLPageAdapter.java index 585a6b48..ca2ebb26 100644 --- a/app/src/main/java/app/fedilab/android/ui/pageadapter/FedilabProfileTLPageAdapter.java +++ b/app/src/main/java/app/fedilab/android/ui/pageadapter/FedilabProfileTLPageAdapter.java @@ -31,10 +31,12 @@ import app.fedilab.android.ui.fragment.timeline.FragmentProfileTimeline; public class FedilabProfileTLPageAdapter extends FragmentStatePagerAdapter { private final Account account; private Fragment mCurrentFragment; + private final boolean checkRemotely; - public FedilabProfileTLPageAdapter(FragmentManager fm, Account account) { + public FedilabProfileTLPageAdapter(FragmentManager fm, Account account, boolean remotely) { super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); this.account = account; + this.checkRemotely = remotely; } public Fragment getCurrentFragment() { @@ -57,6 +59,7 @@ public class FedilabProfileTLPageAdapter extends FragmentStatePagerAdapter { FragmentProfileTimeline fragmentProfileTimeline = new FragmentProfileTimeline(); Bundle bundle = new Bundle(); bundle.putSerializable(Helper.ARG_ACCOUNT, account); + bundle.putSerializable(Helper.ARG_CHECK_REMOTELY, checkRemotely); fragmentProfileTimeline.setArguments(bundle); return fragmentProfileTimeline; case 1: @@ -64,6 +67,7 @@ public class FedilabProfileTLPageAdapter extends FragmentStatePagerAdapter { FragmentMastodonAccount fragmentMastodonAccount = new FragmentMastodonAccount(); bundle = new Bundle(); bundle.putSerializable(Helper.ARG_ACCOUNT, account); + bundle.putSerializable(Helper.ARG_CHECK_REMOTELY, checkRemotely); bundle.putString(Helper.ARG_VIEW_MODEL_KEY, "FEDILAB_" + position); bundle.putSerializable(Helper.ARG_FOLLOW_TYPE, position == 1 ? follow_type.FOLLOWING : follow_type.FOLLOWERS); fragmentMastodonAccount.setArguments(bundle); From fdc365dc00439d0e73f156ac3c28888417325f35 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sat, 19 Nov 2022 16:50:55 +0100 Subject: [PATCH 3/5] Comment #477 - Allow remote actions --- .../fedilab/android/ui/drawer/NotificationAdapter.java | 2 +- .../app/fedilab/android/ui/drawer/StatusAdapter.java | 10 ++++++---- .../ui/fragment/timeline/FragmentMastodonContext.java | 2 +- .../ui/fragment/timeline/FragmentMastodonTimeline.java | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/app/fedilab/android/ui/drawer/NotificationAdapter.java b/app/src/main/java/app/fedilab/android/ui/drawer/NotificationAdapter.java index 04aae75d..4009f56e 100644 --- a/app/src/main/java/app/fedilab/android/ui/drawer/NotificationAdapter.java +++ b/app/src/main/java/app/fedilab/android/ui/drawer/NotificationAdapter.java @@ -259,7 +259,7 @@ public class NotificationAdapter extends RecyclerView.Adapter private final boolean minified; private final Timeline.TimeLineEnum timelineType; private final boolean canBeFederated; + private final boolean checkRemotely; public FetchMoreCallBack fetchMoreCallBack; private Context context; - public StatusAdapter(List statuses, Timeline.TimeLineEnum timelineType, boolean minified, boolean canBeFederated) { + public StatusAdapter(List statuses, Timeline.TimeLineEnum timelineType, boolean minified, boolean canBeFederated, boolean checkRemotely) { this.statusList = statuses; this.timelineType = timelineType; this.minified = minified; this.canBeFederated = canBeFederated; + this.checkRemotely = checkRemotely; } @@ -349,14 +351,14 @@ public class StatusAdapter extends RecyclerView.Adapter List statusList, Status status, Timeline.TimeLineEnum timelineType, - boolean minified, boolean canBeFederated, + boolean minified, boolean canBeFederated, boolean checkRemotely, FetchMoreCallBack fetchMoreCallBack) { if (status == null) { return; } SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context); - boolean remote = timelineType == Timeline.TimeLineEnum.REMOTE; + boolean remote = timelineType == Timeline.TimeLineEnum.REMOTE || checkRemotely; Status statusToDeal = status.reblog != null ? status.reblog : status; @@ -2161,7 +2163,7 @@ public class StatusAdapter extends RecyclerView.Adapter StatusViewHolder holder = (StatusViewHolder) viewHolder; StatusesVM statusesVM = new ViewModelProvider((ViewModelStoreOwner) context).get(StatusesVM.class); SearchVM searchVM = new ViewModelProvider((ViewModelStoreOwner) context).get(SearchVM.class); - statusManagement(context, statusesVM, searchVM, holder, this, statusList, status, timelineType, minified, canBeFederated, fetchMoreCallBack); + statusManagement(context, statusesVM, searchVM, holder, this, statusList, status, timelineType, minified, canBeFederated, checkRemotely, fetchMoreCallBack); } else if (viewHolder.getItemViewType() == STATUS_FILTERED) { StatusViewHolder holder = (StatusViewHolder) viewHolder; holder.bindingFiltered.filteredText.setText(context.getString(R.string.filtered_by, status.filteredByApp.title)); diff --git a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonContext.java b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonContext.java index a5138f52..2388ecc1 100644 --- a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonContext.java +++ b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonContext.java @@ -162,7 +162,7 @@ public class FragmentMastodonContext extends Fragment { this.statuses = new ArrayList<>(); focusedStatus.isFocused = true; this.statuses.add(focusedStatus); - statusAdapter = new StatusAdapter(this.statuses, Timeline.TimeLineEnum.UNKNOWN, false, true); + statusAdapter = new StatusAdapter(this.statuses, Timeline.TimeLineEnum.UNKNOWN, false, true, false); binding.swipeContainer.setRefreshing(false); LinearLayoutManager mLayoutManager = new LinearLayoutManager(requireActivity()); binding.recyclerView.setLayoutManager(mLayoutManager); diff --git a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java index c3487f4b..c822467e 100644 --- a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java +++ b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java @@ -530,7 +530,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. if (min_id == null || (statuses.pagination.min_id != null && Helper.compareTo(statuses.pagination.min_id, min_id) > 0)) { min_id = statuses.pagination.min_id; } - statusAdapter = new StatusAdapter(timelineStatuses, timelineType, minified, canBeFederated); + statusAdapter = new StatusAdapter(timelineStatuses, timelineType, minified, canBeFederated, checkRemotely); statusAdapter.fetchMoreCallBack = this; if (statusReport != null) { scrollToTop(); From 4263d6f842880b883ef8fa560667a2f120fd99df Mon Sep 17 00:00:00 2001 From: Thomas Date: Sat, 19 Nov 2022 17:17:23 +0100 Subject: [PATCH 4/5] Comment #477 - Add button to display messages remotely --- .../android/activities/ProfileActivity.java | 23 +++++++++--- .../drawable/ic_baseline_manage_search_24.xml | 11 ++++++ app/src/main/res/layout/activity_profile.xml | 35 +++++++++++++++---- app/src/main/res/values/strings.xml | 1 + 4 files changed, 58 insertions(+), 12 deletions(-) create mode 100644 app/src/main/res/drawable/ic_baseline_manage_search_24.xml diff --git a/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java b/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java index 9f0b497e..0384c872 100644 --- a/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java @@ -142,14 +142,13 @@ public class ProfileActivity extends BaseActivity { ActionBar actionBar = getSupportActionBar(); Bundle b = getIntent().getExtras(); binding.accountFollow.setEnabled(false); - checkRemotely = true; + checkRemotely = false; if (b != null) { account = (Account) b.getSerializable(Helper.ARG_ACCOUNT); account_id = b.getString(Helper.ARG_USER_ID, null); mention_str = b.getString(Helper.ARG_MENTION, null); checkRemotely = b.getBoolean(Helper.ARG_CHECK_REMOTELY, false); } - checkRemotely = true; postponeEnterTransition(); //Remove title @@ -343,11 +342,25 @@ public class ProfileActivity extends BaseActivity { binding.accountMoved.setMovementMethod(LinkMovementMethod.getInstance()); } if (account.acct != null && account.acct.contains("@")) - binding.warningMessage.setVisibility(View.VISIBLE); + binding.warningContainer.setVisibility(View.VISIBLE); else - binding.warningMessage.setVisibility(View.GONE); - + binding.warningContainer.setVisibility(View.GONE); + binding.openRemoteProfile.setBackgroundTintList(ThemeHelper.getButtonActionColorStateList(ProfileActivity.this)); + if (checkRemotely) { + binding.openRemoteProfile.setVisibility(View.GONE); + } + binding.openRemoteProfile.setOnClickListener(v -> { + Intent intent = new Intent(ProfileActivity.this, ProfileActivity.class); + Bundle b = new Bundle(); + b.putSerializable(Helper.ARG_ACCOUNT, account); + b.putSerializable(Helper.ARG_CHECK_REMOTELY, true); + intent.putExtras(b); + ActivityOptionsCompat options = ActivityOptionsCompat + .makeSceneTransitionAnimation(ProfileActivity.this, binding.profilePicture, getString(R.string.activity_porfile_pp)); + startActivity(intent, options.toBundle()); + finish(); + }); //Fields for profile List fields = account.fields; if (fields != null && fields.size() > 0) { diff --git a/app/src/main/res/drawable/ic_baseline_manage_search_24.xml b/app/src/main/res/drawable/ic_baseline_manage_search_24.xml new file mode 100644 index 00000000..6c4f34d3 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_manage_search_24.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/layout/activity_profile.xml b/app/src/main/res/layout/activity_profile.xml index c2796af7..dc52f2c1 100644 --- a/app/src/main/res/layout/activity_profile.xml +++ b/app/src/main/res/layout/activity_profile.xml @@ -325,18 +325,39 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/info" /> - + app:layout_constraintTop_toBottomOf="@+id/fields_container" + tools:visibility="visible"> + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 43ff53b1..7d10dd68 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1899,4 +1899,5 @@ Show anyway Filtered: %1$s The app failed to add the account into the list! + Display remote profile \ No newline at end of file From 98c1a7e1b54a486cf2c366dd304707bd8b102c67 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sat, 19 Nov 2022 17:43:27 +0100 Subject: [PATCH 5/5] Comment #477 - Display remote media timeline --- .../fragment/media/FragmentMediaProfile.java | 43 +++++++++++++++++-- .../timeline/FragmentMastodonTimeline.java | 16 ++++--- app/src/main/res/values/strings.xml | 1 + 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/app/fedilab/android/ui/fragment/media/FragmentMediaProfile.java b/app/src/main/java/app/fedilab/android/ui/fragment/media/FragmentMediaProfile.java index 732592bf..2bfc1721 100644 --- a/app/src/main/java/app/fedilab/android/ui/fragment/media/FragmentMediaProfile.java +++ b/app/src/main/java/app/fedilab/android/ui/fragment/media/FragmentMediaProfile.java @@ -30,15 +30,18 @@ import java.util.ArrayList; import java.util.List; import app.fedilab.android.BaseMainActivity; +import app.fedilab.android.R; import app.fedilab.android.client.entities.api.Account; import app.fedilab.android.client.entities.api.Attachment; import app.fedilab.android.client.entities.api.Status; import app.fedilab.android.client.entities.api.Statuses; import app.fedilab.android.databinding.FragmentPaginationBinding; +import app.fedilab.android.helper.CrossActionHelper; import app.fedilab.android.helper.Helper; import app.fedilab.android.helper.MastodonHelper; import app.fedilab.android.ui.drawer.ImageAdapter; import app.fedilab.android.viewmodel.mastodon.AccountsVM; +import es.dmoral.toasty.Toasty; public class FragmentMediaProfile extends Fragment { @@ -50,6 +53,10 @@ public class FragmentMediaProfile extends Fragment { private List mediaStatuses; private String max_id; private ImageAdapter imageAdapter; + String tempToken; + String tempInstance; + private boolean checkRemotely; + private String accountId; @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -58,6 +65,7 @@ public class FragmentMediaProfile extends Fragment { Bundle bundle = this.getArguments(); if (bundle != null) { accountTimeline = (Account) getArguments().getSerializable(Helper.ARG_ACCOUNT); + checkRemotely = getArguments().getBoolean(Helper.ARG_CHECK_REMOTELY, false); } return binding.getRoot(); } @@ -68,8 +76,37 @@ public class FragmentMediaProfile extends Fragment { flagLoading = false; accountsVM = new ViewModelProvider(FragmentMediaProfile.this).get(AccountsVM.class); mediaStatuses = new ArrayList<>(); - accountsVM.getAccountStatuses(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, accountTimeline.id, null, null, null, null, null, true, false, MastodonHelper.statusesPerCall(requireActivity())) - .observe(getViewLifecycleOwner(), this::initializeStatusesCommonView); + + if (checkRemotely) { + tempToken = null; + String[] acctArray = accountTimeline.acct.split("@"); + if (acctArray.length > 1) { + tempInstance = acctArray[1]; + } + CrossActionHelper.fetchAccountInRemoteInstance(requireActivity(), accountTimeline.acct, tempInstance, new CrossActionHelper.Callback() { + @Override + public void federatedStatus(Status status) { + } + + @Override + public void federatedAccount(Account account) { + if (account != null) { + accountId = account.id; + accountsVM.getAccountStatuses(tempInstance, null, accountId, null, null, null, null, null, true, false, MastodonHelper.statusesPerCall(requireActivity())) + .observe(getViewLifecycleOwner(), statuses -> initializeStatusesCommonView(statuses)); + } else { + Toasty.error(requireActivity(), getString(R.string.toast_fetch_error), Toasty.LENGTH_LONG).show(); + } + } + }); + } else { + tempToken = BaseMainActivity.currentToken; + tempInstance = BaseMainActivity.currentInstance; + accountId = accountTimeline.id; + accountsVM.getAccountStatuses(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, accountTimeline.id, null, null, null, null, null, true, false, MastodonHelper.statusesPerCall(requireActivity())) + .observe(getViewLifecycleOwner(), this::initializeStatusesCommonView); + } + } /** @@ -133,7 +170,7 @@ public class FragmentMediaProfile extends Fragment { if (!flagLoading) { flagLoading = true; binding.loadingNextElements.setVisibility(View.VISIBLE); - accountsVM.getAccountStatuses(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, accountTimeline.id, max_id, null, null, null, null, true, false, MastodonHelper.statusesPerCall(requireActivity())) + accountsVM.getAccountStatuses(tempInstance, tempToken, accountId, max_id, null, null, null, null, true, false, MastodonHelper.statusesPerCall(requireActivity())) .observe(getViewLifecycleOwner(), newStatuses -> dealWithPagination(newStatuses)); } } else { diff --git a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java index c822467e..ab7e1a42 100644 --- a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java +++ b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java @@ -930,7 +930,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. } else if (timelineType == Timeline.TimeLineEnum.ACCOUNT_TIMELINE) { //PROFILE TIMELINES String tempToken; String tempInstance; - String accountId = null; + String accountId; if (checkRemotely) { tempToken = null; tempInstance = remoteInstance; @@ -948,14 +948,18 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. accountsVM.getAccountStatuses(tempInstance, null, accountIDInRemoteInstance, null, null, null, null, null, false, true, MastodonHelper.statusesPerCall(requireActivity())) .observe(getViewLifecycleOwner(), pinnedStatuses -> accountsVM.getAccountStatuses(tempInstance, null, accountIDInRemoteInstance, null, null, null, exclude_replies, exclude_reblogs, media_only, false, MastodonHelper.statusesPerCall(requireActivity())) .observe(getViewLifecycleOwner(), otherStatuses -> { - if (otherStatuses != null && otherStatuses.statuses != null && pinnedStatuses != null && pinnedStatuses.statuses != null) { - for (Status status : pinnedStatuses.statuses) { - status.pinned = true; + if (otherStatuses != null && otherStatuses.statuses != null) { + if (pinnedStatuses != null && pinnedStatuses.statuses != null) { + for (Status status : pinnedStatuses.statuses) { + status.pinned = true; + } + otherStatuses.statuses.addAll(0, pinnedStatuses.statuses); } - otherStatuses.statuses.addAll(0, pinnedStatuses.statuses); - initializeStatusesCommonView(otherStatuses); } + initializeStatusesCommonView(otherStatuses); })); + } else { + Toasty.error(requireActivity(), getString(R.string.toast_fetch_error), Toasty.LENGTH_LONG).show(); } } }); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7d10dd68..16bda48a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1900,4 +1900,5 @@ Filtered: %1$s The app failed to add the account into the list! Display remote profile + The app cannot find remote data! \ No newline at end of file