From 2c5cd1bedb5480639748cadb1fce98601265d8d6 Mon Sep 17 00:00:00 2001 From: Florens Douwes Date: Wed, 26 Feb 2014 17:06:20 +0100 Subject: [PATCH] ThreadWatcher updates --- .../{pin_icon.xml => pin_icon_blue.xml} | 0 Chan/res/drawable/pin_icon_red.xml | 16 +++++ Chan/res/layout/pin_item.xml | 5 +- .../floens/chan/activity/BaseActivity.java | 16 ++++- .../floens/chan/adapter/PinnedAdapter.java | 13 ++++ .../floens/chan/database/DatabaseHelper.java | 12 +++- .../floens/chan/fragment/ThreadFragment.java | 1 + .../floens/chan/manager/PinnedManager.java | 33 ++++++++++ .../floens/chan/manager/ThreadManager.java | 33 ++++++---- Chan/src/org/floens/chan/model/Loadable.java | 19 ++++++ Chan/src/org/floens/chan/model/Pin.java | 41 ++++--------- Chan/src/org/floens/chan/model/Post.java | 12 ++-- .../floens/chan/net/ChanReaderRequest.java | 49 ++++++++++----- .../src/org/floens/chan/net/ThreadLoader.java | 21 ++----- .../floens/chan/service/PinnedService.java | 14 ++++- .../src/org/floens/chan/watch/PinWatcher.java | 61 +++++++++++++++++++ 16 files changed, 263 insertions(+), 83 deletions(-) rename Chan/res/drawable/{pin_icon.xml => pin_icon_blue.xml} (100%) create mode 100644 Chan/res/drawable/pin_icon_red.xml create mode 100644 Chan/src/org/floens/chan/watch/PinWatcher.java diff --git a/Chan/res/drawable/pin_icon.xml b/Chan/res/drawable/pin_icon_blue.xml similarity index 100% rename from Chan/res/drawable/pin_icon.xml rename to Chan/res/drawable/pin_icon_blue.xml diff --git a/Chan/res/drawable/pin_icon_red.xml b/Chan/res/drawable/pin_icon_red.xml new file mode 100644 index 00000000..c12eb1e2 --- /dev/null +++ b/Chan/res/drawable/pin_icon_red.xml @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/Chan/res/layout/pin_item.xml b/Chan/res/layout/pin_item.xml index 33b85c79..5d9b751e 100644 --- a/Chan/res/layout/pin_item.xml +++ b/Chan/res/layout/pin_item.xml @@ -23,7 +23,8 @@ @@ -34,7 +35,7 @@ android:gravity="center" android:textSize="16dp" android:textColor="#fff" - android:text="99+" /> + android:text="99" /> diff --git a/Chan/src/org/floens/chan/activity/BaseActivity.java b/Chan/src/org/floens/chan/activity/BaseActivity.java index 31ee912b..742b5ec2 100644 --- a/Chan/src/org/floens/chan/activity/BaseActivity.java +++ b/Chan/src/org/floens/chan/activity/BaseActivity.java @@ -36,7 +36,7 @@ import android.widget.EditText; import android.widget.ListView; import android.widget.ShareActionProvider; -public abstract class BaseActivity extends Activity implements PanelSlideListener { +public abstract class BaseActivity extends Activity implements PanelSlideListener, PinnedManager.PinListener { private final static int ACTION_OPEN_URL = 1; protected PinnedAdapter pinnedAdapter; @@ -71,6 +71,15 @@ public abstract class BaseActivity extends Activity implements PanelSlideListene threadPane = (SlidingPaneLayout) findViewById(R.id.pane_container); initPane(); + + PinnedManager.getInstance().addPinListener(this); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + + PinnedManager.getInstance().removePinListener(this); } protected void initDrawer() { @@ -134,6 +143,11 @@ public abstract class BaseActivity extends Activity implements PanelSlideListene threadPane.openPane(); } + @Override + public void onPinsChanged() { + pinnedAdapter.notifyDataSetChanged(); + } + public void addPin(Pin pin) { if (PinnedManager.getInstance().add(pin)) { pinnedAdapter.add(pin); diff --git a/Chan/src/org/floens/chan/adapter/PinnedAdapter.java b/Chan/src/org/floens/chan/adapter/PinnedAdapter.java index 17d5c1f1..0ea8b011 100644 --- a/Chan/src/org/floens/chan/adapter/PinnedAdapter.java +++ b/Chan/src/org/floens/chan/adapter/PinnedAdapter.java @@ -11,6 +11,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; +import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.TextView; @@ -45,6 +46,18 @@ public class PinnedAdapter extends ArrayAdapter { view = (LinearLayout) inflater.inflate(R.layout.pin_item, null); ((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)); + + ((TextView) view.findViewById(R.id.drawer_item_count)).setText(total); + + FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.drawer_item_count_container); +// if (Math.random() < 0.5d) { + frameLayout.setBackgroundResource(R.drawable.pin_icon_blue); +// } else { +// frameLayout.setBackgroundResource(R.drawable.pin_icon_red); +// } } if (listener != null) { diff --git a/Chan/src/org/floens/chan/database/DatabaseHelper.java b/Chan/src/org/floens/chan/database/DatabaseHelper.java index 6decdf0a..9c45038c 100644 --- a/Chan/src/org/floens/chan/database/DatabaseHelper.java +++ b/Chan/src/org/floens/chan/database/DatabaseHelper.java @@ -16,7 +16,7 @@ import com.j256.ormlite.table.TableUtils; public class DatabaseHelper extends OrmLiteSqliteOpenHelper { private static final String DATABASE_NAME = "ChanDB"; - private static final int DATABASE_VERSION = 1; + private static final int DATABASE_VERSION = 3; public Dao pinDao; public Dao loadableDao; @@ -48,6 +48,16 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { switch(oldVersion) { // Change tables if we make adjustments } + + // Drop the tables and recreate them for now + try { + TableUtils.dropTable(connectionSource, Pin.class, true); + TableUtils.dropTable(connectionSource, Loadable.class, true); + + onCreate(database, connectionSource); + } catch (SQLException e) { + e.printStackTrace(); + } } } diff --git a/Chan/src/org/floens/chan/fragment/ThreadFragment.java b/Chan/src/org/floens/chan/fragment/ThreadFragment.java index b3dd1f97..14c11542 100644 --- a/Chan/src/org/floens/chan/fragment/ThreadFragment.java +++ b/Chan/src/org/floens/chan/fragment/ThreadFragment.java @@ -81,6 +81,7 @@ public class ThreadFragment extends Fragment implements ThreadListener { stopLoading(); this.loadable = loadable; + threadManager.startLoading(loadable); } diff --git a/Chan/src/org/floens/chan/manager/PinnedManager.java b/Chan/src/org/floens/chan/manager/PinnedManager.java index a3bbca15..10ef76b3 100644 --- a/Chan/src/org/floens/chan/manager/PinnedManager.java +++ b/Chan/src/org/floens/chan/manager/PinnedManager.java @@ -1,5 +1,6 @@ package org.floens.chan.manager; +import java.util.ArrayList; import java.util.List; import org.floens.chan.adapter.PinnedAdapter; @@ -13,6 +14,7 @@ public class PinnedManager { private static PinnedManager instance; private final Context context; + private final List listeners = new ArrayList(); private final List pins; public PinnedManager(Context context) { @@ -26,6 +28,14 @@ public class PinnedManager { return instance; } + public void addPinListener(PinListener l) { + listeners.add(l); + } + + public void removePinListener(PinListener l) { + listeners.remove(l); + } + public PinnedAdapter getAdapter() { PinnedAdapter adapter = new PinnedAdapter(context, 0); @@ -72,6 +82,9 @@ public class PinnedManager { pins.add(pin); DatabaseManager.getInstance().addPin(pin); + + onPinsChanged(); + return true; } @@ -82,6 +95,8 @@ public class PinnedManager { public void remove(Pin pin) { pins.remove(pin); DatabaseManager.getInstance().removePin(pin); + + onPinsChanged(); } /** @@ -90,6 +105,8 @@ public class PinnedManager { */ public void update(Pin pin) { DatabaseManager.getInstance().updatePin(pin); + + onPinsChanged(); } /** @@ -105,6 +122,22 @@ public class PinnedManager { } }).start(); } + + public void onPinViewed(Pin pin) { + pin.watchLastCount = pin.watchNewCount; + + onPinsChanged(); + } + + public void onPinsChanged() { + for (PinListener l : listeners) { + l.onPinsChanged(); + } + } + + public static interface PinListener { + public void onPinsChanged(); + } } diff --git a/Chan/src/org/floens/chan/manager/ThreadManager.java b/Chan/src/org/floens/chan/manager/ThreadManager.java index 92b264dc..e75e9c56 100644 --- a/Chan/src/org/floens/chan/manager/ThreadManager.java +++ b/Chan/src/org/floens/chan/manager/ThreadManager.java @@ -8,6 +8,7 @@ import org.floens.chan.activity.ReplyActivity; import org.floens.chan.fragment.PostRepliesFragment; import org.floens.chan.fragment.ReplyFragment; 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.net.ThreadLoader; @@ -35,9 +36,10 @@ import com.android.volley.VolleyError; /** * All PostView's need to have this referenced. - * This manages some things like pages, starting and stopping of loading etc. + * This manages some things like pages, starting and stopping of loading, + * handling linkables, replies popups etc. */ -public class ThreadManager { +public class ThreadManager implements ThreadLoader.ThreadLoaderListener { private final Activity activity; private final ThreadLoader threadLoader; private final ThreadManager.ThreadListener threadListener; @@ -51,17 +53,17 @@ public class ThreadManager { this.activity = context; threadListener = listener; - threadLoader = new ThreadLoader(new ThreadLoader.ThreadLoaderListener() { - @Override - public void onError(VolleyError error) { - listener.onThreadLoadError(error); - } - - @Override - public void onData(List result) { - listener.onThreadLoaded(result); - } - }); + threadLoader = new ThreadLoader(this); + } + + @Override + public void onError(VolleyError error) { + threadListener.onThreadLoadError(error); + } + + @Override + public void onData(List result) { + threadListener.onThreadLoaded(result); } public boolean hasThread() { @@ -80,6 +82,11 @@ public class ThreadManager { this.loadable = loadable; threadLoader.start(loadable); + + Pin pin = PinnedManager.getInstance().findPinByLoadable(loadable); + if (pin != null) { + PinnedManager.getInstance().onPinViewed(pin); + } } public void stop() { diff --git a/Chan/src/org/floens/chan/model/Loadable.java b/Chan/src/org/floens/chan/model/Loadable.java index 75136652..48b2e270 100644 --- a/Chan/src/org/floens/chan/model/Loadable.java +++ b/Chan/src/org/floens/chan/model/Loadable.java @@ -32,6 +32,12 @@ public class Loadable { @DatabaseField public int listViewTop; + /** + * When simple mode is enabled, CPU intensive methods won't get called. + * This is used for the thread watcher. + */ + public boolean simpleMode = false; + /** * Constructs an empty loadable. * The mode is INVALID. @@ -120,6 +126,19 @@ public class Loadable { bundle.putInt(p + ".listViewTop", listViewTop); } + public Loadable copy() { + Loadable copy = new Loadable(); + copy.mode = mode; + copy.board = board; + copy.no = no; + copy.title = title; + copy.listViewIndex = listViewIndex; + copy.listViewTop = listViewTop; + copy.simpleMode = simpleMode; + + return copy; + } + public static class Mode { public static final int INVALID = -1; public static final int THREAD = 0; diff --git a/Chan/src/org/floens/chan/model/Pin.java b/Chan/src/org/floens/chan/model/Pin.java index 548a6dc0..d38ea88b 100644 --- a/Chan/src/org/floens/chan/model/Pin.java +++ b/Chan/src/org/floens/chan/model/Pin.java @@ -1,16 +1,12 @@ package org.floens.chan.model; -import java.util.List; +import org.floens.chan.watch.PinWatcher; -import org.floens.chan.net.ThreadLoader; -import org.floens.chan.utils.Logger; - -import com.android.volley.VolleyError; import com.j256.ormlite.field.DatabaseField; import com.j256.ormlite.table.DatabaseTable; @DatabaseTable -public class Pin implements ThreadLoader.ThreadLoaderListener { +public class Pin { // Database stuff @DatabaseField(generatedId = true) private int id; @@ -27,35 +23,22 @@ public class Pin implements ThreadLoader.ThreadLoaderListener { }; // PinnedService stuff - public ThreadLoader threadLoader; - public int lastPostCount; - public int newPostCount; + public PinWatcher pinWatcher; - public void update() { - Logger.test("Update in pin"); - - if (threadLoader == null) { - threadLoader = new ThreadLoader(this); - } - - threadLoader.start(loadable); - } + @DatabaseField + public int watchLastCount; - @Override - public void onError(VolleyError error) { - Logger.test("OnError in pin: ", error); - } + @DatabaseField + public int watchNewCount; - @Override - public void onData(List result) { - Logger.test("OnData in pin: "); - Logger.test("Size: " + result.size()); + public void updateWatch() { + if (pinWatcher == null) { + pinWatcher = new PinWatcher(this); + } - newPostCount = result.size(); + pinWatcher.update(); } } - - diff --git a/Chan/src/org/floens/chan/model/Post.java b/Chan/src/org/floens/chan/model/Post.java index 78a18d36..daab99e5 100644 --- a/Chan/src/org/floens/chan/model/Post.java +++ b/Chan/src/org/floens/chan/model/Post.java @@ -86,7 +86,7 @@ public class Post { * Finish up the data * @return false if this data is invalid */ - public boolean finish() { + public boolean finish(Loadable loadable) { if (board == null) return false; if (no < 0 || resto < 0 || date == null) return false; @@ -105,7 +105,7 @@ public class Post { } if (rawComment != null) { - comment = parseComment(rawComment); + comment = parseComment(rawComment, loadable.simpleMode); } try { @@ -123,9 +123,13 @@ public class Post { return true; } - private CharSequence parseComment(String commentRaw) { - CharSequence total = new SpannableString(""); + private CharSequence parseComment(String commentRaw, boolean simpleMode) { + if (simpleMode) { + return ""; + } + CharSequence total = new SpannableString(""); + try { String comment = commentRaw.replace("", ""); diff --git a/Chan/src/org/floens/chan/net/ChanReaderRequest.java b/Chan/src/org/floens/chan/net/ChanReaderRequest.java index 90844f3e..bccf73da 100644 --- a/Chan/src/org/floens/chan/net/ChanReaderRequest.java +++ b/Chan/src/org/floens/chan/net/ChanReaderRequest.java @@ -2,6 +2,7 @@ package org.floens.chan.net; import java.io.IOException; import java.util.ArrayList; +import java.util.List; import org.floens.chan.model.Loadable; import org.floens.chan.model.Post; @@ -13,10 +14,10 @@ import com.android.volley.Response.ErrorListener; import com.android.volley.Response.Listener; import com.android.volley.extra.JsonReaderRequest; -public class ChanReaderRequest extends JsonReaderRequest> { +public class ChanReaderRequest extends JsonReaderRequest> { private Loadable loadable; - private ChanReaderRequest(String url, Listener> listener, ErrorListener errorListener) { + private ChanReaderRequest(String url, Listener> listener, ErrorListener errorListener) { super(url, listener, errorListener); } @@ -29,7 +30,7 @@ public class ChanReaderRequest extends JsonReaderRequest> { * @param errorListener * @return New instance of ChanReaderRequest */ - public static ChanReaderRequest newInstance(Loadable loadable, Listener> listener, ErrorListener errorListener) { + public static ChanReaderRequest newInstance(Loadable loadable, Listener> listener, ErrorListener errorListener) { String url; if (loadable.isBoardMode()) { @@ -54,19 +55,35 @@ public class ChanReaderRequest extends JsonReaderRequest> { } @Override - public ArrayList readJson(JsonReader reader) { + public List readJson(JsonReader reader) { + List list = new ArrayList(); + if (loadable.isBoardMode()) { - return loadBoard(reader); + list = loadBoard(reader); } else if (loadable.isThreadMode()) { - return loadThread(reader); + list = loadThread(reader); } else if (loadable.isCatalogMode()) { - return loadCatalog(reader); + list = loadCatalog(reader); } else { throw new IllegalArgumentException("Unknown mode"); } + + processPosts(list); + + return list; + } + + private void processPosts(List posts) { + for (Post post : posts) { + for (Post other : posts) { + if (other.repliesTo.contains(post.no)) { + post.repliesFrom.add(other.no); + } + } + } } - private ArrayList loadThread(JsonReader reader) { + private List loadThread(JsonReader reader) { ArrayList list = new ArrayList(); try { @@ -78,7 +95,7 @@ public class ChanReaderRequest extends JsonReaderRequest> { // Thread array while (reader.hasNext()) { // Thread object - list.add(readPostObject(reader, loadable.board)); + list.add(readPostObject(reader)); } reader.endArray(); } else { @@ -100,7 +117,7 @@ public class ChanReaderRequest extends JsonReaderRequest> { return list; } - private ArrayList loadBoard(JsonReader reader) { + private List loadBoard(JsonReader reader) { ArrayList list = new ArrayList(); try { @@ -115,7 +132,7 @@ public class ChanReaderRequest extends JsonReaderRequest> { if (reader.nextName().equals("posts")) { reader.beginArray(); - list.add(readPostObject(reader, loadable.board)); + list.add(readPostObject(reader)); // Only consume one post while (reader.hasNext()) reader.skipValue(); @@ -148,7 +165,7 @@ public class ChanReaderRequest extends JsonReaderRequest> { return list; } - private ArrayList loadCatalog(JsonReader reader) { + private List loadCatalog(JsonReader reader) { ArrayList list = new ArrayList(); try { @@ -162,7 +179,7 @@ public class ChanReaderRequest extends JsonReaderRequest> { reader.beginArray(); // Threads array while (reader.hasNext()) { - list.add(readPostObject(reader, loadable.board)); + list.add(readPostObject(reader)); } reader.endArray(); @@ -189,9 +206,9 @@ public class ChanReaderRequest extends JsonReaderRequest> { return list; } - private Post readPostObject(JsonReader reader, String board) throws IllegalStateException, NumberFormatException, IOException { + private Post readPostObject(JsonReader reader) throws IllegalStateException, NumberFormatException, IOException { Post post = new Post(); - post.board = board; + post.board = loadable.board; reader.beginObject(); while(reader.hasNext()) { @@ -252,7 +269,7 @@ public class ChanReaderRequest extends JsonReaderRequest> { } reader.endObject(); - if (!post.finish()) { + if (!post.finish(loadable)) { throw new IOException("Incorrect data about post received."); } diff --git a/Chan/src/org/floens/chan/net/ThreadLoader.java b/Chan/src/org/floens/chan/net/ThreadLoader.java index 21c13f28..7f7ffd29 100644 --- a/Chan/src/org/floens/chan/net/ThreadLoader.java +++ b/Chan/src/org/floens/chan/net/ThreadLoader.java @@ -1,6 +1,5 @@ package org.floens.chan.net; -import java.util.ArrayList; import java.util.List; import org.floens.chan.ChanApplication; @@ -65,9 +64,9 @@ public class ThreadLoader { } private ChanReaderRequest getData(Loadable loadable) { - ChanReaderRequest request = ChanReaderRequest.newInstance(loadable, new Response.Listener>() { + ChanReaderRequest request = ChanReaderRequest.newInstance(loadable, new Response.Listener>() { @Override - public void onResponse(ArrayList list) { + public void onResponse(List list) { loading = false; onData(list); } @@ -88,7 +87,9 @@ public class ThreadLoader { private void onData(List result) { if (stopped) return; - processPosts(result); + for (Post post : result) { + postsById.append(post.no, post); + } listener.onData(result); } @@ -106,18 +107,6 @@ public class ThreadLoader { listener.onError(error); } - private void processPosts(List posts) { - for (Post post : posts) { - postsById.append(post.no, post); - - for (Post other : posts) { - if (other.repliesTo.contains(post.no)) { - post.repliesFrom.add(other.no); - } - } - } - } - public static abstract interface ThreadLoaderListener { public abstract void onData(List result); public abstract void onError(VolleyError error); diff --git a/Chan/src/org/floens/chan/service/PinnedService.java b/Chan/src/org/floens/chan/service/PinnedService.java index f071da4c..ccdffb4d 100644 --- a/Chan/src/org/floens/chan/service/PinnedService.java +++ b/Chan/src/org/floens/chan/service/PinnedService.java @@ -10,7 +10,9 @@ import android.app.Notification; import android.app.NotificationManager; import android.app.Service; import android.content.Intent; +import android.os.Handler; import android.os.IBinder; +import android.os.Looper; public class PinnedService extends Service { private Thread loadThread; @@ -61,10 +63,20 @@ public class PinnedService extends Service { private void doUpdates() { List pins = PinnedManager.getInstance().getPins(); for (Pin pin : pins) { -// pin.update(); + pin.updateWatch(); +// pin.newPostCount++; } } + public static void callOnPinsChanged() { + new Handler(Looper.getMainLooper()).post(new Runnable() { + @Override + public void run() { + PinnedManager.getInstance().onPinsChanged(); + } + }); + } + @SuppressWarnings("deprecation") private void showNotification(String text) { NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); diff --git a/Chan/src/org/floens/chan/watch/PinWatcher.java b/Chan/src/org/floens/chan/watch/PinWatcher.java new file mode 100644 index 00000000..152d2ad4 --- /dev/null +++ b/Chan/src/org/floens/chan/watch/PinWatcher.java @@ -0,0 +1,61 @@ +package org.floens.chan.watch; + +import java.util.List; + +import org.floens.chan.model.Loadable; +import org.floens.chan.model.Pin; +import org.floens.chan.model.Post; +import org.floens.chan.net.ThreadLoader; +import org.floens.chan.service.PinnedService; +import org.floens.chan.utils.Logger; + +import com.android.volley.VolleyError; + +public class PinWatcher implements ThreadLoader.ThreadLoaderListener { + private static final int[] timeouts = {10, 15, 20, 30, 60, 90, 120, 180, 240, 300}; + + private final ThreadLoader watchLoader; + private final Loadable watchLoadable; + + private final Pin pin; + + private long startTime; + + public PinWatcher(Pin pin) { + this.pin = pin; + + watchLoadable = pin.loadable.copy(); + watchLoadable.simpleMode = true; + + watchLoader = new ThreadLoader(this); + } + + public void update() { + Logger.test("PinWatcher update"); + + startTime = System.currentTimeMillis(); + + watchLoader.start(watchLoadable); + } + + @Override + public void onError(VolleyError error) { + Logger.test("PinWatcher onError: ", error); + } + + @Override + public void onData(List result) { + int count = result.size(); + + Logger.i("PinWatcher onData"); + Logger.i("Post size: " + count); + + pin.watchNewCount = count; + + Logger.i("Load time: " + (System.currentTimeMillis() - startTime) + "ms"); + + PinnedService.callOnPinsChanged(); + } + + +}