Add setting to show/hide notification filter bar (#1314)

* Add setting to show/hide notification filter bar tuskyapp/Tusky#1306

* Remove not required requestLayout

* Fix notifications reload issue
This commit is contained in:
pandasoft0 2019-06-11 17:41:15 +03:00 committed by Konrad Pozniak
parent a6819ce28e
commit ce501f24e6
3 changed files with 88 additions and 40 deletions

View File

@ -32,6 +32,23 @@ import android.widget.ListView;
import android.widget.PopupWindow; import android.widget.PopupWindow;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.arch.core.util.Function;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.core.util.Pair;
import androidx.lifecycle.Lifecycle;
import androidx.recyclerview.widget.AsyncDifferConfig;
import androidx.recyclerview.widget.AsyncListDiffer;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.ListUpdateCallback;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SimpleItemAnimator;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.keylesspalace.tusky.R; import com.keylesspalace.tusky.R;
@ -75,21 +92,6 @@ import java.util.concurrent.TimeUnit;
import javax.inject.Inject; import javax.inject.Inject;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.arch.core.util.Function;
import androidx.core.util.Pair;
import androidx.lifecycle.Lifecycle;
import androidx.recyclerview.widget.AsyncDifferConfig;
import androidx.recyclerview.widget.AsyncListDiffer;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.ListUpdateCallback;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SimpleItemAnimator;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import at.connyduck.sparkbutton.helpers.Utils; import at.connyduck.sparkbutton.helpers.Utils;
import io.reactivex.Observable; import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
@ -160,6 +162,7 @@ public class NotificationsFragment extends SFragment implements
private boolean bottomLoading; private boolean bottomLoading;
private String bottomId; private String bottomId;
private boolean alwaysShowSensitiveMedia; private boolean alwaysShowSensitiveMedia;
private boolean showNotificationsFilter;
// Each element is either a Notification for loading data or a Placeholder // Each element is either a Notification for loading data or a Placeholder
private final PairedList<Either<Placeholder, Notification>, NotificationViewData> notifications private final PairedList<Either<Placeholder, Notification>, NotificationViewData> notifications
@ -192,6 +195,14 @@ public class NotificationsFragment extends SFragment implements
View rootView = inflater.inflate(R.layout.fragment_timeline_notifications, container, false); View rootView = inflater.inflate(R.layout.fragment_timeline_notifications, container, false);
@NonNull Context context = inflater.getContext(); // from inflater to silence warning @NonNull Context context = inflater.getContext(); // from inflater to silence warning
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
boolean showNotificationsFilterSetting = preferences.getBoolean("showNotificationsFilter", true);
//Clear notifications on filter visibility change to force refresh
if (showNotificationsFilterSetting != showNotificationsFilter)
notifications.clear();
showNotificationsFilter = showNotificationsFilterSetting;
// Setup the SwipeRefreshLayout. // Setup the SwipeRefreshLayout.
swipeRefreshLayout = rootView.findViewById(R.id.swipeRefreshLayout); swipeRefreshLayout = rootView.findViewById(R.id.swipeRefreshLayout);
recyclerView = rootView.findViewById(R.id.recyclerView); recyclerView = rootView.findViewById(R.id.recyclerView);
@ -224,7 +235,6 @@ public class NotificationsFragment extends SFragment implements
adapter = new NotificationsAdapter(accountManager.getActiveAccount().getAccountId(), adapter = new NotificationsAdapter(accountManager.getActiveAccount().getAccountId(),
dataSource, this, this); dataSource, this, this);
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
alwaysShowSensitiveMedia = accountManager.getActiveAccount().getAlwaysShowSensitiveMedia(); alwaysShowSensitiveMedia = accountManager.getActiveAccount().getAlwaysShowSensitiveMedia();
boolean mediaPreviewEnabled = accountManager.getActiveAccount().getMediaPreviewEnabled(); boolean mediaPreviewEnabled = accountManager.getActiveAccount().getMediaPreviewEnabled();
adapter.setMediaPreviewEnabled(mediaPreviewEnabled); adapter.setMediaPreviewEnabled(mediaPreviewEnabled);
@ -255,10 +265,28 @@ public class NotificationsFragment extends SFragment implements
((SimpleItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false); ((SimpleItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
updateFilterVisibility();
return rootView; return rootView;
} }
private void confirmClearNotifications(){ private void updateFilterVisibility() {
CoordinatorLayout.LayoutParams params =
(CoordinatorLayout.LayoutParams) swipeRefreshLayout.getLayoutParams();
if (showNotificationsFilter) {
appBarOptions.setExpanded(true, false);
appBarOptions.setVisibility(View.VISIBLE);
//Set content behaviour to hide filter on scroll
params.setBehavior(new AppBarLayout.ScrollingViewBehavior());
} else {
appBarOptions.setExpanded(false, false);
appBarOptions.setVisibility(View.GONE);
//Clear behaviour to hide app bar
params.setBehavior(null);
}
}
private void confirmClearNotifications() {
new AlertDialog.Builder(getContext()) new AlertDialog.Builder(getContext())
.setMessage(R.string.notification_clear_text) .setMessage(R.string.notification_clear_text)
.setPositiveButton(android.R.string.yes, (DialogInterface dia, int which) -> clearNotifications()) .setPositiveButton(android.R.string.yes, (DialogInterface dia, int which) -> clearNotifications())
@ -583,18 +611,7 @@ public class NotificationsFragment extends SFragment implements
private void clearNotifications() { private void clearNotifications() {
//Cancel all ongoing requests //Cancel all ongoing requests
swipeRefreshLayout.setRefreshing(false); swipeRefreshLayout.setRefreshing(false);
for (Call callItem : callList) { resetNotificationsLoad();
callItem.cancel();
}
callList.clear();
bottomLoading = false;
topLoading = false;
//Disable load more
bottomId = null;
//Clear exists notifications
notifications.clear();
//Show friend elephant //Show friend elephant
this.statusView.setVisibility(View.VISIBLE); this.statusView.setVisibility(View.VISIBLE);
@ -625,6 +642,21 @@ public class NotificationsFragment extends SFragment implements
callList.add(call); callList.add(call);
} }
private void resetNotificationsLoad() {
for (Call callItem : callList) {
callItem.cancel();
}
callList.clear();
bottomLoading = false;
topLoading = false;
//Disable load more
bottomId = null;
//Clear exists notifications
notifications.clear();
}
private void showFilterMenu() { private void showFilterMenu() {
List<Notification.Type> notificationsList = Notification.Type.Companion.getAsList(); List<Notification.Type> notificationsList = Notification.Type.Companion.getAsList();
@ -751,6 +783,13 @@ public class NotificationsFragment extends SFragment implements
fullyRefresh(); fullyRefresh();
} }
} }
case "showNotificationsFilter": {
if (isAdded()) {
showNotificationsFilter = PreferenceManager.getDefaultSharedPreferences(getContext()).getBoolean("showNotificationsFilter", true);
updateFilterVisibility();
fullyRefreshWithProgressBar(true);
}
}
} }
} }
@ -805,7 +844,7 @@ public class NotificationsFragment extends SFragment implements
private void jumpToTop() { private void jumpToTop() {
if (isAdded()) { if (isAdded()) {
appBarOptions.setExpanded(true,false); appBarOptions.setExpanded(true, false);
layoutManager.scrollToPosition(0); layoutManager.scrollToPosition(0);
scrollListener.reset(); scrollListener.reset();
} }
@ -828,7 +867,7 @@ public class NotificationsFragment extends SFragment implements
bottomLoading = true; bottomLoading = true;
} }
Call<List<Notification>> call = mastodonApi.notifications(fromId, uptoId, LOAD_AT_ONCE, notificationFilter); Call<List<Notification>> call = mastodonApi.notifications(fromId, uptoId, LOAD_AT_ONCE, showNotificationsFilter ? notificationFilter : null);
call.enqueue(new Callback<List<Notification>>() { call.enqueue(new Callback<List<Notification>>() {
@Override @Override
@ -844,6 +883,7 @@ public class NotificationsFragment extends SFragment implements
@Override @Override
public void onFailure(@NonNull Call<List<Notification>> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<List<Notification>> call, @NonNull Throwable t) {
if (!call.isCanceled())
onFetchNotificationsFailure((Exception) t, fetchEnd, pos); onFetchNotificationsFailure((Exception) t, fetchEnd, pos);
} }
}); });
@ -853,9 +893,15 @@ public class NotificationsFragment extends SFragment implements
private void onFetchNotificationsSuccess(List<Notification> notifications, String linkHeader, private void onFetchNotificationsSuccess(List<Notification> notifications, String linkHeader,
FetchEnd fetchEnd, int pos) { FetchEnd fetchEnd, int pos) {
List<HttpHeaderLink> links = HttpHeaderLink.parse(linkHeader); List<HttpHeaderLink> links = HttpHeaderLink.parse(linkHeader);
HttpHeaderLink next = HttpHeaderLink.findByRelationType(links, "next");
String fromId = null;
if (next != null) {
fromId = next.uri.getQueryParameter("max_id");
}
switch (fetchEnd) { switch (fetchEnd) {
case TOP: { case TOP: {
update(notifications, null); update(notifications, this.notifications.isEmpty() ? fromId : null);
break; break;
} }
case MIDDLE: { case MIDDLE: {
@ -863,11 +909,6 @@ public class NotificationsFragment extends SFragment implements
break; break;
} }
case BOTTOM: { case BOTTOM: {
HttpHeaderLink next = HttpHeaderLink.findByRelationType(links, "next");
String fromId = null;
if (next != null) {
fromId = next.uri.getQueryParameter("max_id");
}
if (!this.notifications.isEmpty() if (!this.notifications.isEmpty()
&& !this.notifications.get(this.notifications.size() - 1).isRight()) { && !this.notifications.get(this.notifications.size() - 1).isRight()) {
@ -1026,8 +1067,8 @@ public class NotificationsFragment extends SFragment implements
} }
private void fullyRefreshWithProgressBar(boolean isShow) { private void fullyRefreshWithProgressBar(boolean isShow) {
notifications.clear(); resetNotificationsLoad();
if (isShow && notifications.isEmpty()) { if (isShow) {
progressBar.setVisibility(View.VISIBLE); progressBar.setVisibility(View.VISIBLE);
statusView.setVisibility(View.GONE); statusView.setVisibility(View.GONE);
} }

View File

@ -513,4 +513,5 @@
<string name="report_description_1">The report will be sent to your server moderator. You can provide an explanation of why you are reporting this account below:</string> <string name="report_description_1">The report will be sent to your server moderator. You can provide an explanation of why you are reporting this account below:</string>
<string name="report_description_remote_instance">The account is from another server. Send an anonymized copy of the report there as well?</string> <string name="report_description_remote_instance">The account is from another server. Send an anonymized copy of the report there as well?</string>
<string name="pref_title_show_notifications_filter">Show Notifications filter</string>
</resources> </resources>

View File

@ -55,6 +55,12 @@
android:defaultValue="false" android:defaultValue="false"
android:key="animateGifAvatars" android:key="animateGifAvatars"
android:title="@string/pref_title_animate_gif_avatars" /> android:title="@string/pref_title_animate_gif_avatars" />
<SwitchPreferenceCompat
android:defaultValue="true"
android:key="showNotificationsFilter"
android:title="@string/pref_title_show_notifications_filter" />
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory android:title="@string/pref_title_browser_settings"> <PreferenceCategory android:title="@string/pref_title_browser_settings">