diff --git a/Clover/app/src/main/java/org/floens/chan/core/ChanPreferences.java b/Clover/app/src/main/java/org/floens/chan/core/ChanPreferences.java index 724eed30..5edecc34 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/ChanPreferences.java +++ b/Clover/app/src/main/java/org/floens/chan/core/ChanPreferences.java @@ -129,4 +129,12 @@ public class ChanPreferences { public static boolean setBoardEditorFillerEnabled(boolean enabled) { return p().edit().putBoolean("preference_board_editor_filler", enabled).commit(); } + + public static String getBoardViewMode() { + return p().getString("preference_board_view_mode", "list"); + } + + public static void setBoardViewMode(String mode) { + p().edit().putString("preference_board_view_mode", mode).commit(); + } } diff --git a/Clover/app/src/main/java/org/floens/chan/core/loader/Loader.java b/Clover/app/src/main/java/org/floens/chan/core/loader/Loader.java index 2023ef86..27d8943c 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/loader/Loader.java +++ b/Clover/app/src/main/java/org/floens/chan/core/loader/Loader.java @@ -124,7 +124,7 @@ public class Loader { request.cancel(); } - if (loadable.isBoardMode()) { + if (loadable.isBoardMode() || loadable.isCatalogMode()) { loadable.no = 0; loadable.listViewIndex = 0; loadable.listViewTop = 0; diff --git a/Clover/app/src/main/java/org/floens/chan/core/manager/ThreadManager.java b/Clover/app/src/main/java/org/floens/chan/core/manager/ThreadManager.java index dce167c4..ea7a3e88 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/manager/ThreadManager.java +++ b/Clover/app/src/main/java/org/floens/chan/core/manager/ThreadManager.java @@ -63,6 +63,10 @@ import java.util.List; * etc. onDestroy, onStart and onStop must be called from the activity/fragment */ public class ThreadManager implements Loader.LoaderListener { + public static enum ViewMode { + LIST, GRID + } + private static final String TAG = "ThreadManager"; private final Activity activity; @@ -211,7 +215,7 @@ public class ThreadManager implements Loader.LoaderListener { } public void onPostClicked(Post post) { - if (loader != null && loader.getLoadable().isBoardMode()) { + if (loader != null && (loader.getLoadable().isBoardMode() || loader.getLoadable().isCatalogMode())) { threadManagerListener.onOPClicked(post); } } @@ -219,6 +223,10 @@ public class ThreadManager implements Loader.LoaderListener { public void showPostOptions(final Post post, PopupMenu popupMenu) { Menu menu = popupMenu.getMenu(); + if (loader.getLoadable().isBoardMode() || loader.getLoadable().isCatalogMode()) { + menu.add(Menu.NONE, 8, Menu.NONE, activity.getString(R.string.action_pin)); + } + String[] baseOptions = activity.getResources().getStringArray(R.array.post_options); for (int i = 0; i < baseOptions.length; i++) { menu.add(Menu.NONE, i, Menu.NONE, baseOptions[i]); @@ -266,6 +274,11 @@ public class ThreadManager implements Loader.LoaderListener { case 7: // Save reply ChanApplication.getDatabaseManager().saveReply(new SavedReply(post.board, post.no, "foo")); break; + case 8: // Pin + Pin pin = new Pin(); + pin.loadable = new Loadable(loader.getLoadable().board, post.no, WatchManager.generateTitle(post)); + ChanApplication.getWatchManager().addPin(pin); + break; } return false; } @@ -395,6 +408,10 @@ public class ThreadManager implements Loader.LoaderListener { } } + public ThreadManager.ViewMode getViewMode() { + return threadManagerListener.getViewMode(); + } + /** * Handle when a linkable has been clicked. * @@ -559,6 +576,8 @@ public class ThreadManager implements Loader.LoaderListener { public void onRefreshView(); public void onOpenThread(Loadable thread, int highlightedPost); + + public ThreadManager.ViewMode getViewMode(); } public static class RepliesPopup { diff --git a/Clover/app/src/main/java/org/floens/chan/core/manager/WatchManager.java b/Clover/app/src/main/java/org/floens/chan/core/manager/WatchManager.java index 290ae145..90dcce08 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/manager/WatchManager.java +++ b/Clover/app/src/main/java/org/floens/chan/core/manager/WatchManager.java @@ -19,11 +19,13 @@ package org.floens.chan.core.manager; import android.content.Context; import android.content.Intent; +import android.text.TextUtils; import org.floens.chan.ChanApplication; import org.floens.chan.core.ChanPreferences; import org.floens.chan.core.model.Loadable; import org.floens.chan.core.model.Pin; +import org.floens.chan.core.model.Post; import org.floens.chan.ui.service.WatchNotifier; import org.floens.chan.utils.Logger; import org.floens.chan.utils.Utils; @@ -46,6 +48,16 @@ public class WatchManager implements ChanApplication.ForegroundChangedListener { private ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); private PendingTimer pendingTimer; + public static String generateTitle(Post post) { + if (!TextUtils.isEmpty(post.subject)) { + return post.subject; + } else if (!TextUtils.isEmpty(post.comment)) { + return post.comment.subSequence(0, Math.min(post.comment.length(), 100)).toString(); + } else { + return "/" + post.board + "/" + post.no; + } + } + public WatchManager(Context context) { this.context = context; diff --git a/Clover/app/src/main/java/org/floens/chan/ui/ScrollerRunnable.java b/Clover/app/src/main/java/org/floens/chan/ui/ScrollerRunnable.java index 93c082d8..d70e12c8 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/ScrollerRunnable.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/ScrollerRunnable.java @@ -19,6 +19,7 @@ package org.floens.chan.ui; import android.view.View; import android.view.ViewConfiguration; +import android.widget.AbsListView; import android.widget.ListView; public class ScrollerRunnable implements Runnable { @@ -27,7 +28,7 @@ public class ScrollerRunnable implements Runnable { private static final int MOVE_DOWN_POS = 1; private static final int MOVE_UP_POS = 2; - private final ListView mList; + private final AbsListView mList; private int mMode; private int mTargetPos; @@ -35,7 +36,7 @@ public class ScrollerRunnable implements Runnable { private int mScrollDuration; private final int mExtraScroll; - public ScrollerRunnable(ListView listView) { + public ScrollerRunnable(AbsListView listView) { mList = listView; mExtraScroll = ViewConfiguration.get(mList.getContext()).getScaledFadingEdgeLength(); } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/activity/BoardActivity.java b/Clover/app/src/main/java/org/floens/chan/ui/activity/BoardActivity.java index 34d8c2d9..56986910 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/activity/BoardActivity.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/activity/BoardActivity.java @@ -45,6 +45,8 @@ import org.floens.chan.ChanApplication; import org.floens.chan.R; import org.floens.chan.chan.ChanUrls; import org.floens.chan.core.ChanPreferences; +import org.floens.chan.core.manager.ThreadManager; +import org.floens.chan.core.manager.WatchManager; import org.floens.chan.core.model.Loadable; import org.floens.chan.core.model.Pin; import org.floens.chan.core.model.Post; @@ -74,6 +76,8 @@ public class BoardActivity extends BaseActivity implements AdapterView.OnItemSel threadLoadable = new Loadable(); boardFragment = ThreadFragment.newInstance(this); + setBoardFragmentViewMode(); + threadFragment = ThreadFragment.newInstance(this); FragmentTransaction ft = getFragmentManager().beginTransaction(); @@ -210,7 +214,7 @@ public class BoardActivity extends BaseActivity implements AdapterView.OnItemSel @Override public void onOPClicked(Post post) { - startLoadingThread(new Loadable(post.board, post.no, generateTitle(post))); + startLoadingThread(new Loadable(post.board, post.no, WatchManager.generateTitle(post))); } @Override @@ -221,7 +225,7 @@ public class BoardActivity extends BaseActivity implements AdapterView.OnItemSel @Override public void onThreadLoaded(Loadable loadable, List posts) { if (loadable.isThreadMode() && TextUtils.isEmpty(threadLoadable.title) && posts.size() > 0) { - threadLoadable.title = generateTitle(posts.get(0)); + threadLoadable.title = WatchManager.generateTitle(posts.get(0)); updateActionBarState(); } } @@ -344,7 +348,7 @@ public class BoardActivity extends BaseActivity implements AdapterView.OnItemSel actionBar.setTitle(""); pinDrawerListener.setDrawerIndicatorEnabled(true); - if (boardLoadable.isBoardMode()) + if (boardLoadable.isBoardMode() || boardLoadable.isCatalogMode()) setShareUrl(ChanUrls.getBoardUrlDesktop(boardLoadable.board)); } else { actionBar.setDisplayShowCustomEnabled(false); @@ -385,6 +389,14 @@ public class BoardActivity extends BaseActivity implements AdapterView.OnItemSel setMenuItemEnabled(menu.findItem(R.id.action_reply), slidable); setMenuItemEnabled(menu.findItem(R.id.action_reply_tablet), !slidable); + setMenuItemEnabled(menu.findItem(R.id.action_board_view_mode), !slidable || open); + + if (ChanPreferences.getBoardViewMode().equals("list")) { + menu.findItem(R.id.action_board_view_mode_list).setChecked(true); + } else if (ChanPreferences.getBoardViewMode().equals("grid")) { + menu.findItem(R.id.action_board_view_mode_grid).setChecked(true); + } + return super.onPrepareOptionsMenu(menu); } @@ -445,6 +457,20 @@ public class BoardActivity extends BaseActivity implements AdapterView.OnItemSel } } + return true; + case R.id.action_board_view_mode_grid: + if (!ChanPreferences.getBoardViewMode().equals("grid")) { + ChanPreferences.setBoardViewMode("grid"); + setBoardFragmentViewMode(); + startLoadingBoard(boardLoadable); + } + return true; + case R.id.action_board_view_mode_list: + if (!ChanPreferences.getBoardViewMode().equals("list")) { + ChanPreferences.setBoardViewMode("list"); + setBoardFragmentViewMode(); + startLoadingBoard(boardLoadable); + } return true; case android.R.id.home: threadPane.openPane(); @@ -472,6 +498,9 @@ public class BoardActivity extends BaseActivity implements AdapterView.OnItemSel boardLoadable = loadable; + // TODO: make this an option + boardLoadable.mode = Loadable.Mode.CATALOG; + boardFragment.bindLoadable(loadable); boardFragment.requestData(); @@ -553,13 +582,11 @@ public class BoardActivity extends BaseActivity implements AdapterView.OnItemSel }).setCancelable(false).create().show(); } - private String generateTitle(Post post) { - if (!TextUtils.isEmpty(post.subject)) { - return post.subject; - } else if (!TextUtils.isEmpty(post.comment)) { - return post.comment.subSequence(0, Math.min(post.comment.length(), 100)).toString(); - } else { - return "/" + post.board + "/" + post.no; + private void setBoardFragmentViewMode() { + if (ChanPreferences.getBoardViewMode().equals("list")) { + boardFragment.setViewMode(ThreadManager.ViewMode.LIST); + } else if (ChanPreferences.getBoardViewMode().equals("grid")) { + boardFragment.setViewMode(ThreadManager.ViewMode.GRID); } } 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 7b9003d0..a6ca0e5f 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 @@ -21,8 +21,8 @@ import android.content.Context; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; +import android.widget.AbsListView; import android.widget.BaseAdapter; -import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; @@ -41,14 +41,14 @@ import java.util.List; public class PostAdapter extends BaseAdapter { private final Context context; private final ThreadManager threadManager; - private final ListView listView; + private final AbsListView listView; private boolean endOfLine; private final List postList = new ArrayList<>(); private int lastPostCount = 0; private long lastViewedTime = 0; private String loadMessage = null; - public PostAdapter(Context activity, ThreadManager threadManager, ListView listView) { + public PostAdapter(Context activity, ThreadManager threadManager, AbsListView listView) { context = activity; this.threadManager = threadManager; this.listView = listView; diff --git a/Clover/app/src/main/java/org/floens/chan/ui/fragment/ReplyFragment.java b/Clover/app/src/main/java/org/floens/chan/ui/fragment/ReplyFragment.java index ae6826ac..5e336b5e 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/fragment/ReplyFragment.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/fragment/ReplyFragment.java @@ -477,7 +477,7 @@ public class ReplyFragment extends DialogFragment { } } - draft.resto = loadable.isBoardMode() ? -1 : loadable.no; + draft.resto = loadable.isThreadMode() ? loadable.no : -1; draft.board = loadable.board; if (ChanPreferences.getPassEnabled()) { diff --git a/Clover/app/src/main/java/org/floens/chan/ui/fragment/ThreadFragment.java b/Clover/app/src/main/java/org/floens/chan/ui/fragment/ThreadFragment.java index 289e5338..6edae5c6 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/fragment/ThreadFragment.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/fragment/ThreadFragment.java @@ -26,6 +26,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; +import android.widget.GridView; import android.widget.ImageView; import android.widget.ListView; import android.widget.RelativeLayout; @@ -56,10 +57,11 @@ public class ThreadFragment extends Fragment implements ThreadManager.ThreadMana private PostAdapter postAdapter; private LoadView container; - private ListView listView; + private AbsListView listView; private ImageView skip; private SkipLogic skipLogic; private int highlightedPost = -1; + private ThreadManager.ViewMode viewMode = ThreadManager.ViewMode.LIST; public static ThreadFragment newInstance(BaseActivity activity) { ThreadFragment fragment = new ThreadFragment(); @@ -100,6 +102,10 @@ public class ThreadFragment extends Fragment implements ThreadManager.ThreadMana return threadManager.hasLoader(); } + public void setViewMode(ThreadManager.ViewMode viewMode) { + this.viewMode = viewMode; + } + @Override public void onDestroy() { super.onDestroy(); @@ -136,16 +142,68 @@ public class ThreadFragment extends Fragment implements ThreadManager.ThreadMana } @Override - public void onThreadLoaded(List posts, boolean append) { + public void onOPClicked(Post post) { + baseActivity.onOPClicked(post); + } + + @Override + public void onThumbnailClicked(Post source) { + if (postAdapter != null) { + ImageViewActivity.setAdapter(postAdapter, source.no); + + Intent intent = new Intent(baseActivity, ImageViewActivity.class); + baseActivity.startActivity(intent); + baseActivity.overridePendingTransition(R.anim.fade_in, R.anim.fade_out); + } + } + + @Override + public void onScrollTo(int post) { + if (postAdapter != null) { + postAdapter.scrollToPost(post); + } + } + + @Override + public void onRefreshView() { + if (postAdapter != null) { + postAdapter.notifyDataSetChanged(); + } + } + + @Override + public void onOpenThread(final Loadable thread, int highlightedPost) { + baseActivity.onOpenThread(thread); + this.highlightedPost = highlightedPost; + } + + @Override + public ThreadManager.ViewMode getViewMode() { + return viewMode; + } + + @Override + public void onThreadLoaded(List posts, boolean append) { if (postAdapter == null) { RelativeLayout compound = new RelativeLayout(baseActivity); - listView = new ListView(baseActivity); - - postAdapter = new PostAdapter(baseActivity, threadManager, listView); - listView.setLayoutParams(Utils.MATCH_PARAMS); - listView.setAdapter(postAdapter); - listView.setSelectionFromTop(loadable.listViewIndex, loadable.listViewTop); + if (viewMode == ThreadManager.ViewMode.LIST) { + ListView list = new ListView(baseActivity); + listView = list; + postAdapter = new PostAdapter(baseActivity, threadManager, listView); + listView.setAdapter(postAdapter); + list.setSelectionFromTop(loadable.listViewIndex, loadable.listViewTop); + } else if (viewMode == ThreadManager.ViewMode.GRID) { + GridView grid = new GridView(baseActivity); + grid.setNumColumns(GridView.AUTO_FIT); + grid.setColumnWidth(baseActivity.getResources().getDimensionPixelSize(R.dimen.post_grid_width)); + grid.setVerticalSpacing(baseActivity.getResources().getDimensionPixelSize(R.dimen.post_grid_spacing)); + grid.setHorizontalSpacing(baseActivity.getResources().getDimensionPixelSize(R.dimen.post_grid_spacing)); + listView = grid; + postAdapter = new PostAdapter(baseActivity, threadManager, listView); + listView.setAdapter(postAdapter); + listView.setSelection(loadable.listViewIndex); + } listView.setOnScrollListener(new OnScrollListener() { @Override @@ -168,7 +226,7 @@ public class ThreadFragment extends Fragment implements ThreadManager.ThreadMana } }); - compound.addView(listView); + compound.addView(listView, Utils.MATCH_PARAMS); if (loadable.isThreadMode()) { skip = new ImageView(baseActivity); @@ -207,22 +265,6 @@ public class ThreadFragment extends Fragment implements ThreadManager.ThreadMana baseActivity.onThreadLoaded(loadable, posts); } - private void setEmpty() { - postAdapter = null; - - if (container != null) { - container.setView(null); - } - - if (listView != null) { - listView.setOnScrollListener(null); - listView = null; - } - - skip = null; - skipLogic = null; - } - @Override public void onThreadLoadError(VolleyError error) { if (error instanceof EndOfLineException) { @@ -240,6 +282,22 @@ public class ThreadFragment extends Fragment implements ThreadManager.ThreadMana highlightedPost = -1; } + private void setEmpty() { + postAdapter = null; + + if (container != null) { + container.setView(null); + } + + if (listView != null) { + listView.setOnScrollListener(null); + listView = null; + } + + skip = null; + skipLogic = null; + } + /** * Returns an TextView containing the appropriate error message * @@ -272,42 +330,6 @@ public class ThreadFragment extends Fragment implements ThreadManager.ThreadMana return errorMessage; } - @Override - public void onOPClicked(Post post) { - baseActivity.onOPClicked(post); - } - - @Override - public void onThumbnailClicked(Post source) { - if (postAdapter != null) { - ImageViewActivity.setAdapter(postAdapter, source.no); - - Intent intent = new Intent(baseActivity, ImageViewActivity.class); - baseActivity.startActivity(intent); - baseActivity.overridePendingTransition(R.anim.fade_in, R.anim.fade_out); - } - } - - @Override - public void onScrollTo(int post) { - if (postAdapter != null) { - postAdapter.scrollToPost(post); - } - } - - @Override - public void onRefreshView() { - if (postAdapter != null) { - postAdapter.notifyDataSetChanged(); - } - } - - @Override - public void onOpenThread(final Loadable thread, int highlightedPost) { - baseActivity.onOpenThread(thread); - this.highlightedPost = highlightedPost; - } - private static class SkipLogic { private final ImageView skip; private int lastFirstVisibleItem; diff --git a/Clover/app/src/main/java/org/floens/chan/ui/view/PostView.java b/Clover/app/src/main/java/org/floens/chan/ui/view/PostView.java index a3839809..d8436d8c 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/view/PostView.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/view/PostView.java @@ -34,6 +34,7 @@ import android.text.style.ClickableSpan; import android.text.style.ForegroundColorSpan; import android.text.style.UnderlineSpan; import android.util.AttributeSet; +import android.util.TypedValue; import android.view.MotionEvent; import android.view.View; import android.widget.ImageView; @@ -72,12 +73,12 @@ public class PostView extends LinearLayout implements View.OnClickListener { private boolean isBuild = false; private LinearLayout full; - private LinearLayout right; + private LinearLayout contentContainer; private CustomNetworkImageView imageView; private TextView titleView; private TextView commentView; private TextView repliesCountView; - private LinearLayout iconView; + private LinearLayout iconsView; private ImageView stickyView; private ImageView closedView; private NetworkImageView countryView; @@ -126,6 +127,7 @@ public class PostView extends LinearLayout implements View.OnClickListener { public void setPost(final Post post, final ThreadManager manager) { this.post = post; this.manager = manager; + boolean boardCatalogMode = manager.getLoadable().isBoardMode() || manager.getLoadable().isCatalogMode(); post.setLinkableListener(null); @@ -147,34 +149,45 @@ public class PostView extends LinearLayout implements View.OnClickListener { CharSequence total = new SpannableString(""); if (post.subjectSpan != null) { - total = TextUtils.concat(total, post.subjectSpan, "\n"); + total = TextUtils.concat(total, post.subjectSpan); } - if (post.nameSpan != null) { - total = TextUtils.concat(total, post.nameSpan, " "); - } + if (isList()) { + if (post.subjectSpan != null) { + total = TextUtils.concat(total, "\n"); + } - if (post.tripcodeSpan != null) { - total = TextUtils.concat(total, post.tripcodeSpan, " "); - } + if (post.nameSpan != null) { + total = TextUtils.concat(total, post.nameSpan, " "); + } - if (post.idSpan != null) { - total = TextUtils.concat(total, post.idSpan, " "); - } + if (post.tripcodeSpan != null) { + total = TextUtils.concat(total, post.tripcodeSpan, " "); + } - if (post.capcodeSpan != null) { - total = TextUtils.concat(total, post.capcodeSpan, " "); - } + if (post.idSpan != null) { + total = TextUtils.concat(total, post.idSpan, " "); + } - CharSequence relativeTime = DateUtils.getRelativeTimeSpanString(post.time * 1000L, Time.get(), - DateUtils.SECOND_IN_MILLIS, 0); + if (post.capcodeSpan != null) { + total = TextUtils.concat(total, post.capcodeSpan, " "); + } - SpannableString date = new SpannableString("No." + post.no + " " + relativeTime); - date.setSpan(new ForegroundColorSpan(dateColor), 0, date.length(), 0); - date.setSpan(new AbsoluteSizeSpan(10, true), 0, date.length(), 0); - total = TextUtils.concat(total, date, " "); + CharSequence relativeTime = DateUtils.getRelativeTimeSpanString(post.time * 1000L, Time.get(), + DateUtils.SECOND_IN_MILLIS, 0); - titleView.setText(total); + SpannableString date = new SpannableString("No." + post.no + " " + relativeTime); + date.setSpan(new ForegroundColorSpan(dateColor), 0, date.length(), 0); + date.setSpan(new AbsoluteSizeSpan(10, true), 0, date.length(), 0); + total = TextUtils.concat(total, date, " "); + } + + if (!TextUtils.isEmpty(total)) { + titleView.setText(total); + titleView.setVisibility(View.VISIBLE); + } else { + titleView.setVisibility(View.GONE); + } if (!TextUtils.isEmpty(post.comment)) { commentView.setVisibility(View.VISIBLE); @@ -189,36 +202,28 @@ public class PostView extends LinearLayout implements View.OnClickListener { if (manager.getLoadable().isThreadMode()) { post.setLinkableListener(this); } - - if (manager.getLoadable().isBoardMode()) { - int maxHeight = context.getResources().getDimensionPixelSize(R.dimen.post_max_height); - commentView.setMaxHeight(maxHeight); - } else { - commentView.setMaxHeight(10000); - } } else { commentView.setVisibility(View.GONE); commentView.setText(""); commentView.setOnClickListener(null); - commentView.setOnLongClickListener(null); post.setLinkableListener(null); } - if ((post.isOP && manager.getLoadable().isBoardMode() && post.replies > 0) || (post.repliesFrom.size() > 0)) { + if (isGrid() || ((post.isOP && boardCatalogMode && post.replies > 0) || (post.repliesFrom.size() > 0))) { repliesCountView.setVisibility(View.VISIBLE); String text = ""; - int count = manager.getLoadable().isBoardMode() ? post.replies : post.repliesFrom.size(); + int count = boardCatalogMode ? post.replies : post.repliesFrom.size(); - if (count > 1) { + if (count != 1) { text = count + " " + context.getString(R.string.multiple_replies); } else if (count == 1) { text = count + " " + context.getString(R.string.one_reply); } - if (manager.getLoadable().isBoardMode() && post.images > 0) { - if (post.images > 1) { + if (boardCatalogMode && post.images > 0) { + if (post.images != 1) { text += ", " + post.images + " " + context.getString(R.string.multiple_images); } else { text += ", " + post.images + " " + context.getString(R.string.one_image); @@ -240,11 +245,11 @@ public class PostView extends LinearLayout implements View.OnClickListener { repliesCountView.setOnClickListener(null); } - boolean showCountryFlag = !TextUtils.isEmpty(post.country); - boolean showStickyIcon = post.sticky; - boolean showClosedIcon = post.closed; + boolean showCountryFlag = isList() && !TextUtils.isEmpty(post.country); + boolean showStickyIcon = isList() && post.sticky; + boolean showClosedIcon = isList() && post.closed; - iconView.setVisibility((showCountryFlag || showStickyIcon || showClosedIcon) ? View.VISIBLE : View.GONE); + iconsView.setVisibility((showCountryFlag || showStickyIcon || showClosedIcon) ? View.VISIBLE : View.GONE); stickyView.setVisibility(showStickyIcon ? View.VISIBLE : View.GONE); closedView.setVisibility(showClosedIcon ? View.VISIBLE : View.GONE); @@ -269,10 +274,6 @@ public class PostView extends LinearLayout implements View.OnClickListener { } else { lastSeen.setVisibility(View.GONE); } - - if (manager.getLoadable().isBoardMode()) { - Utils.setPressedDrawable(right); - } } private void init() { @@ -341,19 +342,47 @@ public class PostView extends LinearLayout implements View.OnClickListener { isBuild = true; Resources resources = context.getResources(); - int postPadding = resources.getDimensionPixelSize(R.dimen.post_padding); - int commentPadding = resources.getDimensionPixelSize(R.dimen.post_comment_padding); + int postPadding = 0; + if (isList()) { + postPadding = resources.getDimensionPixelSize(R.dimen.post_padding); + } else if (isGrid()) { + postPadding = resources.getDimensionPixelSize(R.dimen.post_padding_grid); + } + int commentPadding = 0; + if (isList()) { + commentPadding = resources.getDimensionPixelSize(R.dimen.post_comment_padding); + } else if (isGrid()) { + commentPadding = resources.getDimensionPixelSize(R.dimen.post_comment_padding_grid); + } int iconPadding = resources.getDimensionPixelSize(R.dimen.post_icon_padding); int iconWidth = resources.getDimensionPixelSize(R.dimen.post_icon_width); int iconHeight = resources.getDimensionPixelSize(R.dimen.post_icon_height); int imageSize = resources.getDimensionPixelSize(R.dimen.thumbnail_size); + int gridHeight = resources.getDimensionPixelSize(R.dimen.post_grid_height); + int gridImageHeight = resources.getDimensionPixelSize(R.dimen.post_grid_image_height); + + int postCommentSize = 0; + if (isList()) { + postCommentSize = resources.getDimensionPixelSize(R.dimen.post_comment_text); + } else if (isGrid()) { + postCommentSize = resources.getDimensionPixelSize(R.dimen.post_comment_text_grid); + } RelativeLayout wrapper = new RelativeLayout(context); wrapper.setLayoutParams(matchParams); full = new LinearLayout(context); - full.setOrientation(HORIZONTAL); - wrapper.addView(full, matchParams); + if (isList()) { + full.setOrientation(HORIZONTAL); + wrapper.addView(full, matchParams); + } else if (isGrid()) { + full.setOrientation(VERTICAL); + wrapper.addView(full, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, gridHeight)); + } + + LinearLayout imageContainer = new LinearLayout(context); + imageContainer.setOrientation(VERTICAL); + imageContainer.setBackgroundColor(thumbnailBackground); // Create thumbnail imageView = new CustomNetworkImageView(context); @@ -367,70 +396,97 @@ public class PostView extends LinearLayout implements View.OnClickListener { } }); - LinearLayout left = new LinearLayout(context); - left.setOrientation(VERTICAL); - left.setBackgroundColor(thumbnailBackground); - - left.addView(imageView, new LinearLayout.LayoutParams(imageSize, imageSize)); + if (isList()) { + imageContainer.addView(imageView, new LinearLayout.LayoutParams(imageSize, imageSize)); + full.addView(imageContainer, wrapMatchParams); + full.setMinimumHeight(imageSize); + } else if (isGrid()) { + imageContainer.addView(imageView, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, gridImageHeight)); + full.addView(imageContainer, matchWrapParams); + } - full.addView(left, wrapMatchParams); - full.setMinimumHeight(imageSize); + contentContainer = new LinearLayout(context); + contentContainer.setOrientation(VERTICAL); - right = new LinearLayout(context); - right.setOrientation(VERTICAL); + LinearLayout titleContainer = new LinearLayout(context); + titleContainer.setOrientation(HORIZONTAL); - LinearLayout header = new LinearLayout(context); - header.setOrientation(HORIZONTAL); - // 25 padding to give optionsView some space - header.setPadding(0, 0, Utils.dp(25), 0); + if (isList()) { + // 25 padding to give optionsView some space + titleContainer.setPadding(0, 0, Utils.dp(25), 0); + } titleView = new TextView(context); titleView.setTextSize(14); titleView.setPadding(postPadding, postPadding, postPadding, 0); - header.addView(titleView, wrapParams); - right.addView(header, matchWrapParams); + titleContainer.addView(titleView, wrapParams); + + contentContainer.addView(titleContainer, matchWrapParams); - iconView = new LinearLayout(context); - iconView.setOrientation(HORIZONTAL); - iconView.setPadding(postPadding, iconPadding, postPadding, 0); + iconsView = new LinearLayout(context); + iconsView.setOrientation(HORIZONTAL); + iconsView.setPadding(postPadding, iconPadding, postPadding, 0); stickyView = new ImageView(context); stickyView.setImageBitmap(IconCache.stickyIcon); - iconView.addView(stickyView, new LinearLayout.LayoutParams(iconWidth, iconHeight)); + iconsView.addView(stickyView, new LinearLayout.LayoutParams(iconWidth, iconHeight)); closedView = new ImageView(context); closedView.setImageBitmap(IconCache.closedIcon); - iconView.addView(closedView, new LinearLayout.LayoutParams(iconWidth, iconHeight)); + iconsView.addView(closedView, new LinearLayout.LayoutParams(iconWidth, iconHeight)); countryView = new NetworkImageView(context); countryView.setScaleType(ImageView.ScaleType.FIT_CENTER); - iconView.addView(countryView, new LinearLayout.LayoutParams(iconWidth, iconHeight)); + iconsView.addView(countryView, new LinearLayout.LayoutParams(iconWidth, iconHeight)); - right.addView(iconView, matchWrapParams); + contentContainer.addView(iconsView, matchWrapParams); commentView = new TextView(context); - commentView.setTextSize(15); - commentView.setPadding(postPadding, commentPadding, postPadding, commentPadding); - right.addView(commentView, matchWrapParams); + commentView.setTextSize(TypedValue.COMPLEX_UNIT_PX, postCommentSize); - repliesCountView = new TextView(context); + if (isList()) { + commentView.setPadding(postPadding, commentPadding, postPadding, commentPadding); - // Set the drawable before the padding, because setting the background resets the padding - // This behavior differs with 4.4 / 4.1 - Utils.setPressedDrawable(repliesCountView); + if (manager.getLoadable().isBoardMode() || manager.getLoadable().isCatalogMode()) { + int maxHeight = context.getResources().getDimensionPixelSize(R.dimen.post_max_height); + commentView.setMaxHeight(maxHeight); + } + } else if (isGrid()) { + commentView.setPadding(postPadding, commentPadding, postPadding, 0); + // So that is fills up all the height using weight later on + commentView.setMinHeight(10000); + commentView.setEllipsize(TextUtils.TruncateAt.END); + } + if (isList()) { + contentContainer.addView(commentView, matchWrapParams); + } else if (isGrid()) { + contentContainer.addView(commentView, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 0, 1f)); + } + + repliesCountView = new TextView(context); + Utils.setPressedDrawable(repliesCountView); repliesCountView.setTextColor(replyCountColor); repliesCountView.setPadding(postPadding, postPadding, postPadding, postPadding); - repliesCountView.setTextSize(14); + if (isList()) { + repliesCountView.setTextSize(14); + } else if (isGrid()) { + repliesCountView.setTextSize(11); + } + repliesCountView.setSingleLine(); - right.addView(repliesCountView, wrapParams); + contentContainer.addView(repliesCountView, wrapParams); lastSeen = new View(context); lastSeen.setBackgroundColor(0xffff0000); - right.addView(lastSeen, new LayoutParams(LayoutParams.MATCH_PARENT, Utils.dp(6f))); + contentContainer.addView(lastSeen, new LayoutParams(LayoutParams.MATCH_PARENT, Utils.dp(6f))); - full.addView(right, matchWrapParams); + if (!manager.getLoadable().isThreadMode()) { + Utils.setPressedDrawable(contentContainer); + } + + full.addView(contentContainer, matchWrapParams); optionsView = new ImageView(context); optionsView.setImageResource(R.drawable.ic_overflow); @@ -478,6 +534,14 @@ public class PostView extends LinearLayout implements View.OnClickListener { manager.onPostClicked(post); } + private boolean isList() { + return manager.getViewMode() == ThreadManager.ViewMode.LIST; + } + + private boolean isGrid() { + return manager.getViewMode() == ThreadManager.ViewMode.GRID; + } + private class PostViewMovementMethod extends LinkMovementMethod { @Override public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) { diff --git a/Clover/app/src/main/java/org/floens/chan/ui/view/ThreadWatchCounterView.java b/Clover/app/src/main/java/org/floens/chan/ui/view/ThreadWatchCounterView.java index 2cc776db..1481ff81 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/view/ThreadWatchCounterView.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/view/ThreadWatchCounterView.java @@ -21,7 +21,7 @@ import android.content.Context; import android.os.Handler; import android.util.AttributeSet; import android.view.View; -import android.widget.ListView; +import android.widget.AbsListView; import android.widget.TextView; import org.floens.chan.core.loader.Loader; @@ -45,7 +45,7 @@ public class ThreadWatchCounterView extends TextView implements View.OnClickList super(activity, attbs, style); } - public void init(final ThreadManager threadManager, final ListView listView, final PostAdapter adapter) { + public void init(final ThreadManager threadManager, final AbsListView listView, final PostAdapter adapter) { tm = threadManager; ad = adapter; diff --git a/Clover/app/src/main/res/menu/base.xml b/Clover/app/src/main/res/menu/base.xml index 1ccf0d60..a51d47c5 100644 --- a/Clover/app/src/main/res/menu/base.xml +++ b/Clover/app/src/main/res/menu/base.xml @@ -91,6 +91,23 @@ along with this program. If not, see . android:showAsAction="never" android:title="@string/action_open_browser"/> + + + + + + + + + . 12dp 10dp + 5dp 11dp + 8dp 6dp - 70dp 24dp 14dp 200dp - + 110dp + 300dp + 120dp + 15sp + 14sp + 1dp 8dp diff --git a/Clover/app/src/main/res/values/strings.xml b/Clover/app/src/main/res/values/strings.xml index 4520d1fb..38a7b86a 100644 --- a/Clover/app/src/main/res/values/strings.xml +++ b/Clover/app/src/main/res/values/strings.xml @@ -35,9 +35,11 @@ along with this program. If not, see . Reply to board Reply to thread Open in browser - Open catalog Share Download album + View mode + List + Grid Unsupported link Clover can\'t open this link. Opening it in your browser instead.