From 714bdc143aa80bcec6f0d350825f46a2accd9ccb Mon Sep 17 00:00:00 2001 From: Florens Douwes Date: Wed, 2 Apr 2014 21:00:39 +0200 Subject: [PATCH] Notifications with big views about new posts and quotes --- Chan/AndroidManifest.xml | 1 + .../chan/core/manager/PinnedManager.java | 4 +- Chan/src/org/floens/chan/core/model/Pin.java | 20 ++-- .../floens/chan/core/watch/PinWatcher.java | 104 +++++++++++++++++- .../floens/chan/core/watch/WatchNotifier.java | 95 +++++++++++----- .../org/floens/chan/service/WatchService.java | 5 + .../floens/chan/ui/activity/BaseActivity.java | 2 +- .../floens/chan/ui/adapter/PinnedAdapter.java | 2 +- 8 files changed, 187 insertions(+), 46 deletions(-) diff --git a/Chan/AndroidManifest.xml b/Chan/AndroidManifest.xml index d7dd1b0a..3a947364 100644 --- a/Chan/AndroidManifest.xml +++ b/Chan/AndroidManifest.xml @@ -21,6 +21,7 @@ android:theme="@style/AppTheme" > diff --git a/Chan/src/org/floens/chan/core/manager/PinnedManager.java b/Chan/src/org/floens/chan/core/manager/PinnedManager.java index c0bd01f8..4cc64a8f 100644 --- a/Chan/src/org/floens/chan/core/manager/PinnedManager.java +++ b/Chan/src/org/floens/chan/core/manager/PinnedManager.java @@ -119,7 +119,9 @@ public class PinnedManager { } public void onPinViewed(Pin pin) { - pin.onViewed(); + if (pin.getPinWatcher() != null) { + pin.getPinWatcher().onViewed(); + } onPinsChanged(); } diff --git a/Chan/src/org/floens/chan/core/model/Pin.java b/Chan/src/org/floens/chan/core/model/Pin.java index 985d4853..95cb5f81 100644 --- a/Chan/src/org/floens/chan/core/model/Pin.java +++ b/Chan/src/org/floens/chan/core/model/Pin.java @@ -34,6 +34,14 @@ public class Pin { @DatabaseField public int watchNewCount; + public int quoteLastCount; + + public int quoteNewCount; + + public PinWatcher getPinWatcher() { + return pinWatcher; + } + public void updateWatch() { if (pinWatcher == null) { pinWatcher = new PinWatcher(this); @@ -42,18 +50,6 @@ public class Pin { pinWatcher.update(); } - public int getNewPostCount() { - if (pinWatcher != null) { - return pinWatcher.getNewPostCount(); - } else { - return 0; - } - } - - public void onViewed() { - watchLastCount = watchNewCount; - } - public void destroyWatcher() { if (pinWatcher != null) { pinWatcher.destroy(); diff --git a/Chan/src/org/floens/chan/core/watch/PinWatcher.java b/Chan/src/org/floens/chan/core/watch/PinWatcher.java index e0ad2799..8a441aae 100644 --- a/Chan/src/org/floens/chan/core/watch/PinWatcher.java +++ b/Chan/src/org/floens/chan/core/watch/PinWatcher.java @@ -1,5 +1,6 @@ package org.floens.chan.core.watch; +import java.util.ArrayList; import java.util.List; import org.floens.chan.core.loader.Loader; @@ -18,6 +19,14 @@ public class PinWatcher implements Loader.LoaderListener { private Loader loader; private boolean isError = false; + private final List posts = new ArrayList(); + + private boolean wereNewPosts = false; + private boolean wereNewQuotes = false; + + private int postLastLoad; + private int quoteLastLoad; + public PinWatcher(Pin pin) { this.pin = pin; @@ -37,7 +46,20 @@ public class PinWatcher implements Loader.LoaderListener { } } - public int getNewPostCount() { + public void onViewed() { + pin.watchLastCount = pin.watchNewCount; + pin.quoteLastCount = pin.quoteNewCount; + } + + public List getNewPosts() { + if (posts.size() == 0) { + return posts; + } else { + return posts.subList(Math.max(0, posts.size() - getNewPostsCount()), posts.size()); + } + } + + public int getNewPostsCount() { if (pin.watchLastCount <= 0) { return 0; } else { @@ -45,6 +67,40 @@ public class PinWatcher implements Loader.LoaderListener { } } + public boolean getWereNewPosts() { + if (wereNewPosts) { + wereNewPosts = false; + return true; + } else { + return false; + } + } + + public List getNewQuotes() { + if (posts.size() == 0) { + return posts; + } else { + return posts.subList(Math.max(0, posts.size() - getNewQuoteCount()), posts.size()); + } + } + + public int getNewQuoteCount() { + if (pin.quoteLastCount <= 0) { + return 0; + } else { + return Math.max(0, pin.quoteNewCount - pin.quoteLastCount); + } + } + + public boolean getWereNewQuotes() { + if (wereNewQuotes) { + wereNewQuotes = false; + return true; + } else { + return false; + } + } + public boolean isError() { return isError; } @@ -63,15 +119,51 @@ public class PinWatcher implements Loader.LoaderListener { public void onData(List result, boolean append) { isError = false; - int count = result.size(); - - Logger.test("PinWatcher onData, Post size: " + count); + posts.clear(); + posts.addAll(result); - if (pin.watchLastCount <= 0) { + if (pin.watchLastCount <= 0) pin.watchLastCount = pin.watchNewCount; + + if (pin.quoteLastCount <= 0) + pin.quoteLastCount = pin.quoteNewCount; + + pin.watchNewCount = result.size(); + + if (postLastLoad == 0) + postLastLoad = pin.watchNewCount; + + if (pin.watchNewCount > postLastLoad) { + wereNewPosts = true; + postLastLoad = pin.watchNewCount; + } + + // Get list of saved posts + List savedPosts = new ArrayList(); + for (Post saved : result) { + if (saved.isSavedReply) { + savedPosts.add(saved); + } } - pin.watchNewCount = count; + // Find posts quoting these saved posts + pin.quoteNewCount = 0; + for (Post resultPost : result) { + // This post replies to me + for (Post savedPost : savedPosts) { + if (resultPost.repliesTo.contains(savedPost.no)) { + pin.quoteNewCount++; + } + } + } + + if (quoteLastLoad == 0) + quoteLastLoad = pin.quoteNewCount; + + if (pin.quoteNewCount > quoteLastLoad) { + wereNewQuotes = true; + quoteLastLoad = pin.quoteNewCount; + } WatchService.onPinWatcherResult(); } diff --git a/Chan/src/org/floens/chan/core/watch/WatchNotifier.java b/Chan/src/org/floens/chan/core/watch/WatchNotifier.java index 378f91bc..d9b50972 100644 --- a/Chan/src/org/floens/chan/core/watch/WatchNotifier.java +++ b/Chan/src/org/floens/chan/core/watch/WatchNotifier.java @@ -6,14 +6,17 @@ import java.util.List; import org.floens.chan.ChanApplication; import org.floens.chan.R; import org.floens.chan.core.model.Pin; +import org.floens.chan.core.model.Post; import org.floens.chan.service.WatchService; import org.floens.chan.ui.activity.BoardActivity; +import org.floens.chan.utils.Logger; -import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; +import android.media.RingtoneManager; +import android.support.v4.app.NotificationCompat; public class WatchNotifier { private final int NOTIFICATION_ID = 1; @@ -21,8 +24,6 @@ public class WatchNotifier { private final WatchService pinnedService; private final NotificationManager nm; - private int lastNewPosts; - public WatchNotifier(WatchService pinnedService) { this.pinnedService = pinnedService; nm = (NotificationManager) pinnedService.getSystemService(Context.NOTIFICATION_SERVICE); @@ -47,48 +48,78 @@ public class WatchNotifier { } private void prepareNotification() { - List pins = ChanApplication.getPinnedManager().getWatchingPins(); + List watchingPins = ChanApplication.getPinnedManager().getWatchingPins(); + + List pins = new ArrayList(); + int newPostsCount = 0; + int newQuotesCount = 0; + List newPosts = new ArrayList(); + boolean makeSound = false; + boolean show = false; - int newPosts = 0; - List pinsWithNewPosts = new ArrayList(); + for (Pin pin : watchingPins) { + PinWatcher watcher = pin.getPinWatcher(); + if (watcher == null) + continue; - for (Pin pin : pins) { - if (pin.getNewPostCount() > 0) { - newPosts += pin.getNewPostCount(); - pinsWithNewPosts.add(pin); + boolean add = false; + + if (watcher.getWereNewPosts()) { + newPostsCount += watcher.getNewPostsCount(); + newPosts.addAll(watcher.getNewPosts()); + show = true; + add = true; } - } - boolean show = false; + if (watcher.getWereNewQuotes()) { + newQuotesCount += watcher.getNewQuoteCount(); + show = true; + makeSound = true; + add = true; + } - if (lastNewPosts != newPosts && newPosts > 0) { - show = true; + if (add) { + pins.add(pin); + } } - lastNewPosts = newPosts; if (show) { + // "33 new posts, 3 quoting you" + String title = newPostsCount + " new posts"; + if (newQuotesCount > 0) { + title += ", " + newQuotesCount + " quoting you"; + } + + // "234 new posts in DPT" + // "234 new posts in 5 threads" String descriptor; - if (pinsWithNewPosts.size() == 1) { - descriptor = pinsWithNewPosts.get(0).loadable.title; + if (pins.size() == 1) { + descriptor = pins.get(0).loadable.title; } else { - descriptor = pinsWithNewPosts.size() + " threads"; + descriptor = pins.size() + " threads"; } - String content = newPosts + " new posts in " + descriptor; - String title = "New posts"; + String content = newPostsCount + " new posts in " + descriptor; + + List lines = new ArrayList(); + for (int i = newPosts.size() - 1; i >= 0; i--) { + lines.add(newPosts.get(i).comment); + } - showNotification(content, title, content, Integer.toString(newPosts)); + showNotification(content, title, content, Integer.toString(newPostsCount), lines, makeSound); } } @SuppressWarnings("deprecation") - private void showNotification(String tickerText, String title, String content, String contentInfo) { + private void showNotification(String tickerText, String title, String content, String contentInfo, + List lines, boolean makeSound) { Intent intent = new Intent(pinnedService, BoardActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP - | Intent.FLAG_ACTIVITY_NEW_TASK); + // intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | + // Intent.FLAG_ACTIVITY_SINGLE_TOP + // | Intent.FLAG_ACTIVITY_NEW_TASK); PendingIntent pending = PendingIntent.getActivity(pinnedService, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); - Notification.Builder builder = new Notification.Builder(pinnedService); + NotificationCompat.Builder builder = new NotificationCompat.Builder(pinnedService); builder.setContentIntent(pending); builder.setTicker(tickerText); @@ -97,6 +128,20 @@ public class WatchNotifier { builder.setContentInfo(contentInfo); builder.setSmallIcon(R.drawable.ic_stat_notify); + if (makeSound) { + builder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)); + } + + NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle(); + for (CharSequence line : lines.subList(Math.max(0, lines.size() - 10), lines.size())) { + style.addLine(line); + } + style.setBigContentTitle(title); + style.setSummaryText(content); + + builder.setStyle(style); + + Logger.test("SHOWING NOTIFICATION!"); nm.notify(NOTIFICATION_ID, builder.getNotification()); } } diff --git a/Chan/src/org/floens/chan/service/WatchService.java b/Chan/src/org/floens/chan/service/WatchService.java index 31d3ba9a..d9e148f0 100644 --- a/Chan/src/org/floens/chan/service/WatchService.java +++ b/Chan/src/org/floens/chan/service/WatchService.java @@ -128,6 +128,11 @@ public class WatchService extends Service { Logger.i(TAG, "WatchService destroyed"); } + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + return START_STICKY; + } + private void startThread() { running = true; diff --git a/Chan/src/org/floens/chan/ui/activity/BaseActivity.java b/Chan/src/org/floens/chan/ui/activity/BaseActivity.java index 0383551c..c5d22d3f 100644 --- a/Chan/src/org/floens/chan/ui/activity/BaseActivity.java +++ b/Chan/src/org/floens/chan/ui/activity/BaseActivity.java @@ -87,7 +87,7 @@ public abstract class BaseActivity extends Activity implements PanelSlideListene protected void onNewIntent(Intent intent) { super.onNewIntent(intent); - pinDrawer.openDrawer(pinDrawerView); +// pinDrawer.openDrawer(pinDrawerView); } private void initPane() { diff --git a/Chan/src/org/floens/chan/ui/adapter/PinnedAdapter.java b/Chan/src/org/floens/chan/ui/adapter/PinnedAdapter.java index a1579f00..f6bf2417 100644 --- a/Chan/src/org/floens/chan/ui/adapter/PinnedAdapter.java +++ b/Chan/src/org/floens/chan/ui/adapter/PinnedAdapter.java @@ -53,7 +53,7 @@ public class PinnedAdapter extends ArrayAdapter { if (item.isError()) { itemCount.setText("404"); } else { - int count = item.getNewPostCount(); + int count = item.getPinWatcher() == null ? 0 : item.getPinWatcher().getNewPostsCount(); String total = Integer.toString(count); if (count > 999) { total = "1k+";