diff --git a/app/src/main/java/com/keylesspalace/tusky/AccountActivity.java b/app/src/main/java/com/keylesspalace/tusky/AccountActivity.java index ebf1ebd9..df7afd39 100644 --- a/app/src/main/java/com/keylesspalace/tusky/AccountActivity.java +++ b/app/src/main/java/com/keylesspalace/tusky/AccountActivity.java @@ -28,6 +28,7 @@ import android.support.design.widget.CollapsingToolbarLayout; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.design.widget.TabLayout; +import android.support.v4.app.Fragment; import android.support.v4.view.ViewCompat; import android.support.v4.view.ViewPager; import android.support.v7.app.ActionBar; @@ -54,7 +55,7 @@ import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; -public class AccountActivity extends BaseActivity { +public class AccountActivity extends BaseActivity implements SFragment.OnUserRemovedListener { private static final String TAG = "AccountActivity"; // logging tag private String accountId; @@ -63,6 +64,7 @@ public class AccountActivity extends BaseActivity { private boolean muting = false; private boolean isSelf; private TabLayout tabLayout; + private AccountPagerAdapter pagerAdapter; private Account loadedAccount; @BindView(R.id.account_locked) ImageView accountLockedView; @@ -80,8 +82,7 @@ public class AccountActivity extends BaseActivity { accountId = intent.getStringExtra("id"); } - SharedPreferences preferences = getSharedPreferences( - getString(R.string.preferences_file_key), Context.MODE_PRIVATE); + SharedPreferences preferences = getPrivatePreferences(); String loggedInAccountId = preferences.getString("loggedInAccountId", null); final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); @@ -142,6 +143,7 @@ public class AccountActivity extends BaseActivity { // Setup the tabs and timeline pager. AccountPagerAdapter adapter = new AccountPagerAdapter(getSupportFragmentManager(), this, accountId); + pagerAdapter = adapter; String[] pageTitles = { getString(R.string.title_statuses), getString(R.string.title_follows), @@ -165,6 +167,12 @@ public class AccountActivity extends BaseActivity { } } + @Override + protected void onSaveInstanceState(Bundle outState) { + outState.putString("accountId", accountId); + super.onSaveInstanceState(outState); + } + private void obtainAccount() { mastodonAPI.account(accountId).enqueue(new Callback() { @Override @@ -183,12 +191,6 @@ public class AccountActivity extends BaseActivity { }); } - @Override - protected void onSaveInstanceState(Bundle outState) { - outState.putString("accountId", accountId); - super.onSaveInstanceState(outState); - } - private void onObtainAccountSuccess(Account account) { loadedAccount = account; @@ -289,6 +291,16 @@ public class AccountActivity extends BaseActivity { updateButtons(); } + @Override + public void onUserRemoved(String accountId) { + for (Fragment fragment : pagerAdapter.getRegisteredFragments()) { + if (fragment instanceof StatusRemoveListener) { + StatusRemoveListener listener = (StatusRemoveListener) fragment; + listener.removePostsByUser(accountId); + } + } + } + private void updateFollowButton(FloatingActionButton button) { if (following) { button.setImageResource(R.drawable.ic_person_minus_24px); diff --git a/app/src/main/java/com/keylesspalace/tusky/AccountPagerAdapter.java b/app/src/main/java/com/keylesspalace/tusky/AccountPagerAdapter.java index ff500001..dd56dfad 100644 --- a/app/src/main/java/com/keylesspalace/tusky/AccountPagerAdapter.java +++ b/app/src/main/java/com/keylesspalace/tusky/AccountPagerAdapter.java @@ -24,15 +24,20 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import java.util.ArrayList; +import java.util.List; + class AccountPagerAdapter extends FragmentPagerAdapter { private Context context; private String accountId; private String[] pageTitles; + private List registeredFragments; AccountPagerAdapter(FragmentManager manager, Context context, String accountId) { super(manager); this.context = context; this.accountId = accountId; + registeredFragments = new ArrayList<>(); } void setPageTitles(String[] titles) { @@ -73,4 +78,21 @@ class AccountPagerAdapter extends FragmentPagerAdapter { title.setText(pageTitles[position]); return view; } + + @Override + public Object instantiateItem(ViewGroup container, int position) { + Fragment fragment = (Fragment) super.instantiateItem(container, position); + registeredFragments.add(fragment); + return fragment; + } + + @Override + public void destroyItem(ViewGroup container, int position, Object object) { + registeredFragments.remove((Fragment) object); + super.destroyItem(container, position, object); + } + + List getRegisteredFragments() { + return registeredFragments; + } } diff --git a/app/src/main/java/com/keylesspalace/tusky/AdapterItemRemover.java b/app/src/main/java/com/keylesspalace/tusky/AdapterItemRemover.java index aff7b033..634935ff 100644 --- a/app/src/main/java/com/keylesspalace/tusky/AdapterItemRemover.java +++ b/app/src/main/java/com/keylesspalace/tusky/AdapterItemRemover.java @@ -17,5 +17,4 @@ package com.keylesspalace.tusky; interface AdapterItemRemover { void removeItem(int position); - void removeAllByAccountId(String accountId); } diff --git a/app/src/main/java/com/keylesspalace/tusky/MainActivity.java b/app/src/main/java/com/keylesspalace/tusky/MainActivity.java index 2a24c362..f42dd72c 100644 --- a/app/src/main/java/com/keylesspalace/tusky/MainActivity.java +++ b/app/src/main/java/com/keylesspalace/tusky/MainActivity.java @@ -20,7 +20,6 @@ import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Typeface; import android.graphics.drawable.Drawable; -import android.graphics.drawable.Icon; import android.net.Uri; import android.os.Bundle; import android.os.PersistableBundle; @@ -43,12 +42,10 @@ import com.arlib.floatingsearchview.suggestions.SearchSuggestionsAdapter; import com.arlib.floatingsearchview.suggestions.model.SearchSuggestion; import com.keylesspalace.tusky.entity.Account; import com.mikepenz.google_material_typeface_library.GoogleMaterial; -import com.mikepenz.iconics.typeface.GenericFont; import com.mikepenz.materialdrawer.AccountHeader; import com.mikepenz.materialdrawer.AccountHeaderBuilder; import com.mikepenz.materialdrawer.Drawer; import com.mikepenz.materialdrawer.DrawerBuilder; -import com.mikepenz.materialdrawer.icons.MaterialDrawerFont; import com.mikepenz.materialdrawer.model.DividerDrawerItem; import com.mikepenz.materialdrawer.model.PrimaryDrawerItem; import com.mikepenz.materialdrawer.model.ProfileDrawerItem; @@ -69,8 +66,8 @@ import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; -public class MainActivity extends BaseActivity { - private static final String TAG = "MainActivity"; // logging tag and Volley request tag +public class MainActivity extends BaseActivity implements SFragment.OnUserRemovedListener { + private static final String TAG = "MainActivity"; // logging tag protected static int COMPOSE_RESULT = 1; private String loggedInAccountId; @@ -518,12 +515,22 @@ public class MainActivity extends BaseActivity { } @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, + @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); - List fragments = getSupportFragmentManager().getFragments(); - if (fragments != null) { - for (Fragment fragment : fragments) { - fragment.onRequestPermissionsResult(requestCode, permissions, grantResults); + TimelinePagerAdapter adapter = (TimelinePagerAdapter) viewPager.getAdapter(); + for (Fragment fragment : adapter.getRegisteredFragments()) { + fragment.onRequestPermissionsResult(requestCode, permissions, grantResults); + } + } + + @Override + public void onUserRemoved(String accountId) { + TimelinePagerAdapter adapter = (TimelinePagerAdapter) viewPager.getAdapter(); + for (Fragment fragment : adapter.getRegisteredFragments()) { + if (fragment instanceof StatusRemoveListener) { + StatusRemoveListener listener = (StatusRemoveListener) fragment; + listener.removePostsByUser(accountId); } } } diff --git a/app/src/main/java/com/keylesspalace/tusky/NotificationsFragment.java b/app/src/main/java/com/keylesspalace/tusky/NotificationsFragment.java index b754e6c4..76a89c1f 100644 --- a/app/src/main/java/com/keylesspalace/tusky/NotificationsFragment.java +++ b/app/src/main/java/com/keylesspalace/tusky/NotificationsFragment.java @@ -39,7 +39,7 @@ import retrofit2.Callback; import retrofit2.Response; public class NotificationsFragment extends SFragment implements - SwipeRefreshLayout.OnRefreshListener, StatusActionListener, + SwipeRefreshLayout.OnRefreshListener, StatusActionListener, StatusRemoveListener, NotificationsAdapter.NotificationActionListener { private static final String TAG = "Notifications"; // logging tag @@ -57,11 +57,6 @@ public class NotificationsFragment extends SFragment implements return fragment; } - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - } - @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @@ -117,12 +112,6 @@ public class NotificationsFragment extends SFragment implements return rootView; } - @Override - public void onResume() { - super.onResume(); - sendFetchNotificationsRequest(); - } - @Override public void onDestroy() { super.onDestroy(); @@ -142,13 +131,11 @@ public class NotificationsFragment extends SFragment implements } private void sendFetchNotificationsRequest(final String fromId, String uptoId) { - MastodonAPI api = ((BaseActivity) getActivity()).mastodonAPI; - if (fromId != null || adapter.getItemCount() <= 1) { adapter.setFooterState(NotificationsAdapter.FooterState.LOADING); } - listCall = api.notifications(fromId, uptoId, null); + listCall = mastodonAPI.notifications(fromId, uptoId, null); listCall.enqueue(new Callback>() { @Override @@ -172,6 +159,10 @@ public class NotificationsFragment extends SFragment implements sendFetchNotificationsRequest(null, null); } + public void removePostsByUser(String accountId) { + adapter.removeAllByAccountId(accountId); + } + private static boolean findNotification(List notifications, String id) { for (Notification notification : notifications) { if (notification.id.equals(id)) { diff --git a/app/src/main/java/com/keylesspalace/tusky/SFragment.java b/app/src/main/java/com/keylesspalace/tusky/SFragment.java index 482d3a3b..3fb124b2 100644 --- a/app/src/main/java/com/keylesspalace/tusky/SFragment.java +++ b/app/src/main/java/com/keylesspalace/tusky/SFragment.java @@ -46,8 +46,14 @@ import retrofit2.Response; * overlap functionality. So, I'm momentarily leaving it and hopefully working on those will clear * up what needs to be where. */ public abstract class SFragment extends BaseFragment { + interface OnUserRemovedListener { + void onUserRemoved(String accountId); + } + protected String loggedInAccountId; protected String loggedInUsername; + protected MastodonAPI mastodonAPI; + protected OnUserRemovedListener userRemovedListener; protected static int COMPOSE_RESULT = 1; @Override @@ -60,8 +66,12 @@ public abstract class SFragment extends BaseFragment { loggedInUsername = preferences.getString("loggedInAccountUsername", null); } - public MastodonAPI getApi() { - return ((BaseActivity) getActivity()).mastodonAPI; + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + BaseActivity activity = (BaseActivity) getActivity(); + mastodonAPI = activity.mastodonAPI; + userRemovedListener = (OnUserRemovedListener) activity; } protected void reply(Status status) { @@ -84,8 +94,7 @@ public abstract class SFragment extends BaseFragment { startActivityForResult(intent, COMPOSE_RESULT); } - public void onSuccessfulStatus() { - } + public void onSuccessfulStatus() {} @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { @@ -115,16 +124,14 @@ public abstract class SFragment extends BaseFragment { } @Override - public void onFailure(Call call, Throwable t) { - - } + public void onFailure(Call call, Throwable t) {} }; Call call; if (reblog) { - call = getApi().reblogStatus(id); + call = mastodonAPI.reblogStatus(id); } else { - call = getApi().unreblogStatus(id); + call = mastodonAPI.unreblogStatus(id); } call.enqueue(cb); callList.add(call); @@ -149,23 +156,21 @@ public abstract class SFragment extends BaseFragment { } @Override - public void onFailure(Call call, Throwable t) { - - } + public void onFailure(Call call, Throwable t) {} }; Call call; if (favourite) { - call = getApi().favouriteStatus(id); + call = mastodonAPI.favouriteStatus(id); } else { - call = getApi().unfavouriteStatus(id); + call = mastodonAPI.unfavouriteStatus(id); } call.enqueue(cb); callList.add(call); } private void mute(String id) { - Call call = getApi().muteAccount(id); + Call call = mastodonAPI.muteAccount(id); call.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) {} @@ -174,10 +179,11 @@ public abstract class SFragment extends BaseFragment { public void onFailure(Call call, Throwable t) {} }); callList.add(call); + userRemovedListener.onUserRemoved(id); } private void block(String id) { - Call call = getApi().blockAccount(id); + Call call = mastodonAPI.blockAccount(id); call.enqueue(new Callback() { @Override public void onResponse(Call call, retrofit2.Response response) {} @@ -186,10 +192,11 @@ public abstract class SFragment extends BaseFragment { public void onFailure(Call call, Throwable t) {} }); callList.add(call); + userRemovedListener.onUserRemoved(id); } private void delete(String id) { - Call call = getApi().deleteStatus(id); + Call call = mastodonAPI.deleteStatus(id); call.enqueue(new Callback() { @Override public void onResponse(Call call, retrofit2.Response response) {} @@ -242,12 +249,10 @@ public abstract class SFragment extends BaseFragment { } case R.id.status_mute: { mute(accountId); - adapter.removeAllByAccountId(accountId); return true; } case R.id.status_block: { block(accountId); - adapter.removeAllByAccountId(accountId); return true; } case R.id.status_report: { diff --git a/app/src/main/java/com/keylesspalace/tusky/StatusRemoveListener.java b/app/src/main/java/com/keylesspalace/tusky/StatusRemoveListener.java new file mode 100644 index 00000000..b662f237 --- /dev/null +++ b/app/src/main/java/com/keylesspalace/tusky/StatusRemoveListener.java @@ -0,0 +1,5 @@ +package com.keylesspalace.tusky; + +interface StatusRemoveListener { + void removePostsByUser(String accountId); +} diff --git a/app/src/main/java/com/keylesspalace/tusky/TimelineAdapter.java b/app/src/main/java/com/keylesspalace/tusky/TimelineAdapter.java index d2dd0b09..759a2357 100644 --- a/app/src/main/java/com/keylesspalace/tusky/TimelineAdapter.java +++ b/app/src/main/java/com/keylesspalace/tusky/TimelineAdapter.java @@ -142,7 +142,7 @@ class TimelineAdapter extends RecyclerView.Adapter implements AdapterItemRemover notifyItemRemoved(position); } - public void removeAllByAccountId(String accountId) { + void removeAllByAccountId(String accountId) { for (int i = 0; i < statuses.size();) { Status status = statuses.get(i); if (accountId.equals(status.account.id)) { diff --git a/app/src/main/java/com/keylesspalace/tusky/TimelineFragment.java b/app/src/main/java/com/keylesspalace/tusky/TimelineFragment.java index 7102764d..223f6a08 100644 --- a/app/src/main/java/com/keylesspalace/tusky/TimelineFragment.java +++ b/app/src/main/java/com/keylesspalace/tusky/TimelineFragment.java @@ -39,7 +39,7 @@ import retrofit2.Call; import retrofit2.Callback; public class TimelineFragment extends SFragment implements - SwipeRefreshLayout.OnRefreshListener, StatusActionListener { + SwipeRefreshLayout.OnRefreshListener, StatusActionListener, StatusRemoveListener { private static final String TAG = "Timeline"; // logging tag private Call> listCall; @@ -145,7 +145,7 @@ public class TimelineFragment extends SFragment implements /* This is delayed until onActivityCreated solely because MainActivity.composeButton isn't * guaranteed to be set until then. */ - if (followButtonPresent()) { + if (composeButtonPresent()) { /* Use a modified scroll listener that both loads more statuses as it goes, and hides * the follow button on down-scroll. */ MainActivity activity = (MainActivity) getActivity(); @@ -202,7 +202,7 @@ public class TimelineFragment extends SFragment implements return kind != Kind.TAG && kind != Kind.FAVOURITES; } - private boolean followButtonPresent() { + private boolean composeButtonPresent() { return kind != Kind.TAG && kind != Kind.FAVOURITES && kind != Kind.USER; } @@ -212,8 +212,6 @@ public class TimelineFragment extends SFragment implements } private void sendFetchTimelineRequest(@Nullable final String fromId, @Nullable String uptoId) { - MastodonAPI api = ((BaseActivity) getActivity()).mastodonAPI; - if (fromId != null || adapter.getItemCount() <= 1) { adapter.setFooterState(TimelineAdapter.FooterState.LOADING); } @@ -237,27 +235,27 @@ public class TimelineFragment extends SFragment implements switch (kind) { default: case HOME: { - listCall = api.homeTimeline(fromId, uptoId, null); + listCall = mastodonAPI.homeTimeline(fromId, uptoId, null); break; } case PUBLIC_FEDERATED: { - listCall = api.publicTimeline(null, fromId, uptoId, null); + listCall = mastodonAPI.publicTimeline(null, fromId, uptoId, null); break; } case PUBLIC_LOCAL: { - listCall = api.publicTimeline(true, fromId, uptoId, null); + listCall = mastodonAPI.publicTimeline(true, fromId, uptoId, null); break; } case TAG: { - listCall = api.hashtagTimeline(hashtagOrId, null, fromId, uptoId, null); + listCall = mastodonAPI.hashtagTimeline(hashtagOrId, null, fromId, uptoId, null); break; } case USER: { - listCall = api.accountStatuses(hashtagOrId, fromId, uptoId, null); + listCall = mastodonAPI.accountStatuses(hashtagOrId, fromId, uptoId, null); break; } case FAVOURITES: { - listCall = api.favourites(fromId, uptoId, null); + listCall = mastodonAPI.favourites(fromId, uptoId, null); break; } } @@ -269,6 +267,10 @@ public class TimelineFragment extends SFragment implements sendFetchTimelineRequest(null, null); } + public void removePostsByUser(String accountId) { + adapter.removeAllByAccountId(accountId); + } + private static boolean findStatus(List statuses, String id) { for (Status status : statuses) { if (status.id.equals(id)) { diff --git a/app/src/main/java/com/keylesspalace/tusky/TimelinePagerAdapter.java b/app/src/main/java/com/keylesspalace/tusky/TimelinePagerAdapter.java index 2e81adc3..03dc88dc 100644 --- a/app/src/main/java/com/keylesspalace/tusky/TimelinePagerAdapter.java +++ b/app/src/main/java/com/keylesspalace/tusky/TimelinePagerAdapter.java @@ -20,21 +20,31 @@ import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.view.ViewGroup; +import java.util.ArrayList; +import java.util.List; + class TimelinePagerAdapter extends FragmentPagerAdapter { - private Fragment currentFragment; + private int currentFragmentIndex; + private List registeredFragments; TimelinePagerAdapter(FragmentManager manager) { super(manager); + currentFragmentIndex = 0; + registeredFragments = new ArrayList<>(); } - public Fragment getCurrentFragment() { - return currentFragment; + Fragment getCurrentFragment() { + return registeredFragments.get(currentFragmentIndex); + } + + List getRegisteredFragments() { + return registeredFragments; } @Override public void setPrimaryItem(ViewGroup container, int position, Object object) { - if (getCurrentFragment() != object) { - currentFragment = ((Fragment) object); + if (position != currentFragmentIndex) { + currentFragmentIndex = position; } super.setPrimaryItem(container, position, object); } @@ -69,4 +79,17 @@ class TimelinePagerAdapter extends FragmentPagerAdapter { public CharSequence getPageTitle(int position) { return null; } + + @Override + public Object instantiateItem(ViewGroup container, int position) { + Fragment fragment = (Fragment) super.instantiateItem(container, position); + registeredFragments.add(fragment); + return fragment; + } + + @Override + public void destroyItem(ViewGroup container, int position, Object object) { + registeredFragments.remove((Fragment) object); + super.destroyItem(container, position, object); + } }