diff --git a/Chan/AndroidManifest.xml b/Chan/AndroidManifest.xml
index 39d9aa07..935eafa5 100644
--- a/Chan/AndroidManifest.xml
+++ b/Chan/AndroidManifest.xml
@@ -40,10 +40,6 @@
-
-
= getCount() - 1 && !endOfLine && threadManager.getLoadable().isBoardMode()) {
// Try to load more posts
- threadManager.loadMore();
+ threadManager.requestNextData();
}
if (position >= count) {
@@ -80,7 +80,7 @@ public class PostAdapter extends BaseAdapter {
}
private View createThreadEndView() {
- if (threadManager.getWatchLogic() != null) {
+ if (false/* && threadManager.getWatchLogic() != null*/) {
ThreadWatchCounterView view = new ThreadWatchCounterView(context);
Utils.setPressedDrawable(view);
view.init(threadManager, listView, this);
diff --git a/Chan/src/org/floens/chan/fragment/ThreadFragment.java b/Chan/src/org/floens/chan/fragment/ThreadFragment.java
index 751c9858..5f7f323e 100644
--- a/Chan/src/org/floens/chan/fragment/ThreadFragment.java
+++ b/Chan/src/org/floens/chan/fragment/ThreadFragment.java
@@ -8,7 +8,6 @@ import org.floens.chan.adapter.PostAdapter;
import org.floens.chan.imageview.activity.ImageViewActivity;
import org.floens.chan.loader.EndOfLineException;
import org.floens.chan.manager.ThreadManager;
-import org.floens.chan.manager.ThreadManager.ThreadListener;
import org.floens.chan.model.Loadable;
import org.floens.chan.model.Post;
import org.floens.chan.utils.LoadView;
@@ -26,12 +25,12 @@ import android.widget.ListView;
import com.android.volley.VolleyError;
-public class ThreadFragment extends Fragment implements ThreadListener {
+public class ThreadFragment extends Fragment implements ThreadManager.ThreadManagerListener {
private BaseActivity baseActivity;
private ThreadManager threadManager;
- private PostAdapter postAdapter;
- private boolean shown = false;
private Loadable loadable;
+
+ private PostAdapter postAdapter;
private LoadView container;
private ListView listView;
@@ -43,8 +42,48 @@ public class ThreadFragment extends Fragment implements ThreadListener {
return fragment;
}
- public ThreadManager getThreadManager() {
- return threadManager;
+ public void bindLoadable(Loadable l) {
+ if (loadable != null) {
+ threadManager.unbindLoader();
+ }
+
+ setEmpty();
+
+ loadable = l;
+ threadManager.bindLoader(loadable);
+ }
+
+ public void requestData() {
+ threadManager.requestData();
+ }
+
+ private void setEmpty() {
+ postAdapter = null;
+
+ if (container != null) {
+ container.setView(null);
+ }
+
+ if (listView != null) {
+ listView.setOnScrollListener(null);
+ listView = null;
+ }
+ }
+
+ public void reload() {
+ setEmpty();
+
+ threadManager.requestData();
+ }
+
+ public void openReply() {
+ if (threadManager.hasLoader()) {
+ threadManager.openReply(true);
+ }
+ }
+
+ public boolean hasLoader() {
+ return threadManager.hasLoader();
}
@Override
@@ -52,8 +91,6 @@ public class ThreadFragment extends Fragment implements ThreadListener {
super.onDestroy();
if (threadManager != null) {
- stopLoading();
-
threadManager.onDestroy();
}
}
@@ -82,42 +119,9 @@ public class ThreadFragment extends Fragment implements ThreadListener {
return container;
}
- public void stopLoading() {
- if (threadManager != null) {
- threadManager.stop();
- }
-
- shown = false;
- postAdapter = null;
-
- if (container != null) {
- container.setView(null);
- }
-
- if (listView != null) {
- listView.setOnScrollListener(null);
- }
- }
-
- public void startLoading(Loadable loadable) {
- stopLoading();
-
- this.loadable = loadable;
-
- threadManager.startLoading(loadable);
- }
-
- public void reload() {
- stopLoading();
-
- threadManager.reload();
- }
-
@Override
public void onThreadLoaded(List posts) {
- if (!shown) {
- shown = true;
-
+ if (postAdapter == null) {
listView = new ListView(baseActivity);
postAdapter = new PostAdapter(baseActivity, threadManager, listView);
@@ -166,7 +170,7 @@ public class ThreadFragment extends Fragment implements ThreadListener {
}
@Override
- public void onPostClicked(Post post) {
+ public void onOPClicked(Post post) {
baseActivity.onOPClicked(post);
}
diff --git a/Chan/src/org/floens/chan/loader/EndOfLineException.java b/Chan/src/org/floens/chan/loader/EndOfLineException.java
index 6c2576de..c1087c40 100644
--- a/Chan/src/org/floens/chan/loader/EndOfLineException.java
+++ b/Chan/src/org/floens/chan/loader/EndOfLineException.java
@@ -12,4 +12,9 @@ public class EndOfLineException extends VolleyError {
public EndOfLineException() {
super();
}
+
+ @Override
+ public String getMessage() {
+ return "End of the line";
+ }
}
diff --git a/Chan/src/org/floens/chan/loader/Loader.java b/Chan/src/org/floens/chan/loader/Loader.java
new file mode 100644
index 00000000..e945c6b2
--- /dev/null
+++ b/Chan/src/org/floens/chan/loader/Loader.java
@@ -0,0 +1,155 @@
+package org.floens.chan.loader;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.floens.chan.ChanApplication;
+import org.floens.chan.model.Loadable;
+import org.floens.chan.model.Post;
+import org.floens.chan.utils.Logger;
+
+import android.util.SparseArray;
+
+import com.android.volley.Response;
+import com.android.volley.ServerError;
+import com.android.volley.VolleyError;
+
+public class Loader {
+ private static final String TAG = "Loader";
+
+ private final List listeners = new ArrayList();
+ private final Loadable loadable;
+ private ChanReaderRequest request;
+ private boolean destroyed = false;
+
+ private final SparseArray postsById = new SparseArray();
+
+ public Loader(Loadable loadable) {
+ this.loadable = loadable;
+ }
+
+ /**
+ * Add a LoaderListener
+ * @param l the listener to add
+ */
+ public void addListener(LoaderListener l) {
+ listeners.add(l);
+ }
+
+ /**
+ * Remove a LoaderListener
+ * @param l the listener to remove
+ * @return true if there are no more listeners, false otherwise
+ */
+ public boolean removeListener(LoaderListener l) {
+ listeners.remove(l);
+ if (listeners.size() == 0) {
+ destroyed = true;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public void requestData() {
+ if (request != null) {
+ request.cancel();
+ }
+
+ postsById.clear();
+
+ if (loadable.isBoardMode()) {
+ loadable.no = 0;
+ loadable.listViewIndex = 0;
+ loadable.listViewTop = 0;
+ }
+
+ request = getData(loadable);
+ }
+
+ public void requestNextData() {
+ if (loadable.isBoardMode()) {
+ loadable.no++;
+
+ if (request != null) {
+ request.cancel();
+ }
+
+ request = getData(loadable);
+ }
+ }
+
+ /**
+ * @return Returns if this loader is currently loading
+ */
+ public boolean isLoading() {
+ return request != null;
+ }
+
+ public Post getPostById(int id) {
+ return postsById.get(id);
+ }
+
+ public Loadable getLoadable() {
+ return loadable;
+ }
+
+ private ChanReaderRequest getData(Loadable loadable) {
+ Logger.i(TAG, "Requested " + loadable.board + ", " + loadable.no);
+
+ ChanReaderRequest request = ChanReaderRequest.newInstance(loadable, new Response.Listener>() {
+ @Override
+ public void onResponse(List list) {
+ Loader.this.request = null;
+ onData(list);
+ }
+ }, new Response.ErrorListener() {
+ @Override
+ public void onErrorResponse(VolleyError error) {
+ Loader.this.request = null;
+ onError(error);
+ }
+ });
+
+ ChanApplication.getVolleyRequestQueue().add(request);
+
+ return request;
+ }
+
+ private void onData(List result) {
+ if (destroyed) return;
+
+ for (Post post : result) {
+ postsById.append(post.no, post);
+ }
+
+ for (LoaderListener l : listeners) {
+ l.onData(result);
+ }
+ }
+
+ private void onError(VolleyError error) {
+ if (destroyed) return;
+
+ Logger.e(TAG, "Error loading " + error.getMessage(), error);
+
+ // 404 with more pages already loaded means endofline
+ if ((error instanceof ServerError) && loadable.isBoardMode() && loadable.no > 0) {
+ error = new EndOfLineException();
+ }
+
+ for (LoaderListener l : listeners) {
+ l.onError(error);
+ }
+ }
+
+ public static interface LoaderListener {
+ public void onData(List result);
+ public void onError(VolleyError error);
+ }
+}
+
+
+
+
+
diff --git a/Chan/src/org/floens/chan/loader/LoaderPool.java b/Chan/src/org/floens/chan/loader/LoaderPool.java
new file mode 100644
index 00000000..2cc8598b
--- /dev/null
+++ b/Chan/src/org/floens/chan/loader/LoaderPool.java
@@ -0,0 +1,47 @@
+package org.floens.chan.loader;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.floens.chan.model.Loadable;
+import org.floens.chan.utils.Logger;
+
+public class LoaderPool {
+ private static final String TAG = "LoaderPool";
+
+ private static LoaderPool instance;
+
+ private static Map loaders = new HashMap();
+
+ public static LoaderPool getInstance() {
+ if (instance == null) {
+ instance = new LoaderPool();
+ }
+
+ return instance;
+ }
+
+ public Loader obtain(Loadable loadable, Loader.LoaderListener listener) {
+ Logger.d(TAG, "loaders size: " + loaders.size());
+
+ Loader loader = loaders.get(loadable);
+ if (loader == null) {
+ loader = new Loader(loadable);
+ loaders.put(loadable, loader);
+ }
+
+ loader.addListener(listener);
+
+ return loader;
+ }
+
+ public void release(Loader loader, Loader.LoaderListener listener) {
+ if (!loaders.containsValue(loader)) {
+ throw new RuntimeException("The released loader does not exist");
+ }
+
+ if (loader.removeListener(listener)) {
+ loaders.remove(loader);
+ }
+ }
+}
diff --git a/Chan/src/org/floens/chan/loader/ThreadLoader.java b/Chan/src/org/floens/chan/loader/ThreadLoader.java
deleted file mode 100644
index 9a0631b5..00000000
--- a/Chan/src/org/floens/chan/loader/ThreadLoader.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package org.floens.chan.loader;
-
-import java.util.List;
-
-import org.floens.chan.ChanApplication;
-import org.floens.chan.model.Loadable;
-import org.floens.chan.model.Post;
-import org.floens.chan.utils.Logger;
-
-import android.util.SparseArray;
-
-import com.android.volley.Response;
-import com.android.volley.ServerError;
-import com.android.volley.VolleyError;
-
-public class ThreadLoader {
- private static final String TAG = "ThreadLoader";
-
- private final ThreadLoaderListener listener;
- private ChanReaderRequest loader;
- private boolean stopped = false;
- private boolean loading = false;
- private Loadable loadable;
- private final SparseArray postsById = new SparseArray();
-
- public ThreadLoader(ThreadLoaderListener listener) {
- this.listener = listener;
- }
-
- /**
- * @return Returns if this loader is currently loading
- */
- public boolean isLoading() {
- return loading;
- }
-
- // public void start(int mode, String board, int pageOrThreadId) {
- public void start(Loadable loadable) {
- Logger.i(TAG, "Start loading " + loadable.board + ", " + loadable.no);
-
- stop();
- stopped = false;
-
- this.loadable = loadable;
- loader = getData(loadable);
- }
-
- public void loadMore() {
- if (loadable.isBoardMode()) {
- loadable.no++;
- start(loadable);
- }
- }
-
- public void stop() {
- if (loader != null) {
-// Logger.i(TAG, "Stop loading");
- loader.cancel();
- loader = null;
- }
-
- postsById.clear();
-
- stopped = true;
- }
-
- public Post getPostById(int id) {
- return postsById.get(id);
- }
-
- private ChanReaderRequest getData(Loadable loadable) {
- ChanReaderRequest request = ChanReaderRequest.newInstance(loadable, new Response.Listener>() {
- @Override
- public void onResponse(List list) {
- loading = false;
- onData(list);
- }
- }, new Response.ErrorListener() {
- @Override
- public void onErrorResponse(VolleyError error) {
- loading = false;
- onError(error);
- }
- });
-
- ChanApplication.getVolleyRequestQueue().add(request);
- loading = true;
-
- return request;
- }
-
- private void onData(List result) {
- if (stopped) return;
-
- for (Post post : result) {
- postsById.append(post.no, post);
- }
-
- listener.onData(result);
- }
-
- private void onError(VolleyError error) {
- if (stopped) return;
-
- Logger.e(TAG, "Error loading" + error.getMessage(), error);
-
- // 404 with more pages already loaded means endofline
- if ((error instanceof ServerError) && loadable.isBoardMode() && loadable.no > 0) {
- error = new EndOfLineException();
- }
-
- listener.onError(error);
- }
-
- 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/manager/ThreadManager.java b/Chan/src/org/floens/chan/manager/ThreadManager.java
index 4565814f..00de221d 100644
--- a/Chan/src/org/floens/chan/manager/ThreadManager.java
+++ b/Chan/src/org/floens/chan/manager/ThreadManager.java
@@ -8,18 +8,16 @@ import org.floens.chan.activity.ReplyActivity;
import org.floens.chan.database.DatabaseManager;
import org.floens.chan.fragment.PostRepliesFragment;
import org.floens.chan.fragment.ReplyFragment;
-import org.floens.chan.loader.ThreadLoader;
+import org.floens.chan.loader.Loader;
+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;
import org.floens.chan.utils.ChanPreferences;
import org.floens.chan.utils.Logger;
-import org.floens.chan.watch.WatchLogic;
-import org.floens.chan.watch.WatchLogic.WatchListener;
import android.app.Activity;
import android.app.AlertDialog;
@@ -50,165 +48,100 @@ import com.android.volley.VolleyError;
* handling linkables, replies popups etc.
* onDestroy, onPause and onResume must be called from the activity/fragment
*/
-public class ThreadManager implements ThreadLoader.ThreadLoaderListener, WatchListener {
+public class ThreadManager implements Loader.LoaderListener {
private static final String TAG = "ThreadManager";
private final Activity activity;
- private final ThreadLoader threadLoader;
- private final ThreadManager.ThreadListener threadListener;
- private Loadable loadable;
- private boolean endOfLine = false;
- private WatchLogic watchLogic;
-
+ private final ThreadManager.ThreadManagerListener threadManagerListener;
private final List> popupQueue = new ArrayList>();
private PostRepliesFragment currentPopupFragment;
- public ThreadManager(Activity context, final ThreadListener listener) {
+ private Loader loader;
+
+ public ThreadManager(Activity context, final ThreadManagerListener listener) {
this.activity = context;
- threadListener = listener;
-
- threadLoader = new ThreadLoader(this);
+ threadManagerListener = listener;
}
public void onDestroy() {
- if (watchLogic != null) {
- watchLogic.destroy();
- watchLogic = null;
- }
+ unbindLoader();
}
public void onPause() {
- if (watchLogic != null) {
- watchLogic.stopTimer();
- }
+
}
public void onResume() {
- if (watchLogic != null) {
- watchLogic.startTimer();
- }
- }
-
- @Override
- public void onWatchReloadRequested() {
- Logger.d(TAG, "Reload requested");
- if (!threadLoader.isLoading()) {
- threadLoader.start(loadable);
-
- Pin pin = PinnedManager.getInstance().findPinByLoadable(loadable);
- if (pin != null) {
- PinnedManager.getInstance().onPinViewed(pin);
- }
- }
}
- public WatchLogic getWatchLogic() {
- return watchLogic;
- }
-
- @Override
- public void onError(VolleyError error) {
- threadListener.onThreadLoadError(error);
-
- if (watchLogic != null) {
- watchLogic.stopTimer();
+ public void bindLoader(Loadable loadable) {
+ if (loader != null) {
+ unbindLoader();
}
+
+ loader = LoaderPool.getInstance().obtain(loadable, this);
}
- @Override
- public void onData(List result) {
- if (watchLogic != null) {
- watchLogic.onLoaded(result.size(), true);
+ public void unbindLoader() {
+ if (loader != null) {
+ LoaderPool.getInstance().release(loader, this);
+ loader = null;
+ } else {
+ Logger.e(TAG, "Loader already unbinded");
}
-
- threadListener.onThreadLoaded(result);
}
- public boolean hasLoadable() {
- return loadable != null;
+ public void requestData() {
+ if (loader != null) {
+ loader.requestData();
+ } else {
+ Logger.e(TAG, "Loader null in requestData");
+ }
}
- public Post findPostById(int id) {
- return threadLoader.getPostById(id);
+ /**
+ * Called by postadapter and threadwatchcounterview.onclick
+ */
+ public void requestNextData() {
+ if (loader != null) {
+ loader.requestNextData();
+ } else {
+ Logger.e(TAG, "Loader null in requestData");
+ }
}
- public Loadable getLoadable() {
- return loadable;
+ @Override
+ public void onError(VolleyError error) {
+ threadManagerListener.onThreadLoadError(error);
}
- public void startLoading(Loadable loadable) {
- this.loadable = loadable;
-
- stop();
-
- threadLoader.start(loadable);
-
- Pin pin = PinnedManager.getInstance().findPinByLoadable(loadable);
- if (pin != null) {
- PinnedManager.getInstance().onPinViewed(pin);
- }
-
- if (watchLogic != null) {
- watchLogic.destroy();
- watchLogic = null;
- }
-
- if (loadable.isThreadMode()) {
- watchLogic = new WatchLogic(this);
- watchLogic.startTimer();
- }
+ @Override
+ public void onData(List result) {
+ threadManagerListener.onThreadLoaded(result);
}
- public void stop() {
- threadLoader.stop();
- endOfLine = false;
-
- if (watchLogic != null) {
- watchLogic.destroy();
- watchLogic = null;
- }
+ public boolean hasLoader() {
+ return loader != null;
}
- public void reload() {
- if (loadable == null) {
- Logger.e(TAG, "ThreadManager: loadable null");
- } else {
- if (loadable.isBoardMode()) {
- loadable.no = 0;
- loadable.listViewIndex = 0;
- loadable.listViewTop = 0;
- }
-
- startLoading(loadable);
- }
+ public Post findPostById(int id) {
+ if (loader == null) return null;
+ return loader.getPostById(id);
}
- public void loadMore() {
- if (threadLoader.isLoading()) return;
-
- if (loadable == null) {
- Logger.e(TAG, "ThreadManager: loadable null");
- } else {
- if (loadable.isBoardMode()) {
- if (!endOfLine) {
- threadLoader.loadMore();
- }
- } else if (loadable.isThreadMode()) {
- if (watchLogic != null) {
- watchLogic.loadNow();
- }
- }
- }
+ public Loadable getLoadable() {
+ if (loader == null) return null;
+ return loader.getLoadable();
}
public void onThumbnailClicked(Post post) {
- threadListener.onThumbnailClicked(post);
+ threadManagerListener.onThumbnailClicked(post);
}
public void onPostClicked(Post post) {
- if (loadable.isBoardMode()) {
- threadListener.onPostClicked(post);
+ if (loader != null && loader.getLoadable().isBoardMode()) {
+ threadManagerListener.onOPClicked(post);
}
}
@@ -257,12 +190,14 @@ public class ThreadManager implements ThreadLoader.ThreadLoaderListener, WatchLi
}
public void openReply(boolean startInActivity) {
+ if (loader == null) return;
+
if (startInActivity) {
- ReplyActivity.setLoadable(loadable);
+ ReplyActivity.setLoadable(loader.getLoadable());
Intent i = new Intent(activity, ReplyActivity.class);
activity.startActivity(i);
} else {
- ReplyFragment reply = ReplyFragment.newInstance(loadable);
+ ReplyFragment reply = ReplyFragment.newInstance(loader.getLoadable());
reply.show(activity.getFragmentManager(), "replyDialog");
}
}
@@ -562,10 +497,10 @@ public class ThreadManager implements ThreadLoader.ThreadLoaderListener, WatchLi
});
}
- public interface ThreadListener {
+ public interface ThreadManagerListener {
public void onThreadLoaded(List result);
public void onThreadLoadError(VolleyError error);
- public void onPostClicked(Post post);
+ public void onOPClicked(Post post);
public void onThumbnailClicked(Post post);
}
}
diff --git a/Chan/src/org/floens/chan/model/Pin.java b/Chan/src/org/floens/chan/model/Pin.java
index d38ea88b..c9257ce2 100644
--- a/Chan/src/org/floens/chan/model/Pin.java
+++ b/Chan/src/org/floens/chan/model/Pin.java
@@ -33,10 +33,10 @@ public class Pin {
public void updateWatch() {
if (pinWatcher == null) {
- pinWatcher = new PinWatcher(this);
+// pinWatcher = new PinWatcher(this);
}
- pinWatcher.update();
+// pinWatcher.update();
}
}
diff --git a/Chan/src/org/floens/chan/view/ThreadWatchCounterView.java b/Chan/src/org/floens/chan/view/ThreadWatchCounterView.java
index 16a8d8e3..af886bda 100644
--- a/Chan/src/org/floens/chan/view/ThreadWatchCounterView.java
+++ b/Chan/src/org/floens/chan/view/ThreadWatchCounterView.java
@@ -57,12 +57,13 @@ public class ThreadWatchCounterView extends TextView implements View.OnClickList
@Override
public void onClick(View v) {
- tm.loadMore();
+ tm.requestNextData();
ad.notifyDataSetChanged();
}
private void updateCounterText(ThreadManager threadManager) {
- WatchLogic logic = threadManager.getWatchLogic();
+// WatchLogic logic = threadManager.getWatchLogic();
+ WatchLogic logic = null;
if (logic != null) {
int time = Math.round(logic.timeLeft() / 1000f);
diff --git a/Chan/src/org/floens/chan/watch/PinWatcher.java b/Chan/src/org/floens/chan/watch/PinWatcher.java
index 6396b428..2fefa2c7 100644
--- a/Chan/src/org/floens/chan/watch/PinWatcher.java
+++ b/Chan/src/org/floens/chan/watch/PinWatcher.java
@@ -2,7 +2,7 @@ package org.floens.chan.watch;
import java.util.List;
-import org.floens.chan.loader.ThreadLoader;
+import org.floens.chan.loader.Loader;
import org.floens.chan.model.Loadable;
import org.floens.chan.model.Pin;
import org.floens.chan.model.Post;
@@ -11,12 +11,12 @@ import org.floens.chan.utils.Logger;
import com.android.volley.VolleyError;
-public class PinWatcher implements ThreadLoader.ThreadLoaderListener {
+public class PinWatcher implements Loader.LoaderListener {
private static final String TAG = "PinWatcher";
private final Pin pin;
private final Loadable loadable;
- private final ThreadLoader loader;
+ private Loader loader;
private final WatchLogic watchLogic;
private long startTime;
@@ -27,7 +27,7 @@ public class PinWatcher implements ThreadLoader.ThreadLoaderListener {
loadable = pin.loadable.copy();
loadable.simpleMode = true;
- loader = new ThreadLoader(this);
+// loader = new Loader(this);
watchLogic = new WatchLogic();
}
@@ -38,7 +38,7 @@ public class PinWatcher implements ThreadLoader.ThreadLoaderListener {
startTime = System.currentTimeMillis();
- loader.start(loadable);
+ loader.requestData();
}
}