From 57f3cbefcdd826a4dc74b9e09e3970ac36592fad Mon Sep 17 00:00:00 2001 From: Floens Date: Thu, 18 Jun 2015 18:42:10 +0200 Subject: [PATCH] Add board ordering --- .../chan/core/presenter/ThreadPresenter.java | 43 ++++++++++++- .../chan/core/settings/ChanSettings.java | 6 +- .../floens/chan/ui/adapter/PostAdapter.java | 48 +++++++++++++-- .../chan/ui/cell/PostCellInterface.java | 19 +++++- .../chan/ui/controller/BrowseController.java | 61 ++++++++++++++++++- .../floens/chan/ui/layout/ThreadLayout.java | 6 +- .../chan/ui/layout/ThreadListLayout.java | 5 +- Clover/app/src/main/res/values/strings.xml | 7 +++ 8 files changed, 176 insertions(+), 19 deletions(-) diff --git a/Clover/app/src/main/java/org/floens/chan/core/presenter/ThreadPresenter.java b/Clover/app/src/main/java/org/floens/chan/core/presenter/ThreadPresenter.java index 93674bda..68b16415 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/presenter/ThreadPresenter.java +++ b/Clover/app/src/main/java/org/floens/chan/core/presenter/ThreadPresenter.java @@ -75,6 +75,7 @@ public class ThreadPresenter implements ChanLoader.ChanLoaderCallback, PostAdapt private Loadable loadable; private ChanLoader chanLoader; private boolean searchOpen = false; + private Order order = Order.BUMP; public ThreadPresenter(ThreadPresenterCallback threadPresenterCallback) { this.threadPresenterCallback = threadPresenterCallback; @@ -108,6 +109,7 @@ public class ThreadPresenter implements ChanLoader.ChanLoaderCallback, PostAdapt LoaderPool.getInstance().release(chanLoader, this); chanLoader = null; loadable = null; + order = Order.BUMP; threadPresenterCallback.showLoading(); } @@ -163,6 +165,19 @@ public class ThreadPresenter implements ChanLoader.ChanLoaderCallback, PostAdapt } } + public void setOrder(Order order) { + if (this.order != order) { + this.order = order; + if (chanLoader != null) { + ChanThread thread = chanLoader.getThread(); + if (thread != null) { + threadPresenterCallback.scrollTo(0, false); + threadPresenterCallback.showPosts(thread, order); + } + } + } + } + @Override public Loadable getLoadable() { return loadable; @@ -182,7 +197,7 @@ public class ThreadPresenter implements ChanLoader.ChanLoaderCallback, PostAdapt } chanLoader.setAutoLoadMore(isWatching()); - threadPresenterCallback.showPosts(result); + threadPresenterCallback.showPosts(result, order); if (loadable.markedNo >= 0) { Post markedPost = findPostById(loadable.markedNo); @@ -192,7 +207,6 @@ public class ThreadPresenter implements ChanLoader.ChanLoaderCallback, PostAdapt } loadable.markedNo = -1; } - } @Override @@ -535,8 +549,31 @@ public class ThreadPresenter implements ChanLoader.ChanLoaderCallback, PostAdapt threadPresenterCallback.filterList(originalQuery, filtered, false, false, false); } + public enum Order { + BUMP("bump"), + REPLY("reply"), + IMAGE("image"), + NEWEST("newest"), + OLDEST("oldest"); + + public String name; + + Order(String storeName) { + this.name = storeName; + } + + public static Order find(String name) { + for (Order mode : Order.values()) { + if (mode.name.equals(name)) { + return mode; + } + } + return null; + } + } + public interface ThreadPresenterCallback { - void showPosts(ChanThread thread); + void showPosts(ChanThread thread, Order order); void postClicked(Post post); diff --git a/Clover/app/src/main/java/org/floens/chan/core/settings/ChanSettings.java b/Clover/app/src/main/java/org/floens/chan/core/settings/ChanSettings.java index 8716210e..17b90228 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/settings/ChanSettings.java +++ b/Clover/app/src/main/java/org/floens/chan/core/settings/ChanSettings.java @@ -23,6 +23,8 @@ import android.os.Environment; import org.floens.chan.Chan; import org.floens.chan.R; import org.floens.chan.chan.ChanUrls; +import org.floens.chan.core.presenter.ThreadPresenter; +import org.floens.chan.ui.cell.PostCellInterface; import org.floens.chan.utils.AndroidUtils; import java.io.File; @@ -37,6 +39,7 @@ public class ChanSettings { public static final BooleanSetting videoOpenExternal; public static final BooleanSetting videoErrorIgnore; public static final StringSetting boardViewMode; + public static final StringSetting boardOrder; public static final StringSetting postDefaultName; public static final BooleanSetting postPinThread; @@ -79,7 +82,8 @@ public class ChanSettings { videoAutoLoad = new BooleanSetting(p, "preference_autoplay", false); videoOpenExternal = new BooleanSetting(p, "preference_video_external", false); videoErrorIgnore = new BooleanSetting(p, "preference_video_error_ignore", false); - boardViewMode = new StringSetting(p, "preference_board_view_mode", "list"); // "list" or "grid" + boardViewMode = new StringSetting(p, "preference_board_view_mode", PostCellInterface.PostViewMode.LIST.name); // "list" or "grid" + boardOrder = new StringSetting(p, "preference_board_order", ThreadPresenter.Order.BUMP.name); postDefaultName = new StringSetting(p, "preference_default_name", ""); postPinThread = new BooleanSetting(p, "preference_pin_on_post", false); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/adapter/PostAdapter.java b/Clover/app/src/main/java/org/floens/chan/ui/adapter/PostAdapter.java index 7064270b..a4ecf40d 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/adapter/PostAdapter.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/adapter/PostAdapter.java @@ -26,21 +26,25 @@ import org.floens.chan.R; 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.presenter.ThreadPresenter; import org.floens.chan.ui.cell.PostCellInterface; import org.floens.chan.ui.cell.ThreadStatusCell; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; public class PostAdapter extends RecyclerView.Adapter { + private static final int TYPE_POST = 0; private static final int TYPE_STATUS = 1; private final PostAdapterCallback postAdapterCallback; private final PostCellInterface.PostCellCallback postCellCallback; - private final ThreadStatusCell.Callback statusCellCallback; private RecyclerView recyclerView; + private final ThreadStatusCell.Callback statusCellCallback; private final List sourceList = new ArrayList<>(); private final List displayList = new ArrayList<>(); private int lastPostCount = 0; @@ -49,6 +53,7 @@ public class PostAdapter extends RecyclerView.Adapter { private String highlightedPostId; private int highlightedPostNo = -1; private boolean filtering = false; + private PostCellInterface.PostViewMode postViewMode; public PostAdapter(RecyclerView recyclerView, PostAdapterCallback postAdapterCallback, PostCellInterface.PostCellCallback postCellCallback, ThreadStatusCell.Callback statusCellCallback) { @@ -127,10 +132,11 @@ public class PostAdapter extends RecyclerView.Adapter { } } - public void setThread(ChanThread thread) { + public void setThread(ChanThread thread, ThreadPresenter.Order order) { showError(null); sourceList.clear(); sourceList.addAll(thread.posts); + orderPosts(sourceList, order); if (!filtering) { displayList.clear(); @@ -210,6 +216,10 @@ public class PostAdapter extends RecyclerView.Adapter { notifyDataSetChanged(); } + public void setPostViewMode(PostCellInterface.PostViewMode postViewMode) { + this.postViewMode = postViewMode; + } + private void onScrolledToBottom() { if (!filtering && lastPostCount != sourceList.size()) { lastPostCount = sourceList.size(); @@ -221,8 +231,38 @@ public class PostAdapter extends RecyclerView.Adapter { return postAdapterCallback.getLoadable().isThreadMode(); } - public void setPostViewMode(PostCellInterface.PostViewMode postViewMode) { - this.postViewMode = postViewMode; + private void orderPosts(List posts, ThreadPresenter.Order order) { + if (order != ThreadPresenter.Order.BUMP) { + if (order == ThreadPresenter.Order.IMAGE) { + Collections.sort(posts, new Comparator() { + @Override + public int compare(Post lhs, Post rhs) { + return rhs.images - lhs.images; + } + }); + } else if (order == ThreadPresenter.Order.REPLY) { + Collections.sort(posts, new Comparator() { + @Override + public int compare(Post lhs, Post rhs) { + return rhs.replies - lhs.replies; + } + }); + } else if (order == ThreadPresenter.Order.NEWEST) { + Collections.sort(posts, new Comparator() { + @Override + public int compare(Post lhs, Post rhs) { + return (int) (rhs.time - lhs.time); + } + }); + } else if (order == ThreadPresenter.Order.OLDEST) { + Collections.sort(posts, new Comparator() { + @Override + public int compare(Post lhs, Post rhs) { + return (int) (lhs.time - rhs.time); + } + }); + } + } } public static class PostViewHolder extends RecyclerView.ViewHolder { diff --git a/Clover/app/src/main/java/org/floens/chan/ui/cell/PostCellInterface.java b/Clover/app/src/main/java/org/floens/chan/ui/cell/PostCellInterface.java index ddf6ba8f..34df8c56 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/cell/PostCellInterface.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/cell/PostCellInterface.java @@ -34,8 +34,23 @@ public interface PostCellInterface { ThumbnailView getThumbnailView(); enum PostViewMode { - LIST, - CARD + LIST("list"), + CARD("grid"); + + public String name; + + PostViewMode(String name) { + this.name = name; + } + + public static PostViewMode find(String name) { + for (PostViewMode mode : PostViewMode.values()) { + if (mode.name.equals(name)) { + return mode; + } + } + return null; + } } interface PostCellCallback { diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/BrowseController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/BrowseController.java index 11876450..8f1be566 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/BrowseController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/BrowseController.java @@ -32,6 +32,7 @@ import org.floens.chan.core.manager.BoardManager; import org.floens.chan.core.model.Board; import org.floens.chan.core.model.Loadable; import org.floens.chan.core.model.Pin; +import org.floens.chan.core.presenter.ThreadPresenter; import org.floens.chan.core.settings.ChanSettings; import org.floens.chan.ui.cell.PostCellInterface; import org.floens.chan.ui.layout.ThreadLayout; @@ -49,10 +50,14 @@ public class BrowseController extends ThreadController implements ToolbarMenuIte private static final int SEARCH_ID = 101; private static final int SHARE_ID = 102; private static final int VIEW_MODE_ID = 103; + private static final int ORDER_ID = 104; private PostCellInterface.PostViewMode postViewMode; + private ThreadPresenter.Order order; private List boardItems; + private FloatingMenuItem viewModeMenuItem; + private ToolbarMenuItem overflow; public BrowseController(Context context) { super(context); @@ -62,8 +67,10 @@ public class BrowseController extends ThreadController implements ToolbarMenuIte public void onCreate() { super.onCreate(); - postViewMode = ChanSettings.boardViewMode.get().equals("list") ? PostCellInterface.PostViewMode.LIST : PostCellInterface.PostViewMode.CARD; + postViewMode = PostCellInterface.PostViewMode.find(ChanSettings.boardViewMode.get()); + order = ThreadPresenter.Order.find(ChanSettings.boardOrder.get()); threadLayout.setPostViewMode(postViewMode); + threadLayout.getPresenter().setOrder(order); navigationItem.hasDrawer = true; navigationItem.middleMenu = new FloatingMenu(context); @@ -76,7 +83,7 @@ public class BrowseController extends ThreadController implements ToolbarMenuIte menu.addItem(new ToolbarMenuItem(context, this, REFRESH_ID, R.drawable.ic_refresh_white_24dp)); - ToolbarMenuItem overflow = menu.createOverflow(this); + overflow = menu.createOverflow(this); List items = new ArrayList<>(); items.add(new FloatingMenuItem(SEARCH_ID, context.getString(R.string.action_search))); @@ -84,6 +91,7 @@ public class BrowseController extends ThreadController implements ToolbarMenuIte viewModeMenuItem = new FloatingMenuItem(VIEW_MODE_ID, context.getString( postViewMode == PostCellInterface.PostViewMode.LIST ? R.string.action_switch_catalog : R.string.action_switch_board)); items.add(viewModeMenuItem); + items.add(new FloatingMenuItem(ORDER_ID, context.getString(R.string.action_order))); overflow.setSubMenu(new FloatingMenu(context, overflow.getView(), items)); } @@ -114,13 +122,60 @@ public class BrowseController extends ThreadController implements ToolbarMenuIte postViewMode = PostCellInterface.PostViewMode.LIST; } - ChanSettings.boardViewMode.set(postViewMode == PostCellInterface.PostViewMode.LIST ? "list" : "grid"); + ChanSettings.boardViewMode.set(postViewMode.name); viewModeMenuItem.setText(context.getString( postViewMode == PostCellInterface.PostViewMode.LIST ? R.string.action_switch_catalog : R.string.action_switch_board)); threadLayout.setPostViewMode(postViewMode); + break; + case ORDER_ID: + List items = new ArrayList<>(); + for (ThreadPresenter.Order order : ThreadPresenter.Order.values()) { + int nameId = 0; + switch (order) { + case BUMP: + nameId = R.string.order_bump; + break; + case REPLY: + nameId = R.string.order_reply; + break; + case IMAGE: + nameId = R.string.order_image; + break; + case NEWEST: + nameId = R.string.order_newest; + break; + case OLDEST: + nameId = R.string.order_oldest; + break; + } + + String name = string(nameId); + if (order == this.order) { + name = "\u2713 " + name; // Checkmark + } + + items.add(new FloatingMenuItem(order, name)); + } + + FloatingMenu menu = new FloatingMenu(context, overflow.getView(), items); + menu.setCallback(new FloatingMenu.FloatingMenuCallback() { + @Override + public void onFloatingMenuItemClicked(FloatingMenu menu, FloatingMenuItem item) { + ThreadPresenter.Order order = (ThreadPresenter.Order) item.getId(); + ChanSettings.boardOrder.set(order.name); + BrowseController.this.order = order; + threadLayout.getPresenter().setOrder(order); + } + + @Override + public void onFloatingMenuDismissed(FloatingMenu menu) { + } + }); + menu.show(); + break; } } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java b/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java index 8a820fa8..a4eb33b1 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java @@ -89,7 +89,6 @@ public class ThreadLayout extends CoordinatorLayout implements ThreadPresenter.T private ProgressDialog deletingDialog; private boolean refreshedFromSwipe; private boolean showingReplyButton = false; - private PostCellInterface.PostViewMode postViewMode; public ThreadLayout(Context context) { super(context); @@ -162,7 +161,6 @@ public class ThreadLayout extends CoordinatorLayout implements ThreadPresenter.T } public void setPostViewMode(PostCellInterface.PostViewMode postViewMode) { - this.postViewMode = postViewMode; threadListLayout.setPostViewMode(postViewMode); } @@ -172,8 +170,8 @@ public class ThreadLayout extends CoordinatorLayout implements ThreadPresenter.T } @Override - public void showPosts(ChanThread thread) { - threadListLayout.showPosts(thread, visible != Visible.THREAD); + public void showPosts(ChanThread thread, ThreadPresenter.Order order) { + threadListLayout.showPosts(thread, order, visible != Visible.THREAD); switchVisible(Visible.THREAD); callback.onShowPosts(); } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadListLayout.java b/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadListLayout.java index 7b871f4b..2749a32c 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadListLayout.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadListLayout.java @@ -32,6 +32,7 @@ import org.floens.chan.core.model.Loadable; import org.floens.chan.core.model.Post; import org.floens.chan.core.model.PostImage; import org.floens.chan.core.presenter.ReplyPresenter; +import org.floens.chan.core.presenter.ThreadPresenter; import org.floens.chan.ui.adapter.PostAdapter; import org.floens.chan.ui.cell.PostCell; import org.floens.chan.ui.cell.PostCellInterface; @@ -163,7 +164,7 @@ public class ThreadListLayout extends LinearLayout implements ReplyLayout.ReplyL } } - public void showPosts(ChanThread thread, boolean initial) { + public void showPosts(ChanThread thread, ThreadPresenter.Order order, boolean initial) { showingThread = thread; if (initial) { reply.bindLoadable(showingThread.loadable); @@ -194,7 +195,7 @@ public class ThreadListLayout extends LinearLayout implements ReplyLayout.ReplyL } } - postAdapter.setThread(thread); + postAdapter.setThread(thread, order); } public boolean onBack() { diff --git a/Clover/app/src/main/res/values/strings.xml b/Clover/app/src/main/res/values/strings.xml index c81f08e4..afa2cc6f 100644 --- a/Clover/app/src/main/res/values/strings.xml +++ b/Clover/app/src/main/res/values/strings.xml @@ -60,6 +60,13 @@ along with this program. If not, see . Board mode Up Down + Order + + Bump order + Reply count + Image count + Newest + Oldest Search Found %1$s for "%2$s"