Add Thread model

Contains a list of posts
Already has some other flags like closed and archived.
In the future more data will be added to Thread.
captchafix
Floens 11 years ago
parent 3679fd473b
commit ecc2790275
  1. 80
      Clover/app/src/main/java/org/floens/chan/core/loader/Loader.java
  2. 28
      Clover/app/src/main/java/org/floens/chan/core/manager/ThreadManager.java
  3. 14
      Clover/app/src/main/java/org/floens/chan/core/model/ChanThread.java
  4. 17
      Clover/app/src/main/java/org/floens/chan/core/watch/PinWatcher.java
  5. 3
      Clover/app/src/main/java/org/floens/chan/ui/activity/BaseActivity.java
  6. 7
      Clover/app/src/main/java/org/floens/chan/ui/activity/ChanActivity.java
  7. 58
      Clover/app/src/main/java/org/floens/chan/ui/adapter/PostAdapter.java
  8. 14
      Clover/app/src/main/java/org/floens/chan/ui/fragment/ThreadFragment.java

@ -25,6 +25,7 @@ import com.android.volley.ServerError;
import com.android.volley.VolleyError;
import org.floens.chan.ChanApplication;
import org.floens.chan.core.model.ChanThread;
import org.floens.chan.core.model.Loadable;
import org.floens.chan.core.model.Post;
import org.floens.chan.core.net.ChanReaderRequest;
@ -45,11 +46,10 @@ public class Loader {
private static final int[] watchTimeouts = {10, 15, 20, 30, 60, 90, 120, 180, 240, 300, 600, 1800, 3600};
private final List<LoaderListener> listeners = new ArrayList<LoaderListener>();
private final List<LoaderListener> listeners = new ArrayList<>();
private final Loadable loadable;
private final SparseArray<Post> postsById = new SparseArray<Post>();
private final List<Post> cachedPosts = new ArrayList<Post>();
private Post op;
private final SparseArray<Post> postsById = new SparseArray<>();
private ChanThread thread;
private boolean destroyed = false;
private boolean autoReload = false;
@ -84,6 +84,9 @@ public class Loader {
if (listeners.size() == 0) {
clearTimer();
destroyed = true;
if (request != null) {
request.cancel();
}
return true;
} else {
return false;
@ -133,8 +136,7 @@ public class Loader {
}
currentTimeout = 0;
cachedPosts.clear();
op = null;
thread = null;
request = getData();
}
@ -186,10 +188,6 @@ public class Loader {
return loadable;
}
public Post getOP() {
return op;
}
/**
* Get the time in milliseconds until another loadMore is recommended
*
@ -204,8 +202,8 @@ public class Loader {
}
}
public List<Post> getCachedPosts() {
return cachedPosts;
public ChanThread getThread() {
return thread;
}
private void setTimer(int postCount) {
@ -255,9 +253,10 @@ public class Loader {
}
private ChanReaderRequest getData() {
Logger.i(TAG, "Requested " + loadable.board + ", " + loadable.no);
// Logger.i(TAG, "Requested " + loadable.board + ", " + loadable.no);
ChanReaderRequest request = ChanReaderRequest.newInstance(loadable, cachedPosts,
List<Post> cached = thread == null ? new ArrayList<Post>() : thread.posts;
ChanReaderRequest request = ChanReaderRequest.newInstance(loadable, cached,
new Response.Listener<List<Post>>() {
@Override
public void onResponse(List<Post> list) {
@ -282,31 +281,56 @@ public class Loader {
if (destroyed)
return;
cachedPosts.clear();
if (loadable.isThreadMode()) {
cachedPosts.addAll(result);
if (thread == null) {
thread = new ChanThread(new ArrayList<Post>());
}
postsById.clear();
for (Post post : result) {
postsById.append(post.no, post);
if (loadable.isThreadMode() || loadable.isCatalogMode()) {
thread.posts.clear();
thread.posts.addAll(result);
postsById.clear();
for (Post post : result) {
postsById.append(post.no, post);
}
} else if (loadable.isBoardMode()) {
// Only add new posts
boolean flag;
for (Post post : result) {
flag = true;
for (Post cached : thread.posts) {
if (post.no == cached.no) {
flag = false;
break;
}
}
if (flag) {
thread.posts.add(post);
postsById.append(post.no, post);
}
}
}
if (loadable.isThreadMode() && result.size() > 0) {
op = result.get(0);
if (loadable.isThreadMode() && thread.posts.size() > 0) {
thread.op = thread.posts.get(0);
thread.closed = thread.op.closed;
thread.archived = thread.op.archived;
}
if (TextUtils.isEmpty(loadable.title)) {
if (getOP() != null) {
loadable.generateTitle(getOP());
if (thread.op != null) {
loadable.generateTitle(thread.op);
} else {
loadable.title = "/" + loadable.board + "/";
}
}
for (Post post : thread.posts) {
post.title = loadable.title;
}
for (LoaderListener l : listeners) {
l.onData(result, loadable.isBoardMode());
l.onData(thread);
}
lastLoadTime = Time.get();
@ -320,7 +344,7 @@ public class Loader {
if (destroyed)
return;
cachedPosts.clear();
thread = null;
Logger.e(TAG, "Error loading " + error.getMessage(), error);
@ -337,7 +361,7 @@ public class Loader {
}
public static interface LoaderListener {
public void onData(List<Post> result, boolean append);
public void onData(ChanThread result);
public void onError(VolleyError error);
}

@ -45,6 +45,7 @@ import org.floens.chan.core.loader.Loader;
import org.floens.chan.core.loader.LoaderPool;
import org.floens.chan.core.manager.ReplyManager.DeleteListener;
import org.floens.chan.core.manager.ReplyManager.DeleteResponse;
import org.floens.chan.core.model.ChanThread;
import org.floens.chan.core.model.Loadable;
import org.floens.chan.core.model.Pin;
import org.floens.chan.core.model.Post;
@ -92,7 +93,7 @@ public class ThreadManager implements Loader.LoaderListener {
public void onStart() {
if (loader != null) {
if (shouldWatch()) {
if (isWatching()) {
loader.setAutoLoadMore(true);
loader.requestMoreDataAndResetTimer();
}
@ -111,7 +112,7 @@ public class ThreadManager implements Loader.LoaderListener {
}
loader = LoaderPool.getInstance().obtain(loadable, this);
if (shouldWatch()) {
if (isWatching()) {
loader.setAutoLoadMore(true);
}
}
@ -131,11 +132,8 @@ public class ThreadManager implements Loader.LoaderListener {
}
public void bottomPostViewed() {
if (loader != null && loader.getLoadable().isThreadMode()) {
List<Post> posts = loader.getCachedPosts();
if (posts.size() > 0) {
loader.getLoadable().lastViewed = posts.get(posts.size() - 1).no;
}
if (loader.getLoadable().isThreadMode() && loader.getThread() != null && loader.getThread().posts.size() > 0) {
loader.getLoadable().lastViewed = loader.getThread().posts.get(loader.getThread().posts.size() - 1).no;
}
Pin pin = ChanApplication.getWatchManager().findPinByLoadable(loader.getLoadable());
@ -145,12 +143,12 @@ public class ThreadManager implements Loader.LoaderListener {
}
}
public boolean shouldWatch() {
public boolean isWatching() {
if (!loader.getLoadable().isThreadMode()) {
return false;
} else if (!ChanPreferences.getThreadAutoRefresh()) {
return false;
} else if (loader.getCachedPosts().size() > 0 && loader.getCachedPosts().get(0).closed) {
} else if (loader.getThread() != null && loader.getThread().closed) {
return false;
} else {
return true;
@ -182,16 +180,16 @@ public class ThreadManager implements Loader.LoaderListener {
}
@Override
public void onData(List<Post> result, boolean append) {
if (!shouldWatch()) {
public void onData(ChanThread thread) {
if (!isWatching()) {
loader.setAutoLoadMore(false);
}
if (result.size() > 0) {
lastPost = result.get(result.size() - 1).no;
if (thread.posts.size() > 0) {
lastPost = thread.posts.get(thread.posts.size() - 1).no;
}
threadManagerListener.onThreadLoaded(result, append);
threadManagerListener.onThreadLoaded(thread);
}
public boolean hasLoader() {
@ -578,7 +576,7 @@ public class ThreadManager implements Loader.LoaderListener {
}
public interface ThreadManagerListener {
public void onThreadLoaded(List<Post> result, boolean append);
public void onThreadLoaded(ChanThread thread);
public void onThreadLoadError(VolleyError error);

@ -0,0 +1,14 @@
package org.floens.chan.core.model;
import java.util.List;
public class ChanThread {
public List<Post> posts;
public Post op;
public boolean closed = false;
public boolean archived = false;
public ChanThread(List<Post> posts) {
this.posts = posts;
}
}

@ -22,6 +22,7 @@ import com.android.volley.VolleyError;
import org.floens.chan.ChanApplication;
import org.floens.chan.core.loader.Loader;
import org.floens.chan.core.loader.LoaderPool;
import org.floens.chan.core.model.ChanThread;
import org.floens.chan.core.model.Pin;
import org.floens.chan.core.model.Post;
import org.floens.chan.utils.Logger;
@ -124,27 +125,23 @@ public class PinWatcher implements Loader.LoaderListener {
}
@Override
public void onData(List<Post> result, boolean append) {
public void onData(ChanThread thread) {
pin.isError = false;
if (pin.thumbnailUrl == null && loader.getOP() != null && loader.getOP().hasImage) {
pin.thumbnailUrl = loader.getOP().thumbnailUrl;
}
for (Post post : result) {
post.title = pin.loadable.title;
if (pin.thumbnailUrl == null && thread.op != null && thread.op.hasImage) {
pin.thumbnailUrl = thread.op.thumbnailUrl;
}
// Populate posts list
posts.clear();
posts.addAll(result);
posts.addAll(thread.posts);
// Populate quotes list
quotes.clear();
// Get list of saved replies from this thread
List<Post> savedReplies = new ArrayList<>();
for (Post item : result) {
for (Post item : thread.posts) {
// saved.title = pin.loadable.title;
if (item.isSavedReply) {
@ -153,7 +150,7 @@ public class PinWatcher implements Loader.LoaderListener {
}
// Now get a list of posts that have a quote to a saved reply
for (Post post : result) {
for (Post post : thread.posts) {
for (Post saved : savedReplies) {
if (post.repliesTo.contains(saved.no)) {
quotes.add(post);

@ -48,6 +48,7 @@ import android.widget.ShareActionProvider;
import org.floens.chan.ChanApplication;
import org.floens.chan.R;
import org.floens.chan.core.manager.WatchManager;
import org.floens.chan.core.model.ChanThread;
import org.floens.chan.core.model.Loadable;
import org.floens.chan.core.model.Pin;
import org.floens.chan.core.model.Post;
@ -92,7 +93,7 @@ public abstract class BaseActivity extends Activity implements PanelSlideListene
abstract public void onOpenThread(Loadable thread);
abstract public void onThreadLoaded(Loadable loadable, List<Post> posts);
abstract public void onThreadLoaded(ChanThread thread);
@Override
protected void onCreate(Bundle savedInstanceState) {

@ -48,6 +48,7 @@ import org.floens.chan.core.loader.Loader;
import org.floens.chan.core.manager.BoardManager;
import org.floens.chan.core.manager.ThreadManager;
import org.floens.chan.core.model.Board;
import org.floens.chan.core.model.ChanThread;
import org.floens.chan.core.model.Loadable;
import org.floens.chan.core.model.Pin;
import org.floens.chan.core.model.Post;
@ -228,7 +229,7 @@ public class ChanActivity extends BaseActivity implements AdapterView.OnItemSele
}
@Override
public void onThreadLoaded(Loadable loadable, List<Post> posts) {
public void onThreadLoaded(ChanThread thread) {
updateActionBarState();
pinnedAdapter.notifyDataSetChanged();
}
@ -465,8 +466,8 @@ public class ChanActivity extends BaseActivity implements AdapterView.OnItemSele
case R.id.action_pin:
if (threadFragment.hasLoader()) {
Loader loader = threadFragment.getLoader();
if (loader.getCachedPosts().size() > 0) {
ChanApplication.getWatchManager().addPin(loader.getLoadable(), loader.getCachedPosts().get(0));
if (loader != null && loader.getLoadable().isThreadMode() && loader.getThread() != null) {
ChanApplication.getWatchManager().addPin(loader.getLoadable(), loader.getThread().op);
pinDrawer.openDrawer(pinDrawerView);
}
}

@ -35,6 +35,7 @@ import android.widget.TextView;
import org.floens.chan.R;
import org.floens.chan.core.loader.Loader;
import org.floens.chan.core.manager.ThreadManager;
import org.floens.chan.core.model.ChanThread;
import org.floens.chan.core.model.Loadable;
import org.floens.chan.core.model.Post;
import org.floens.chan.ui.ScrollerRunnable;
@ -72,6 +73,7 @@ public class PostAdapter extends BaseAdapter implements Filterable {
private String statusMessage = null;
private String filter = "";
private int pendingScrollToPost = -1;
private String statusPrefix = "";
public PostAdapter(Context activity, ThreadManager threadManager, AbsListView listView, PostAdapterListener listener) {
context = activity;
@ -203,38 +205,18 @@ public class PostAdapter extends BaseAdapter implements Filterable {
notifyDataSetChanged();
}
public void appendList(List<Post> list) {
public void setThread(ChanThread thread) {
synchronized (lock) {
boolean flag;
for (Post post : list) {
flag = true;
for (Post own : sourceList) {
if (post.no == own.no) {
flag = false;
break;
}
}
if (flag) {
sourceList.add(post);
}
}
if (!isFiltering()) {
displayList.clear();
displayList.addAll(sourceList);
if (thread.archived) {
statusPrefix = context.getString(R.string.thread_archived) + " - ";
} else if (thread.closed) {
statusPrefix = context.getString(R.string.thread_closed) + " - ";
} else {
setFilter(filter);
statusPrefix = "";
}
}
notifyDataSetChanged();
}
public void setList(List<Post> list) {
synchronized (lock) {
sourceList.clear();
sourceList.addAll(list);
sourceList.addAll(thread.posts);
if (!isFiltering()) {
displayList.clear();
@ -338,7 +320,7 @@ public class PostAdapter extends BaseAdapter implements Filterable {
public void init() {
Loader loader = threadManager.getLoader();
if (loader == null || loader.getLoadable() == null)
if (loader == null)
return;
setGravity(Gravity.CENTER);
@ -349,22 +331,12 @@ public class PostAdapter extends BaseAdapter implements Filterable {
if (error != null) {
setText(error);
} else {
String prefix = "";
Post op = threadManager.getLoader().getOP();
if (op != null) {
if (op.archived) {
prefix = context.getString(R.string.thread_archived) + " - ";
} else if (op.closed) {
prefix = context.getString(R.string.thread_closed) + " - ";
}
}
if (threadManager.shouldWatch()) {
if (threadManager.isWatching()) {
long time = loader.getTimeUntilLoadMore() / 1000L;
if (time == 0) {
setText(prefix + context.getString(R.string.thread_refresh_now));
setText(statusPrefix + context.getString(R.string.thread_refresh_now));
} else {
setText(prefix + context.getString(R.string.thread_refresh_countdown, time));
setText(statusPrefix + context.getString(R.string.thread_refresh_countdown, time));
}
new Handler().postDelayed(new Runnable() {
@ -377,9 +349,9 @@ public class PostAdapter extends BaseAdapter implements Filterable {
}, 1000);
} else {
if (loader.getTimeUntilLoadMore() == 0) {
setText(prefix + context.getString(R.string.thread_refresh_now));
setText(statusPrefix + context.getString(R.string.thread_refresh_now));
} else {
setText(prefix + context.getString(R.string.thread_refresh_bar_inactive));
setText(statusPrefix + context.getString(R.string.thread_refresh_bar_inactive));
}
}

@ -48,6 +48,7 @@ import org.floens.chan.R;
import org.floens.chan.core.loader.EndOfLineException;
import org.floens.chan.core.loader.Loader;
import org.floens.chan.core.manager.ThreadManager;
import org.floens.chan.core.model.ChanThread;
import org.floens.chan.core.model.Loadable;
import org.floens.chan.core.model.Post;
import org.floens.chan.ui.activity.BaseActivity;
@ -57,8 +58,6 @@ import org.floens.chan.ui.view.LoadView;
import org.floens.chan.utils.ThemeHelper;
import org.floens.chan.utils.Utils;
import java.util.List;
import javax.net.ssl.SSLException;
public class ThreadFragment extends Fragment implements ThreadManager.ThreadManagerListener, PostAdapter.PostAdapterListener {
@ -218,7 +217,7 @@ public class ThreadFragment extends Fragment implements ThreadManager.ThreadMana
}
@Override
public void onThreadLoaded(List<Post> posts, boolean append) {
public void onThreadLoaded(ChanThread thread) {
if (postAdapter == null) {
if (container != null) {
container.setView(createView());
@ -226,12 +225,7 @@ public class ThreadFragment extends Fragment implements ThreadManager.ThreadMana
}
postAdapter.setStatusMessage(null);
if (append) {
postAdapter.appendList(posts);
} else {
postAdapter.setList(posts);
}
postAdapter.setThread(thread);
if (highlightedPost >= 0) {
threadManager.highlightPost(highlightedPost);
@ -239,7 +233,7 @@ public class ThreadFragment extends Fragment implements ThreadManager.ThreadMana
highlightedPost = -1;
}
baseActivity.onThreadLoaded(loadable, posts);
baseActivity.onThreadLoaded(thread);
}
@Override

Loading…
Cancel
Save