Skip to content

Commit

Permalink
#580, add last page notifications for watching threads (background mo…
Browse files Browse the repository at this point in the history
…de must be on)

Fixes tap action on watch notifications for slide-mode viewing
#252, add null check
  • Loading branch information
Adamantcheese committed Mar 4, 2019
1 parent 5ff522e commit e3b65cb
Show file tree
Hide file tree
Showing 10 changed files with 160 additions and 25 deletions.
4 changes: 4 additions & 0 deletions Clover/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
android:name=".ui.service.SavingNotification"
android:exported="false" />

<service
android:name=".ui.service.LastPageNotification"
android:exported="false" />

<receiver
android:name=".core.receiver.WakeUpdateReceiver"
android:exported="false">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,9 @@
*/
package org.floens.chan.core.manager;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.support.annotation.Nullable;

import org.floens.chan.Chan;
Expand All @@ -38,15 +32,17 @@
import org.floens.chan.core.model.orm.Loadable;
import org.floens.chan.core.model.orm.Pin;
import org.floens.chan.core.pool.ChanLoaderFactory;
import org.floens.chan.core.repository.PageRepository;
import org.floens.chan.core.settings.ChanSettings;
import org.floens.chan.core.site.Page;
import org.floens.chan.core.site.loader.ChanThreadLoader;
import org.floens.chan.ui.helper.PostHelper;
import org.floens.chan.ui.service.LastPageNotification;
import org.floens.chan.ui.service.WatchNotifier;
import org.floens.chan.utils.Logger;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
Expand All @@ -59,7 +55,6 @@

import de.greenrobot.event.EventBus;

import static org.floens.chan.Chan.inject;
import static org.floens.chan.utils.AndroidUtils.getAppContext;

/**
Expand Down Expand Up @@ -106,6 +101,7 @@ enum IntervalType {
private final DatabasePinManager databasePinManager;
private final ChanLoaderFactory chanLoaderFactory;
private final WakeManager wakeManager;
private final PageRepository pageRepository;

private IntervalType currentInterval = IntervalType.NONE;

Expand All @@ -114,11 +110,12 @@ enum IntervalType {
private Set<PinWatcher> waitingForPinWatchersForBackgroundUpdate;

@Inject
public WatchManager(DatabaseManager databaseManager, ChanLoaderFactory chanLoaderFactory, WakeManager wakeManager) {
public WatchManager(DatabaseManager databaseManager, ChanLoaderFactory chanLoaderFactory, WakeManager wakeManager, PageRepository pageRepository) {
//retain local references to needed managers/factories/pins
this.databaseManager = databaseManager;
this.chanLoaderFactory = chanLoaderFactory;
this.wakeManager = wakeManager;
this.pageRepository = pageRepository;

databasePinManager = databaseManager.getDatabasePinManager();
pins = databaseManager.runTask(databasePinManager.getPins());
Expand Down Expand Up @@ -557,6 +554,7 @@ public class PinWatcher implements ChanThreadLoader.ChanLoaderCallback {
private final List<Post> quotes = new ArrayList<>();
private boolean wereNewQuotes = false;
private boolean wereNewPosts = false;
private boolean notified;

public PinWatcher(Pin pin) {
this.pin = pin;
Expand Down Expand Up @@ -605,6 +603,20 @@ private void destroy() {

private boolean update(boolean fromBackground) {
if (!pin.isError && pin.watching) {
if (ChanSettings.watchEnabled.get() && ChanSettings.watchLastPageNotify.get() && ChanSettings.watchBackground.get() && chanLoader.getThread() != null) {
//check last page stuff, fake a post
Page p = pageRepository.getPage(chanLoader.getThread().op);
if (p == null) {
Logger.w(TAG, "Pages for page not loaded yet, will check for notification next time");
} else if (p.page >= pin.loadable.board.pages && !notified) {
Intent pageNotifyIntent = new Intent(getAppContext(), LastPageNotification.class);
pageNotifyIntent.putExtra("pin_id", pin.id);
getAppContext().startService(pageNotifyIntent);
notified = true;
} else if (p.page < pin.loadable.board.pages) {
notified = false;
}
}
if (fromBackground) {
// Always load regardless of timer, since the time left is not accurate for 15min+ intervals
chanLoader.clearTimer();
Expand Down
12 changes: 11 additions & 1 deletion Clover/app/src/main/java/org/floens/chan/core/model/Post.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
* Contains all data needed to represent a single post.<br>
* All {@code final} fields are thread-safe.
*/
public class Post {
public class Post implements Comparable<Post> {
public final String boardId;

public final Board board;
Expand Down Expand Up @@ -108,6 +108,16 @@ public class Post {
private long lastModified;
private String title = "";

public int compareTo(Post p) {
if (this.time < p.time) {
return 1;
} else if (this.time > p.time) {
return -1;
} else {
return 0;
}
}

private Post(Builder builder) {
board = builder.board;
boardId = builder.board.code;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ public PageRepository() {
}

public Page getPage(Post op) {
if(op == null) {
return null;
}
Pages pages = getPages(op.board);
if (pages == null) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ public String getKey() {
public static final BooleanSetting watchCountdown;
public static final BooleanSetting watchBackground;
public static final BooleanSetting watchFilterPin;
public static final BooleanSetting watchLastPageNotify;
public static final IntegerSetting watchBackgroundInterval;
public static final StringSetting watchNotifyMode;
public static final StringSetting watchSound;
Expand Down Expand Up @@ -228,6 +229,7 @@ public String getKey() {
watchFilterPin = new BooleanSetting(p, "preference_watch_filter_pin", false);
watchFilterPin.addCallback(((setting, value) ->
EventBus.getDefault().post(new SettingChanged<>(watchFilterPin))));
watchLastPageNotify = new BooleanSetting(p, "preference_watch_last_page_notify", false);
watchBackgroundInterval = new IntegerSetting(p, "preference_watch_background_interval", WakeManager.BACKGROUND_INTERVAL);
watchBackgroundInterval.addCallback((setting, value) ->
EventBus.getDefault().post(new SettingChanged<>(watchBackgroundInterval)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,34 @@ protected void onNewIntent(Intent intent) {
browseController.showThread(pin.loadable, false);
}
}
} else if (pinId != -2 && mainNavigationController.getTop() instanceof ThreadSlideController) {
if(pinId == -1) {
drawerController.onMenuClicked();
} else {
Pin pin = watchManager.findPinById(pinId);
if(pin != null) {
List<Controller> controllers = mainNavigationController.childControllers;
for (Controller controller : controllers) {
if (controller instanceof ViewThreadController) {
((ViewThreadController) controller).loadThread(pin.loadable);
break;
} else if (controller instanceof ThreadSlideController) {
ThreadSlideController slideNav = (ThreadSlideController) controller;
if (slideNav.getRightController() instanceof ViewThreadController) {
((ViewThreadController) slideNav.getRightController()).loadThread(pin.loadable);
slideNav.switchToController(false);
break;
} else {
ViewThreadController v = new ViewThreadController(this);
v.setLoadable(pin.loadable);
slideNav.setRightController(v);
slideNav.switchToController(false);
break;
}
}
}
}
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public class WatchSettingsController extends SettingsController implements Compo
private SettingView enableFilterPin;

private SettingView backgroundTimeout;
private SettingView lastPageNotifyMode;
private SettingView notifyMode;
private SettingView soundMode;
private SettingView peekMode;
Expand Down Expand Up @@ -71,6 +72,7 @@ public void onCreate() {

if (!ChanSettings.watchBackground.get()) {
setSettingViewVisibility(backgroundTimeout, false, false);
setSettingViewVisibility(lastPageNotifyMode, false, false);
setSettingViewVisibility(notifyMode, false, false);
setSettingViewVisibility(soundMode, false, false);
setSettingViewVisibility(peekMode, false, false);
Expand All @@ -92,6 +94,7 @@ public void onPreferenceChange(SettingView item) {
if (item == enableBackground) {
boolean enabled = ChanSettings.watchBackground.get();
setSettingViewVisibility(backgroundTimeout, enabled, true);
setSettingViewVisibility(lastPageNotifyMode, enabled, true);
setSettingViewVisibility(notifyMode, enabled, true);
setSettingViewVisibility(soundMode, enabled, true);
setSettingViewVisibility(peekMode, enabled, true);
Expand Down Expand Up @@ -129,6 +132,8 @@ public String getBottomDescription() {
}
});

lastPageNotifyMode = settings.add(new BooleanSettingView(this, ChanSettings.watchLastPageNotify, R.string.setting_thread_page_limit_notify, R.string.setting_thread_page_limit_notify_description));

notifyMode = settings.add(new ListSettingView<>(this, ChanSettings.watchNotifyMode, R.string.setting_watch_notify_mode,
context.getResources().getStringArray(R.array.setting_watch_notify_modes), new String[]{"all", "quotes"}));

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package org.floens.chan.ui.service;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;

import org.floens.chan.R;
import org.floens.chan.core.manager.WatchManager;
import org.floens.chan.core.model.orm.Pin;
import org.floens.chan.ui.activity.BoardActivity;

import java.util.Random;

import javax.inject.Inject;

import static org.floens.chan.Chan.inject;
import static org.floens.chan.utils.AndroidUtils.getAppContext;

public class LastPageNotification extends Service {
//random notification ID's, so one notification per thread
private Random random = new Random();

@Inject
WatchManager watchManager;

@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}

@Override
public void onCreate() {
super.onCreate();
inject(this);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null && intent.getExtras() != null) {
Bundle extras = intent.getExtras();
int pinId = extras.getInt("pin_id");

//NotificationManagerCompat.from(getAppContext()).notify(random.nextInt(), getNotification(pinId));
((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).notify(random.nextInt(), getNotification(pinId));
}
return START_STICKY;
}

private Notification getNotification(int pinId) {
Pin pin = watchManager.findPinById(pinId);

Intent intent = new Intent(this, BoardActivity.class);
intent.setAction(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_LAUNCHER)
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
.putExtra("pin_id", pinId);

PendingIntent pendingIntent = PendingIntent.getActivity(this, random.nextInt(), intent, PendingIntent.FLAG_ONE_SHOT);

NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setSmallIcon(R.drawable.ic_stat_notify_alert)
.setContentTitle(getString(R.string.thread_page_limit))
.setContentText(pin.loadable.title)
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setTimeoutAfter(10 * 1000 * 60)
.setAutoCancel(true);

return builder.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
public class WatchNotifier extends Service {
private static final String TAG = "WatchNotifier";
private static final int NOTIFICATION_ID = 1;
private static final PostAgeComparator POST_AGE_COMPARATOR = new PostAgeComparator();
private static final int SUBJECT_LENGTH = 6;
private static final String IMAGE_TEXT = "(img) ";
private static final Pattern SHORTEN_NO_PATTERN = Pattern.compile(">>\\d+(?=\\d{3})(\\d{3})");
Expand Down Expand Up @@ -186,7 +185,7 @@ private Notification notifyAboutPosts(List<Pin> pins, List<Pin> subjectPins, Lis
}
}

Collections.sort(postsForExpandedLines, POST_AGE_COMPARATOR);
Collections.sort(postsForExpandedLines);
List<CharSequence> expandedLines = new ArrayList<>();
for (Post postForExpandedLine : postsForExpandedLines) {
CharSequence prefix;
Expand Down Expand Up @@ -288,17 +287,4 @@ private Notification get(String title, String smallText, List<CharSequence> expa

return builder.build();
}

private static class PostAgeComparator implements Comparator<Post> {
@Override
public int compare(Post lhs, Post rhs) {
if (lhs.time < rhs.time) {
return 1;
} else if (lhs.time > rhs.time) {
return -1;
} else {
return 0;
}
}
}
}
4 changes: 4 additions & 0 deletions Clover/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,8 @@ Enable \"Play videos with external player\" in the settings to play videos with
<string name="image_save_as">Saved as \"%1$s\"</string>
<string name="image_save_failed">Saving image failed</string>

<string name="thread_page_limit" tools:ignore="MissingTranslation">Thread hit last page</string>

<string name="drawer_sites">Setup sites</string>
<string name="drawer_history">History</string>

Expand Down Expand Up @@ -391,6 +393,8 @@ Enable \"Play videos with external player\" in the settings to play videos with
<string name="setting_watch_enable_filter_pin_description" tools:ignore="MissingTranslation">Pin posts that match filters with pinning enabled</string>
<string name="setting_watch_background_timeout">Background update interval</string>
<string name="setting_watch_background_timeout_description">The interval between updates when placed in the background</string>
<string name="setting_thread_page_limit_notify" tools:ignore="MissingTranslation">Last page notifications</string>
<string name="setting_thread_page_limit_notify_description" tools:ignore="MissingTranslation">Notify when threads hit the last page</string>
<string name="setting_watch_notify_mode">Notify about</string>
<string-array name="setting_watch_notify_modes">
<item>All posts</item>
Expand Down

0 comments on commit e3b65cb

Please sign in to comment.