mirror of https://github.com/kurisufriend/Clover
parent
f3db76eef6
commit
fbefe1ed33
@ -1,106 +0,0 @@ |
||||
package org.floens.chan.activity; |
||||
|
||||
import org.floens.chan.R; |
||||
import org.floens.chan.fragment.ThreadFragment; |
||||
import org.floens.chan.model.Loadable; |
||||
import org.floens.chan.model.Pin; |
||||
import org.floens.chan.model.Post; |
||||
import org.floens.chan.model.Loadable.Mode; |
||||
import org.floens.chan.net.ChanUrls; |
||||
|
||||
import android.os.Bundle; |
||||
import android.text.TextUtils; |
||||
import android.view.Menu; |
||||
import android.view.MenuItem; |
||||
|
||||
public class CatalogActivity extends BaseActivity { |
||||
private final Loadable loadable = new Loadable(); |
||||
|
||||
private ThreadFragment threadFragment; |
||||
|
||||
@Override |
||||
public void onOPClicked(Post post) { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void openPin(Pin post) { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
protected void onCreate(Bundle savedInstanceState) { |
||||
super.onCreate(savedInstanceState); |
||||
|
||||
loadable.mode = Mode.CATALOG; |
||||
|
||||
threadFragment = ThreadFragment.newInstance(this); |
||||
/*FragmentTransaction ft = getFragmentManager().beginTransaction(); |
||||
ft.replace(R.id.container, threadFragment); |
||||
ft.commitAllowingStateLoss();*/ |
||||
|
||||
Bundle bundle = getIntent().getExtras(); |
||||
|
||||
// Favor savedInstanceState bundle over intent bundle:
|
||||
// the intent bundle may be old, for example when the user
|
||||
// switches the loadable through the drawer.
|
||||
if (savedInstanceState != null) { |
||||
loadable.readFromBundle(this, savedInstanceState); |
||||
} else if (bundle != null) { |
||||
loadable.readFromBundle(this, bundle); |
||||
} else { |
||||
finish(); |
||||
} |
||||
|
||||
startLoading(loadable); |
||||
} |
||||
|
||||
@Override |
||||
protected void onSaveInstanceState(Bundle outState) { |
||||
super.onSaveInstanceState(outState); |
||||
|
||||
loadable.writeToBundle(this, outState); |
||||
} |
||||
|
||||
@Override |
||||
public boolean onOptionsItemSelected(MenuItem item) { |
||||
switch(item.getItemId()) { |
||||
case R.id.action_reload: |
||||
threadFragment.reload(); |
||||
|
||||
return true; |
||||
case R.id.action_open_browser: |
||||
showUrlOpenPicker(ChanUrls.getCatalogUrlDesktop(loadable.board)); |
||||
|
||||
return true; |
||||
case android.R.id.home: |
||||
finish(); |
||||
|
||||
return true; |
||||
default: |
||||
return super.onOptionsItemSelected(item); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public boolean onCreateOptionsMenu(Menu menu) { |
||||
return super.onCreateOptionsMenu(menu); |
||||
} |
||||
|
||||
private void startLoading(Loadable loadable) { |
||||
threadFragment.startLoading(loadable); |
||||
|
||||
setShareUrl(ChanUrls.getCatalogUrlDesktop(loadable.board)); |
||||
|
||||
if (TextUtils.isEmpty(loadable.title)) { |
||||
loadable.title = "Catalog /" + loadable.board + "/"; |
||||
} |
||||
|
||||
getActionBar().setTitle(loadable.title); |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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<LoaderListener> listeners = new ArrayList<LoaderListener>(); |
||||
private final Loadable loadable; |
||||
private ChanReaderRequest request; |
||||
private boolean destroyed = false; |
||||
|
||||
private final SparseArray<Post> postsById = new SparseArray<Post>(); |
||||
|
||||
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<List<Post>>() { |
||||
@Override |
||||
public void onResponse(List<Post> 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<Post> 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<Post> result); |
||||
public void onError(VolleyError error); |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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<Loadable, Loader> loaders = new HashMap<Loadable, Loader>(); |
||||
|
||||
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); |
||||
} |
||||
} |
||||
} |
@ -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<Post> postsById = new SparseArray<Post>(); |
||||
|
||||
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<List<Post>>() { |
||||
@Override |
||||
public void onResponse(List<Post> 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<Post> 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<Post> result); |
||||
public abstract void onError(VolleyError error); |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in new issue