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_close">Close drawer</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="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.PinnedManager;
import org.floens.chan.manager.ReplyManager;
import org.floens.chan.service.PinnedService;
import org.floens.chan.utils.IconCache;
import android.app.Application;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.StrictMode;
import android.preference.PreferenceManager;
@ -70,7 +72,7 @@ public class ChanApplication extends Application {
new PinnedManager(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.model.Pin;
import org.floens.chan.model.Post;
import org.floens.chan.utils.Logger;
import android.app.Activity;
import android.app.AlertDialog;
@ -147,6 +148,8 @@ public abstract class BaseActivity extends Activity implements PanelSlideListene
@Override
public void onPinsChanged() {
pinnedAdapter.reload();
pinDrawerView.invalidate();
Logger.test("onPinsChanged");
}
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() {
final ActionBar actionBar = getActionBar();
@ -297,7 +303,7 @@ public class BoardActivity extends BaseActivity implements ActionBar.OnNavigatio
private void startLoadingBoard(Loadable loadable) {
if (loadable.mode == Loadable.Mode.INVALID) return;
this.boardLoadable = loadable;
boardLoadable = loadable;
boardFragment.bindLoadable(loadable);
boardFragment.requestData();

@ -19,7 +19,6 @@ import android.widget.TextView;
public class PinnedAdapter extends ArrayAdapter<Pin> {
private final HashMap<Pin, Integer> idMap;
private int idCounter;
private View.OnTouchListener listener;
public PinnedAdapter(Context context, int resId) {
super(context, resId, new ArrayList<Pin>());
@ -27,10 +26,6 @@ public class PinnedAdapter extends ArrayAdapter<Pin> {
idMap = new HashMap<Pin, Integer>();
}
public void setTouchListener(View.OnTouchListener listener) {
this.listener = listener;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
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);
int count = Math.max(0, item.watchNewCount - item.watchLastCount);
String total = Integer.toString(Math.min(count, 999));
int count = item.getNewPostCount();
String total = Integer.toString(count);
if (count > 999) {
total = "1k+";
}
((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;
}
@ -76,6 +70,8 @@ public class PinnedAdapter extends ArrayAdapter<Pin> {
add(header);
addAll(PinnedManager.getInstance().getPins());
notifyDataSetChanged();
}
@Override

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

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

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

@ -13,6 +13,7 @@ import org.floens.chan.loader.LoaderPool;
import org.floens.chan.manager.ReplyManager.DeleteListener;
import org.floens.chan.manager.ReplyManager.DeleteResponse;
import org.floens.chan.model.Loadable;
import org.floens.chan.model.Pin;
import org.floens.chan.model.Post;
import org.floens.chan.model.PostLinkable;
import org.floens.chan.model.SavedReply;
@ -93,6 +94,15 @@ public class ThreadManager implements Loader.LoaderListener {
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() {
if (loader != null) {
loader.requestData();
@ -398,7 +408,7 @@ public class ThreadManager implements Loader.LoaderListener {
FragmentTransaction ft = activity.getFragmentManager().beginTransaction();
ft.add(popup, "postPopup");
ft.commit();
ft.commitAllowingStateLoss();
currentPopupFragment = popup;
}

@ -33,10 +33,28 @@ public class Pin {
public void updateWatch() {
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 org.floens.chan.R;
import org.floens.chan.manager.PinnedManager;
import org.floens.chan.model.Pin;
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.content.Intent;
import android.os.Handler;
@ -23,6 +21,7 @@ public class PinnedService extends Service {
private Thread loadThread;
private boolean running = true;
private final WatchNotifier watchNotifier;
public static void onActivityStart() {
Logger.test("onActivityStart");
@ -34,6 +33,10 @@ public class PinnedService extends Service {
activityInForeground = false;
}
public PinnedService() {
watchNotifier = new WatchNotifier(this);
}
@Override
public void onCreate() {
super.onCreate();
@ -49,37 +52,39 @@ public class PinnedService extends Service {
}
private void start() {
loadThread = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
while (running) {
doUpdates();
long timeout = activityInForeground ? FOREGROUND_INTERVAL : BACKGROUND_INTERVAL;
try {
Thread.sleep(timeout);
} catch (InterruptedException e) {
e.printStackTrace();
running = true;
if (loadThread == null) {
loadThread = new Thread(new Runnable() {
@Override
public void run() {
while (running) {
update();
long timeout = activityInForeground ? FOREGROUND_INTERVAL : BACKGROUND_INTERVAL;
try {
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();
for (Pin pin : pins) {
pin.updateWatch();
}
watchNotifier.update();
}
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
public IBinder onBind(Intent intent) {

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