Added grid view

You can now for the board pane choose between list view and grid view.
Also boards are now loaded with the mode.catalog option, there's almost no difference now between the speed of paged mode vs catalog mode.
This will later on be an option. (if people complain about speed)
captchafix
Florens Douwes 11 years ago
parent a36dadf9ac
commit 1887082480
  1. 8
      Clover/app/src/main/java/org/floens/chan/core/ChanPreferences.java
  2. 2
      Clover/app/src/main/java/org/floens/chan/core/loader/Loader.java
  3. 21
      Clover/app/src/main/java/org/floens/chan/core/manager/ThreadManager.java
  4. 12
      Clover/app/src/main/java/org/floens/chan/core/manager/WatchManager.java
  5. 5
      Clover/app/src/main/java/org/floens/chan/ui/ScrollerRunnable.java
  6. 47
      Clover/app/src/main/java/org/floens/chan/ui/activity/BoardActivity.java
  7. 6
      Clover/app/src/main/java/org/floens/chan/ui/adapter/PostAdapter.java
  8. 2
      Clover/app/src/main/java/org/floens/chan/ui/fragment/ReplyFragment.java
  9. 144
      Clover/app/src/main/java/org/floens/chan/ui/fragment/ThreadFragment.java
  10. 224
      Clover/app/src/main/java/org/floens/chan/ui/view/PostView.java
  11. 4
      Clover/app/src/main/java/org/floens/chan/ui/view/ThreadWatchCounterView.java
  12. 17
      Clover/app/src/main/res/menu/base.xml
  13. 10
      Clover/app/src/main/res/values/dimens.xml
  14. 4
      Clover/app/src/main/res/values/strings.xml

@ -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();
}
}

@ -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;

@ -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 {

@ -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;

@ -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();
}

@ -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<Post> 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);
}
}

@ -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<Post> 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;

@ -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()) {

@ -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<Post> 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;

@ -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) {

@ -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;

@ -91,6 +91,23 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
android:showAsAction="never"
android:title="@string/action_open_browser"/>
<item
android:id="@+id/action_board_view_mode"
android:orderInCategory="8"
android:showAsAction="never"
android:title="@string/action_board_view_mode">
<menu>
<group android:checkableBehavior="single">
<item
android:id="@+id/action_board_view_mode_list"
android:title="@string/action_board_view_mode_list"/>
<item
android:id="@+id/action_board_view_mode_grid"
android:title="@string/action_board_view_mode_grid"/>
</group>
</menu>
</item>
<item
android:id="@+id/action_settings"
android:orderInCategory="100"

@ -20,13 +20,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<dimen name="general_padding">12dp</dimen>
<dimen name="post_padding">10dp</dimen>
<dimen name="post_padding_grid">5dp</dimen>
<dimen name="post_comment_padding">11dp</dimen>
<dimen name="post_comment_padding_grid">8dp</dimen>
<dimen name="post_icon_padding">6dp</dimen>
<dimen name="thumbnail_size">70dp</dimen>
<dimen name="post_icon_width">24dp</dimen>
<dimen name="post_icon_height">14dp</dimen>
<dimen name="post_max_height">200dp</dimen>
<dimen name="post_grid_width">110dp</dimen>
<dimen name="post_grid_height">300dp</dimen>
<dimen name="post_grid_image_height">120dp</dimen>
<dimen name="post_comment_text">15sp</dimen>
<dimen name="post_comment_text_grid">14sp</dimen>
<dimen name="post_grid_spacing">1dp</dimen>
<dimen name="image_view_padding">8dp</dimen>
</resources>

@ -35,9 +35,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<string name="action_reply_board">Reply to board</string>
<string name="action_reply_thread">Reply to thread</string>
<string name="action_open_browser">Open in browser</string>
<string name="action_catalog">Open catalog</string>
<string name="action_share">Share</string>
<string name="action_download_album">Download album</string>
<string name="action_board_view_mode">View mode</string>
<string name="action_board_view_mode_list">List</string>
<string name="action_board_view_mode_grid">Grid</string>
<string name="open_unknown_title">Unsupported link</string>
<string name="open_unknown">Clover can\'t open this link. Opening it in your browser instead.</string>

Loading…
Cancel
Save