Notifications about new streams

This commit is contained in:
Vasiliy 2019-05-08 20:17:54 +03:00 committed by Koitharu
parent be95fa6b2b
commit 51d972eeb9
40 changed files with 1090 additions and 27 deletions

View file

@ -1,6 +1,11 @@
package org.schabi.newpipe.fragments.list.channel;
import static org.schabi.newpipe.ktx.TextViewUtils.animateTextColor;
import static org.schabi.newpipe.ktx.ViewUtils.animate;
import static org.schabi.newpipe.ktx.ViewUtils.animateBackgroundColor;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
@ -19,9 +24,11 @@ import androidx.appcompat.app.ActionBar;
import androidx.core.content.ContextCompat;
import androidx.viewbinding.ViewBinding;
import com.google.android.material.snackbar.Snackbar;
import com.jakewharton.rxbinding4.view.RxView;
import org.schabi.newpipe.R;
import org.schabi.newpipe.database.subscription.NotificationMode;
import org.schabi.newpipe.database.subscription.SubscriptionEntity;
import org.schabi.newpipe.databinding.ChannelHeaderBinding;
import org.schabi.newpipe.databinding.FragmentChannelBinding;
@ -37,6 +44,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.fragments.list.BaseListInfoFragment;
import org.schabi.newpipe.ktx.AnimationType;
import org.schabi.newpipe.local.subscription.SubscriptionManager;
import org.schabi.newpipe.notifications.NotificationHelper;
import org.schabi.newpipe.player.playqueue.ChannelPlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.util.ExtractorHelper;
@ -60,10 +68,6 @@ import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.functions.Function;
import io.reactivex.rxjava3.schedulers.Schedulers;
import static org.schabi.newpipe.ktx.TextViewUtils.animateTextColor;
import static org.schabi.newpipe.ktx.ViewUtils.animate;
import static org.schabi.newpipe.ktx.ViewUtils.animateBackgroundColor;
public class ChannelFragment extends BaseListInfoFragment<ChannelInfo>
implements View.OnClickListener {
@ -84,6 +88,7 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo>
private PlaylistControlBinding playlistControlBinding;
private MenuItem menuRssButton;
private MenuItem menuNotifyButton;
public static ChannelFragment getInstance(final int serviceId, final String url,
final String name) {
@ -181,6 +186,7 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo>
+ "menu = [" + menu + "], inflater = [" + inflater + "]");
}
menuRssButton = menu.findItem(R.id.menu_item_rss);
menuNotifyButton = menu.findItem(R.id.menu_item_notify);
}
}
@ -197,6 +203,11 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo>
case R.id.action_settings:
NavigationHelper.openSettings(requireContext());
break;
case R.id.menu_item_notify:
final boolean value = !item.isChecked();
item.setEnabled(false);
setNotify(value);
break;
case R.id.menu_item_rss:
openRssFeed();
break;
@ -238,15 +249,22 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo>
.subscribe(getSubscribeUpdateMonitor(info), onError));
disposables.add(observable
// Some updates are very rapid
// (for example when calling the updateSubscription(info))
// so only update the UI for the latest emission
// ("sync" the subscribe button's state)
.debounce(100, TimeUnit.MILLISECONDS)
.map(List::isEmpty)
.distinctUntilChanged()
.observeOn(AndroidSchedulers.mainThread())
.subscribe((List<SubscriptionEntity> subscriptionEntities) ->
updateSubscribeButton(!subscriptionEntities.isEmpty()), onError));
.subscribe((Boolean isEmpty) -> updateSubscribeButton(!isEmpty), onError));
disposables.add(observable
.map(List::isEmpty)
.filter(x -> NotificationHelper.isNewStreamsNotificationsEnabled(requireContext()))
.distinctUntilChanged()
.skip(1)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(isEmpty -> {
if (!isEmpty) {
showNotifySnackbar();
}
}, onError));
}
private Function<Object, Object> mapOnSubscribe(final SubscriptionEntity subscription,
@ -326,6 +344,7 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo>
info.getAvatarUrl(),
info.getDescription(),
info.getSubscriberCount());
updateNotifyButton(null);
subscribeButtonMonitor = monitorSubscribeButton(
headerBinding.channelSubscribeButton, mapOnSubscribe(channel, info));
} else {
@ -333,6 +352,7 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo>
Log.d(TAG, "Found subscription to this channel!");
}
final SubscriptionEntity subscription = subscriptionEntities.get(0);
updateNotifyButton(subscription);
subscribeButtonMonitor = monitorSubscribeButton(
headerBinding.channelSubscribeButton, mapOnUnsubscribe(subscription));
}
@ -375,6 +395,41 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo>
AnimationType.LIGHT_SCALE_AND_ALPHA);
}
private void updateNotifyButton(@Nullable final SubscriptionEntity subscription) {
if (menuNotifyButton == null) {
return;
}
if (subscription == null) {
menuNotifyButton.setVisible(false);
} else {
menuNotifyButton.setEnabled(
NotificationHelper.isNewStreamsNotificationsEnabled(requireContext())
);
menuNotifyButton.setChecked(
subscription.getNotificationMode() != NotificationMode.DISABLED
);
menuNotifyButton.setVisible(true);
}
}
private void setNotify(final boolean isEnabled) {
final int mode = isEnabled ? NotificationMode.ENABLED_DEFAULT : NotificationMode.DISABLED;
disposables.add(
subscriptionManager.updateNotificationMode(currentInfo.getServiceId(),
currentInfo.getUrl(), mode)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe()
);
}
private void showNotifySnackbar() {
Snackbar.make(itemsList, R.string.you_successfully_subscribed, Snackbar.LENGTH_LONG)
.setAction(R.string.get_notified, v -> setNotify(true))
.setActionTextColor(Color.YELLOW)
.show();
}
/*//////////////////////////////////////////////////////////////////////////
// Load and handle
//////////////////////////////////////////////////////////////////////////*/