Pin watching now works in the background.

captchafix
Florens Douwes 11 years ago
parent f756a6e692
commit 39d974f91c
  1. 2
      Chan/res/values/strings.xml
  2. 4
      Chan/src/org/floens/chan/ChanApplication.java
  3. 3
      Chan/src/org/floens/chan/activity/BaseActivity.java
  4. 8
      Chan/src/org/floens/chan/activity/BoardActivity.java
  5. 18
      Chan/src/org/floens/chan/adapter/PinnedAdapter.java
  6. 6
      Chan/src/org/floens/chan/adapter/PostAdapter.java
  7. 22
      Chan/src/org/floens/chan/loader/Loader.java
  8. 3
      Chan/src/org/floens/chan/manager/PinnedManager.java
  9. 12
      Chan/src/org/floens/chan/manager/ThreadManager.java
  10. 22
      Chan/src/org/floens/chan/model/Pin.java
  11. 67
      Chan/src/org/floens/chan/service/PinnedService.java
  12. 36
      Chan/src/org/floens/chan/watch/PinWatcher.java
  13. 33
      Chan/src/org/floens/chan/watch/WatchNotifier.java

@ -46,7 +46,7 @@
<string name="drawer_open">Open drawer</string> <string name="drawer_open">Open drawer</string>
<string name="drawer_close">Close drawer</string> <string name="drawer_close">Close drawer</string>
<string name="drawer_pinned">Pinned threads</string> <string name="drawer_pinned">Pinned threads</string>
<string name="drawer_pinned_change_title">Enter title</string> <string name="drawer_pinned_change_title">Edit title</string>
<string name="one_reply">reply</string> <string name="one_reply">reply</string>
<string name="multiple_replies">replies</string> <string name="multiple_replies">replies</string>

@ -4,9 +4,11 @@ import org.floens.chan.database.DatabaseManager;
import org.floens.chan.manager.BoardManager; import org.floens.chan.manager.BoardManager;
import org.floens.chan.manager.PinnedManager; import org.floens.chan.manager.PinnedManager;
import org.floens.chan.manager.ReplyManager; import org.floens.chan.manager.ReplyManager;
import org.floens.chan.service.PinnedService;
import org.floens.chan.utils.IconCache; import org.floens.chan.utils.IconCache;
import android.app.Application; import android.app.Application;
import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.StrictMode; import android.os.StrictMode;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
@ -70,7 +72,7 @@ public class ChanApplication extends Application {
new PinnedManager(this); new PinnedManager(this);
new ReplyManager(this); new ReplyManager(this);
// startService(new Intent(this, PinnedService.class)); startService(new Intent(this, PinnedService.class));
} }
} }

@ -7,6 +7,7 @@ import org.floens.chan.animation.SwipeDismissListViewTouchListener.DismissCallba
import org.floens.chan.manager.PinnedManager; import org.floens.chan.manager.PinnedManager;
import org.floens.chan.model.Pin; import org.floens.chan.model.Pin;
import org.floens.chan.model.Post; import org.floens.chan.model.Post;
import org.floens.chan.utils.Logger;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
@ -147,6 +148,8 @@ public abstract class BaseActivity extends Activity implements PanelSlideListene
@Override @Override
public void onPinsChanged() { public void onPinsChanged() {
pinnedAdapter.reload(); pinnedAdapter.reload();
pinDrawerView.invalidate();
Logger.test("onPinsChanged");
} }
public void addPin(Pin pin) { public void addPin(Pin pin) {

@ -171,6 +171,12 @@ public class BoardActivity extends BaseActivity implements ActionBar.OnNavigatio
} }
} }
@Override
public void updatePin(Pin pin) {
super.updatePin(pin);
updateActionBarState();
}
private void updateActionBarState() { private void updateActionBarState() {
final ActionBar actionBar = getActionBar(); final ActionBar actionBar = getActionBar();
@ -297,7 +303,7 @@ public class BoardActivity extends BaseActivity implements ActionBar.OnNavigatio
private void startLoadingBoard(Loadable loadable) { private void startLoadingBoard(Loadable loadable) {
if (loadable.mode == Loadable.Mode.INVALID) return; if (loadable.mode == Loadable.Mode.INVALID) return;
this.boardLoadable = loadable; boardLoadable = loadable;
boardFragment.bindLoadable(loadable); boardFragment.bindLoadable(loadable);
boardFragment.requestData(); boardFragment.requestData();

@ -19,7 +19,6 @@ import android.widget.TextView;
public class PinnedAdapter extends ArrayAdapter<Pin> { public class PinnedAdapter extends ArrayAdapter<Pin> {
private final HashMap<Pin, Integer> idMap; private final HashMap<Pin, Integer> idMap;
private int idCounter; private int idCounter;
private View.OnTouchListener listener;
public PinnedAdapter(Context context, int resId) { public PinnedAdapter(Context context, int resId) {
super(context, resId, new ArrayList<Pin>()); super(context, resId, new ArrayList<Pin>());
@ -27,10 +26,6 @@ public class PinnedAdapter extends ArrayAdapter<Pin> {
idMap = new HashMap<Pin, Integer>(); idMap = new HashMap<Pin, Integer>();
} }
public void setTouchListener(View.OnTouchListener listener) {
this.listener = listener;
}
@Override @Override
public View getView(int position, View convertView, ViewGroup parent) { public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@ -48,8 +43,11 @@ public class PinnedAdapter extends ArrayAdapter<Pin> {
((TextView) view.findViewById(R.id.drawer_item_text)).setText(item.loadable.title); ((TextView) view.findViewById(R.id.drawer_item_text)).setText(item.loadable.title);
int count = Math.max(0, item.watchNewCount - item.watchLastCount); int count = item.getNewPostCount();
String total = Integer.toString(Math.min(count, 999)); String total = Integer.toString(count);
if (count > 999) {
total = "1k+";
}
((TextView) view.findViewById(R.id.drawer_item_count)).setText(total); ((TextView) view.findViewById(R.id.drawer_item_count)).setText(total);
@ -61,10 +59,6 @@ public class PinnedAdapter extends ArrayAdapter<Pin> {
// } // }
} }
if (listener != null) {
view.setOnTouchListener(listener);
}
return view; return view;
} }
@ -76,6 +70,8 @@ public class PinnedAdapter extends ArrayAdapter<Pin> {
add(header); add(header);
addAll(PinnedManager.getInstance().getPins()); addAll(PinnedManager.getInstance().getPins());
notifyDataSetChanged();
} }
@Override @Override

@ -28,6 +28,7 @@ public class PostAdapter extends BaseAdapter {
private boolean endOfLine; private boolean endOfLine;
private int count = 0; private int count = 0;
private final List<Post> postList = new ArrayList<Post>(); private final List<Post> postList = new ArrayList<Post>();
private long lastViewedTime = 0;
public PostAdapter(Context activity, ThreadManager threadManager, ListView listView) { public PostAdapter(Context activity, ThreadManager threadManager, ListView listView) {
context = activity; context = activity;
@ -62,6 +63,11 @@ public class PostAdapter extends BaseAdapter {
} }
if (position >= count) { if (position >= count) {
if (System.currentTimeMillis() - lastViewedTime > 10000L) {
lastViewedTime = System.currentTimeMillis();
threadManager.bottomPostViewed();
}
return createThreadEndView(); return createThreadEndView();
} else { } else {
PostView postView = null; PostView postView = null;

@ -9,6 +9,7 @@ import org.floens.chan.model.Post;
import org.floens.chan.utils.Logger; import org.floens.chan.utils.Logger;
import android.os.Handler; import android.os.Handler;
import android.os.Looper;
import android.util.SparseArray; import android.util.SparseArray;
import com.android.volley.Response; import com.android.volley.Response;
@ -17,9 +18,9 @@ import com.android.volley.VolleyError;
public class Loader { public class Loader {
private static final String TAG = "Loader"; private static final String TAG = "Loader";
private static final Handler handler = new Handler(); private static final Handler handler = new Handler(Looper.getMainLooper());
private static final int[] watchTimeouts = {10, 15, 20, 30, 60, 90, 120, 180, 240, 300}; private static final int[] watchTimeouts = {5, 10, 15, 20, 30, 60, 90, 120, 180, 240, 300};
private final List<LoaderListener> listeners = new ArrayList<LoaderListener>(); private final List<LoaderListener> listeners = new ArrayList<LoaderListener>();
private final Loadable loadable; private final Loadable loadable;
@ -72,6 +73,8 @@ public class Loader {
loadable.listViewTop = 0; loadable.listViewTop = 0;
} }
currentTimeout = 0;
request = getData(loadable); request = getData(loadable);
} }
@ -126,8 +129,12 @@ public class Loader {
} }
public long getTimeUntilReload() { public long getTimeUntilReload() {
long waitTime = watchTimeouts[currentTimeout] * 1000L; if (request != null) {
return lastLoadTime + waitTime - System.currentTimeMillis(); return 0L;
} else {
long waitTime = watchTimeouts[currentTimeout] * 1000L;
return lastLoadTime + waitTime - System.currentTimeMillis();
}
} }
private void setTimer(int postCount) { private void setTimer(int postCount) {
@ -143,14 +150,14 @@ public class Loader {
}; };
}; };
lastPostCount = postCount;
if (postCount > lastPostCount) { if (postCount > lastPostCount) {
currentTimeout = 0; currentTimeout = 0;
} else { } else {
currentTimeout = Math.min(watchTimeouts.length - 1, currentTimeout + 1); currentTimeout = Math.min(watchTimeouts.length - 1, currentTimeout + 1);
} }
lastPostCount = postCount;
handler.postDelayed(pendingRunnable, watchTimeouts[currentTimeout] * 1000L); handler.postDelayed(pendingRunnable, watchTimeouts[currentTimeout] * 1000L);
} }
} }
@ -159,7 +166,6 @@ public class Loader {
if (pendingRunnable != null) { if (pendingRunnable != null) {
handler.removeCallbacks(pendingRunnable); handler.removeCallbacks(pendingRunnable);
pendingRunnable = null; pendingRunnable = null;
lastLoadTime = 0;
} }
} }
@ -194,6 +200,8 @@ public class Loader {
private void onData(List<Post> result) { private void onData(List<Post> result) {
if (destroyed) return; if (destroyed) return;
Logger.test("ondata in loader");
postsById.clear(); postsById.clear();
for (Post post : result) { for (Post post : result) {
postsById.append(post.no, post); postsById.append(post.no, post);

@ -79,6 +79,7 @@ public class PinnedManager {
public void remove(Pin pin) { public void remove(Pin pin) {
pins.remove(pin); pins.remove(pin);
DatabaseManager.getInstance().removePin(pin); DatabaseManager.getInstance().removePin(pin);
pin.destroy();
onPinsChanged(); onPinsChanged();
} }
@ -108,7 +109,7 @@ public class PinnedManager {
} }
public void onPinViewed(Pin pin) { public void onPinViewed(Pin pin) {
pin.watchLastCount = pin.watchNewCount; pin.onViewed();
onPinsChanged(); onPinsChanged();
} }

@ -13,6 +13,7 @@ import org.floens.chan.loader.LoaderPool;
import org.floens.chan.manager.ReplyManager.DeleteListener; import org.floens.chan.manager.ReplyManager.DeleteListener;
import org.floens.chan.manager.ReplyManager.DeleteResponse; import org.floens.chan.manager.ReplyManager.DeleteResponse;
import org.floens.chan.model.Loadable; import org.floens.chan.model.Loadable;
import org.floens.chan.model.Pin;
import org.floens.chan.model.Post; import org.floens.chan.model.Post;
import org.floens.chan.model.PostLinkable; import org.floens.chan.model.PostLinkable;
import org.floens.chan.model.SavedReply; import org.floens.chan.model.SavedReply;
@ -93,6 +94,15 @@ public class ThreadManager implements Loader.LoaderListener {
highlightedPost = null; highlightedPost = null;
} }
public void bottomPostViewed() {
if (loader != null && loader.getLoadable().isThreadMode()) {
Pin pin = PinnedManager.getInstance().findPinByLoadable(loader.getLoadable());
if (pin != null) {
PinnedManager.getInstance().onPinViewed(pin);
}
}
}
public void requestData() { public void requestData() {
if (loader != null) { if (loader != null) {
loader.requestData(); loader.requestData();
@ -398,7 +408,7 @@ public class ThreadManager implements Loader.LoaderListener {
FragmentTransaction ft = activity.getFragmentManager().beginTransaction(); FragmentTransaction ft = activity.getFragmentManager().beginTransaction();
ft.add(popup, "postPopup"); ft.add(popup, "postPopup");
ft.commit(); ft.commitAllowingStateLoss();
currentPopupFragment = popup; currentPopupFragment = popup;
} }

@ -33,10 +33,28 @@ public class Pin {
public void updateWatch() { public void updateWatch() {
if (pinWatcher == null) { if (pinWatcher == null) {
// pinWatcher = new PinWatcher(this); pinWatcher = new PinWatcher(this);
} }
// pinWatcher.update(); pinWatcher.update();
}
public int getNewPostCount() {
if (pinWatcher != null) {
return pinWatcher.getNewPostCount();
} else {
return 0;
}
}
public void onViewed() {
watchLastCount = watchNewCount;
}
public void destroy() {
if (pinWatcher != null) {
pinWatcher.destroy();
}
} }
} }

@ -2,13 +2,11 @@ package org.floens.chan.service;
import java.util.List; import java.util.List;
import org.floens.chan.R;
import org.floens.chan.manager.PinnedManager; import org.floens.chan.manager.PinnedManager;
import org.floens.chan.model.Pin; import org.floens.chan.model.Pin;
import org.floens.chan.utils.Logger; import org.floens.chan.utils.Logger;
import org.floens.chan.watch.WatchNotifier;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service; import android.app.Service;
import android.content.Intent; import android.content.Intent;
import android.os.Handler; import android.os.Handler;
@ -23,6 +21,7 @@ public class PinnedService extends Service {
private Thread loadThread; private Thread loadThread;
private boolean running = true; private boolean running = true;
private final WatchNotifier watchNotifier;
public static void onActivityStart() { public static void onActivityStart() {
Logger.test("onActivityStart"); Logger.test("onActivityStart");
@ -34,6 +33,10 @@ public class PinnedService extends Service {
activityInForeground = false; activityInForeground = false;
} }
public PinnedService() {
watchNotifier = new WatchNotifier(this);
}
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
@ -49,37 +52,39 @@ public class PinnedService extends Service {
} }
private void start() { private void start() {
loadThread = new Thread(new Runnable() { running = true;
@Override
public void run() { if (loadThread == null) {
try { loadThread = new Thread(new Runnable() {
Thread.sleep(2000); @Override
} catch (InterruptedException e1) { public void run() {
e1.printStackTrace(); while (running) {
} update();
while (running) { long timeout = activityInForeground ? FOREGROUND_INTERVAL : BACKGROUND_INTERVAL;
doUpdates();
try {
long timeout = activityInForeground ? FOREGROUND_INTERVAL : BACKGROUND_INTERVAL; Thread.sleep(timeout);
} catch (InterruptedException e) {
try { e.printStackTrace();
Thread.sleep(timeout); }
} catch (InterruptedException e) {
e.printStackTrace();
} }
loadThread = null;
} }
} });
});
loadThread.start(); loadThread.start();
}
} }
private void doUpdates() { private void update() {
List<Pin> pins = PinnedManager.getInstance().getPins(); List<Pin> pins = PinnedManager.getInstance().getPins();
for (Pin pin : pins) { for (Pin pin : pins) {
pin.updateWatch(); pin.updateWatch();
} }
watchNotifier.update();
} }
public static void callOnPinsChanged() { public static void callOnPinsChanged() {
@ -91,18 +96,6 @@ public class PinnedService extends Service {
}); });
} }
@SuppressWarnings("deprecation")
private void showNotification(String text) {
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification.Builder builder = new Notification.Builder(this);
builder.setTicker(text);
builder.setContentTitle(text);
builder.setContentText(text);
builder.setSmallIcon(R.drawable.ic_stat_notify);
nm.notify(1, builder.getNotification());
}
@Override @Override
public IBinder onBind(Intent intent) { public IBinder onBind(Intent intent) {

@ -3,6 +3,7 @@ package org.floens.chan.watch;
import java.util.List; import java.util.List;
import org.floens.chan.loader.Loader; import org.floens.chan.loader.Loader;
import org.floens.chan.loader.LoaderPool;
import org.floens.chan.model.Pin; import org.floens.chan.model.Pin;
import org.floens.chan.model.Post; import org.floens.chan.model.Post;
import org.floens.chan.service.PinnedService; import org.floens.chan.service.PinnedService;
@ -14,31 +15,54 @@ public class PinWatcher implements Loader.LoaderListener {
private static final String TAG = "PinWatcher"; private static final String TAG = "PinWatcher";
private final Pin pin; private final Pin pin;
private Loader loader; private final Loader loader;
private long startTime; private long startTime;
private boolean isError = false;
public PinWatcher(Pin pin) { public PinWatcher(Pin pin) {
this.pin = pin; this.pin = pin;
// loader = new Loader(this); loader = LoaderPool.getInstance().obtain(pin.loadable, this);
} }
public void destroy() { public void destroy() {
LoaderPool.getInstance().release(loader, this);
}
public void update() {
Logger.test("PinWatcher update");
if (!isError) {
if (loader.getTimeUntilReload() < -1000000L) {
Logger.test("Here: " + loader.getTimeUntilReload());
}
if (loader.getTimeUntilReload() < 0L) {
loader.requestNextDataResetTimer();
}
}
}
public int getNewPostCount() {
if (pin.watchLastCount <= 0) {
return 0;
} else {
return Math.max(0, pin.watchNewCount - pin.watchLastCount);
}
} }
@Override @Override
public void onError(VolleyError error) { public void onError(VolleyError error) {
Logger.test("PinWatcher onError: ", error); Logger.test("PinWatcher onError: ", error);
isError = true;
} }
@Override @Override
public void onData(List<Post> result, boolean append) { public void onData(List<Post> result, boolean append) {
int count = result.size(); int count = result.size();
Logger.test("PinWatcher onData"); Logger.test("PinWatcher onData, Post size: " + count);
Logger.test("Post size: " + count);
if (pin.watchLastCount <= 0) { if (pin.watchLastCount <= 0) {
pin.watchLastCount = pin.watchNewCount; pin.watchLastCount = pin.watchNewCount;
@ -46,10 +70,6 @@ public class PinWatcher implements Loader.LoaderListener {
pin.watchNewCount = count; pin.watchNewCount = count;
Logger.test("Load time: " + (System.currentTimeMillis() - startTime) + "ms");
PinnedService.callOnPinsChanged(); PinnedService.callOnPinsChanged();
} }
} }

@ -0,0 +1,33 @@
package org.floens.chan.watch;
import org.floens.chan.R;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
public class WatchNotifier {
private final int NOTIFICATION_ID = 1;
private final Context context;
public WatchNotifier(Context context) {
this.context = context;
}
public void update() {
showNotification("Update!");
}
private void showNotification(String text) {
NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder builder = new Notification.Builder(context);
builder.setTicker(text);
builder.setContentTitle(text);
builder.setContentText(text);
builder.setSmallIcon(R.drawable.ic_stat_notify);
nm.notify(NOTIFICATION_ID, builder.getNotification());
}
}
Loading…
Cancel
Save