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 6a9849c2..0a08c90c 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
@@ -145,4 +145,8 @@ public class ChanPreferences {
public static boolean getAnonymizeIds() {
return p().getBoolean("preference_anonymize_ids", false);
}
+
+ public static String getBoardMode() {
+ return p().getString("preference_board_mode", "catalog");
+ }
}
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 20329677..b8333ee0 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
@@ -145,12 +145,14 @@ public class ThreadManager implements Loader.LoaderListener {
}
public boolean shouldWatch() {
- if (!ChanPreferences.getThreadAutoRefresh()) {
+ if (!loader.getLoadable().isThreadMode()) {
+ return false;
+ } else if (!ChanPreferences.getThreadAutoRefresh()) {
return false;
} else if (loader.getCachedPosts().size() > 0 && loader.getCachedPosts().get(0).closed) {
return false;
} else {
- return loader.getLoadable().isThreadMode();
+ return true;
}
}
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 81f3749f..0a475eee 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
@@ -498,8 +498,11 @@ public class BoardActivity extends BaseActivity implements AdapterView.OnItemSel
boardLoadable = loadable;
- // TODO: make this an option
- boardLoadable.mode = Loadable.Mode.CATALOG;
+ if (ChanPreferences.getBoardMode().equals("catalog")) {
+ boardLoadable.mode = Loadable.Mode.CATALOG;
+ } else if (ChanPreferences.getBoardMode().equals("pages")) {
+ boardLoadable.mode = Loadable.Mode.BOARD;
+ }
boardFragment.bindLoadable(loadable);
boardFragment.requestData();
@@ -670,7 +673,7 @@ public class BoardActivity extends BaseActivity implements AdapterView.OnItemSel
public View getView(final int position, View convertView, final ViewGroup parent) {
switch (getItemViewType(position)) {
case VIEW_TYPE_ITEM: {
- if (convertView == null || (Integer)convertView.getTag() != VIEW_TYPE_ITEM) {
+ if (convertView == null || (Integer) convertView.getTag() != VIEW_TYPE_ITEM) {
convertView = LayoutInflater.from(context).inflate(R.layout.board_select_spinner, null);
convertView.setTag(VIEW_TYPE_ITEM);
}
@@ -680,7 +683,7 @@ public class BoardActivity extends BaseActivity implements AdapterView.OnItemSel
return textView;
}
case VIEW_TYPE_ADD: {
- if (convertView == null || (Integer)convertView.getTag() != VIEW_TYPE_ADD) {
+ if (convertView == null || (Integer) convertView.getTag() != VIEW_TYPE_ADD) {
convertView = LayoutInflater.from(context).inflate(R.layout.board_select_add, null);
convertView.setTag(VIEW_TYPE_ADD);
}
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/activity/WatchSettingsActivity.java b/Clover/app/src/main/java/org/floens/chan/ui/activity/WatchSettingsActivity.java
index fae4c297..d397c001 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/activity/WatchSettingsActivity.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/activity/WatchSettingsActivity.java
@@ -156,10 +156,10 @@ public class WatchSettingsActivity extends Activity implements OnCheckedChangeLi
}
});
- ((CheckBoxPreference)findPreference("preference_watch_background_enabled")).setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
+ ((CheckBoxPreference) findPreference("preference_watch_background_enabled")).setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(final Preference preference, final Object newValue) {
- ChanApplication.getWatchManager().onBackgroundWatchingChanged((Boolean)newValue);
+ ChanApplication.getWatchManager().onBackgroundWatchingChanged((Boolean) newValue);
return true;
}
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 2a7b4989..b55dc3af 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
@@ -18,20 +18,24 @@
package org.floens.chan.ui.adapter;
import android.content.Context;
+import android.os.Handler;
+import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
+import android.widget.LinearLayout;
import android.widget.ProgressBar;
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.Loadable;
import org.floens.chan.core.model.Post;
import org.floens.chan.ui.ScrollerRunnable;
import org.floens.chan.ui.view.PostView;
-import org.floens.chan.ui.view.ThreadWatchCounterView;
import org.floens.chan.utils.Time;
import org.floens.chan.utils.Utils;
@@ -39,6 +43,9 @@ import java.util.ArrayList;
import java.util.List;
public class PostAdapter extends BaseAdapter {
+ private static final int VIEW_TYPE_ITEM = 0;
+ private static final int VIEW_TYPE_STATUS = 1;
+
private final Context context;
private final ThreadManager threadManager;
private final AbsListView listView;
@@ -56,17 +63,30 @@ public class PostAdapter extends BaseAdapter {
@Override
public int getCount() {
- if ((threadManager.getLoadable() != null && threadManager.getLoadable().isBoardMode())
- || threadManager.shouldWatch()) {
- return postList.size() + 1;
+ return postList.size() + (showStatusView() ? 1 : 0);
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return 2;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if (showStatusView()) {
+ return position == getCount() - 1 ? VIEW_TYPE_STATUS : VIEW_TYPE_ITEM;
} else {
- return postList.size();
+ return VIEW_TYPE_ITEM;
}
}
@Override
public Post getItem(int position) {
- return postList.get(position);
+ if (position >= 0 && position < postList.size()) {
+ return postList.get(position);
+ } else {
+ return null;
+ }
}
@Override
@@ -76,61 +96,59 @@ public class PostAdapter extends BaseAdapter {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
- if (position >= getCount() - 1 && !endOfLine && threadManager.getLoadable().isBoardMode()) {
- // Try to load more posts
- threadManager.requestNextData();
+ if (position >= getCount() - 1) {
+ onGetBottomView();
}
- if (position >= postList.size()) {
- if (lastPostCount != postList.size()) {
- lastPostCount = postList.size();
- lastViewedTime = Time.get();
- }
+ switch (getItemViewType(position)) {
+ case VIEW_TYPE_ITEM: {
+ if (convertView == null || convertView.getTag() == null && (Integer) convertView.getTag() != VIEW_TYPE_ITEM) {
+ convertView = new PostView(context);
+ convertView.setTag(VIEW_TYPE_ITEM);
+ }
+
+ PostView postView = (PostView) convertView;
+ postView.setPost(getItem(position), threadManager);
- if (Time.get(lastViewedTime) > 2000L) {
- lastViewedTime = Time.get();
- threadManager.bottomPostViewed();
+ return postView;
}
+ case VIEW_TYPE_STATUS: {
+ return new StatusView(context);
+ }
+ }
- return createThreadEndView();
- } else {
- PostView postView = null;
+ return null;
+ }
- if (position >= 0 && position < postList.size()) {
- if (convertView != null && convertView instanceof PostView) {
- postView = (PostView) convertView;
- } else {
- postView = new PostView(context);
- }
+ private void onGetBottomView() {
+ if (threadManager.getLoadable().isBoardMode() && !endOfLine) {
+ // Try to load more posts
+ threadManager.requestNextData();
+ }
- postView.setPost(postList.get(position), threadManager);
- }
+ if (lastPostCount != postList.size()) {
+ lastPostCount = postList.size();
+ lastViewedTime = Time.get();
+ }
- return postView;
+ if (Time.get(lastViewedTime) > 1000L) {
+ lastViewedTime = Time.get();
+ threadManager.bottomPostViewed();
}
}
- private View createThreadEndView() {
- if (threadManager.shouldWatch()) {
- ThreadWatchCounterView view = new ThreadWatchCounterView(context);
- Utils.setPressedDrawable(view);
- view.init(threadManager, listView, this);
- int padding = Utils.dp(12f);
- view.setPadding(padding, padding, padding, padding);
- int height = Utils.dp(48f);
- view.setHeight(height);
- view.setGravity(Gravity.CENTER);
- return view;
- } else {
- if (endOfLine) {
- TextView textView = new TextView(context);
- textView.setText(context.getString(R.string.thread_load_end_of_line));
- int padding = Utils.dp(12f);
- textView.setPadding(padding, padding, padding, padding);
- return textView;
+ private boolean showStatusView() {
+ Loadable l = threadManager.getLoadable();
+ if (l != null) {
+ if (l.isBoardMode()) {
+ return true;
+ } else if (l.isThreadMode() && threadManager.shouldWatch()) {
+ return true;
} else {
- return new ProgressBar(context);
+ return false;
}
+ } else {
+ return false;
}
}
@@ -193,4 +211,91 @@ public class PostAdapter extends BaseAdapter {
public String getErrorMessage() {
return loadMessage;
}
+
+ public class StatusView extends LinearLayout {
+ boolean detached = false;
+
+ public StatusView(Context activity) {
+ super(activity);
+ init();
+ }
+
+ public StatusView(Context activity, AttributeSet attr) {
+ super(activity, attr);
+ init();
+ }
+
+ public StatusView(Context activity, AttributeSet attr, int style) {
+ super(activity, attr, style);
+ init();
+ }
+
+ public void init() {
+ Loader loader = threadManager.getLoader();
+ if (loader == null)
+ return;
+
+ setGravity(Gravity.CENTER);
+
+ if (threadManager.shouldWatch()) {
+ String error = getErrorMessage();
+ if (error != null) {
+ setText(error);
+ } else {
+ int time = Math.round(loader.getTimeUntilLoadMore() / 1000f);
+ if (time == 0) {
+ setText("Loading");
+ } else {
+ setText("Loading in " + time);
+ }
+ }
+
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ if (!detached) {
+ notifyDataSetChanged();
+ }
+ }
+ }, 1000);
+
+ setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Loader loader = threadManager.getLoader();
+ if (loader != null) {
+ loader.requestMoreDataAndResetTimer();
+ }
+
+ notifyDataSetChanged();
+ }
+ });
+
+ Utils.setPressedDrawable(this);
+ } else {
+ if (endOfLine) {
+ setText(context.getString(R.string.thread_load_end_of_line));
+ } else {
+ setProgressBar();
+ }
+ }
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ detached = true;
+ }
+
+ private void setText(String string) {
+ TextView text = new TextView(context);
+ text.setText(string);
+ text.setGravity(Gravity.CENTER);
+ addView(text, new LayoutParams(LayoutParams.MATCH_PARENT, Utils.dp(48)));
+ }
+
+ private void setProgressBar() {
+ addView(new ProgressBar(context));
+ }
+ }
}
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/fragment/PostRepliesFragment.java b/Clover/app/src/main/java/org/floens/chan/ui/fragment/PostRepliesFragment.java
index ba2a273f..b5585da4 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/fragment/PostRepliesFragment.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/fragment/PostRepliesFragment.java
@@ -96,8 +96,8 @@ public class PostRepliesFragment extends DialogFragment {
});
if (!ThemeHelper.getInstance().getTheme().isLightTheme) {
- ((TextView)container.findViewById(R.id.replies_back_icon)).setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_action_back_dark, 0, 0, 0);
- ((TextView)container.findViewById(R.id.replies_close_icon)).setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_action_done_dark, 0, 0, 0);
+ ((TextView) container.findViewById(R.id.replies_back_icon)).setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_action_back_dark, 0, 0, 0);
+ ((TextView) container.findViewById(R.id.replies_close_icon)).setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_action_done_dark, 0, 0, 0);
}
return container;
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/fragment/SettingsFragment.java b/Clover/app/src/main/java/org/floens/chan/ui/fragment/SettingsFragment.java
index 470e0a8b..45be71f3 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/fragment/SettingsFragment.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/fragment/SettingsFragment.java
@@ -32,6 +32,7 @@ import android.widget.Toast;
import org.floens.chan.R;
import org.floens.chan.core.ChanPreferences;
import org.floens.chan.ui.activity.AboutActivity;
+import org.floens.chan.ui.activity.BaseActivity;
import org.floens.chan.ui.activity.SettingsActivity;
import org.floens.chan.utils.ThemeHelper;
@@ -100,12 +101,12 @@ public class SettingsFragment extends PreferenceFragment {
theme.setValue((String) theme.getEntryValues()[0]);
currentValue = theme.getValue();
}
- updateThemeSummary(theme, currentValue);
+ updateSummary(theme, currentValue);
theme.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
- updateThemeSummary(theme, newValue.toString());
+ updateSummary(theme, newValue.toString());
// Thanks! https://github.com/CyanogenMod/android_packages_apps_Calculator/blob/cm-10.2/src/com/android/calculator2/view/PreferencesFragment.java
if (!newValue.toString().equals(ThemeHelper.getInstance().getTheme().name)) {
@@ -121,6 +122,22 @@ public class SettingsFragment extends PreferenceFragment {
return true;
}
});
+
+ final ListPreference boardMode = (ListPreference) findPreference("preference_board_mode");
+ String currentModeValue = boardMode.getValue();
+ if (currentModeValue == null) {
+ boardMode.setValue((String) boardMode.getEntryValues()[0]);
+ currentModeValue = boardMode.getValue();
+ }
+ updateSummary(boardMode, currentModeValue);
+ boardMode.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ updateSummary(boardMode, newValue.toString());
+ BaseActivity.doRestartOnResume = true;
+ return true;
+ }
+ });
}
public void onStart() {
@@ -162,7 +179,7 @@ public class SettingsFragment extends PreferenceFragment {
}
}
- private void updateThemeSummary(ListPreference list, String value) {
+ private void updateSummary(ListPreference list, String value) {
int index = list.findIndexOfValue(value);
list.setSummary(list.getEntries()[index]);
}
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
deleted file mode 100644
index 1481ff81..00000000
--- a/Clover/app/src/main/java/org/floens/chan/ui/view/ThreadWatchCounterView.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Clover - 4chan browser https://github.com/Floens/Clover/
- * Copyright (C) 2014 Floens
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package org.floens.chan.ui.view;
-
-import android.content.Context;
-import android.os.Handler;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.AbsListView;
-import android.widget.TextView;
-
-import org.floens.chan.core.loader.Loader;
-import org.floens.chan.core.manager.ThreadManager;
-import org.floens.chan.ui.adapter.PostAdapter;
-
-public class ThreadWatchCounterView extends TextView implements View.OnClickListener {
- private boolean detached = false;
- private ThreadManager tm;
- private PostAdapter ad;
-
- public ThreadWatchCounterView(Context activity) {
- super(activity);
- }
-
- public ThreadWatchCounterView(Context activity, AttributeSet attbs) {
- super(activity, attbs);
- }
-
- public ThreadWatchCounterView(Context activity, AttributeSet attbs, int style) {
- super(activity, attbs, style);
- }
-
- public void init(final ThreadManager threadManager, final AbsListView listView, final PostAdapter adapter) {
- tm = threadManager;
- ad = adapter;
-
- updateCounterText(threadManager);
-
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- if (!detached) {
- adapter.notifyDataSetChanged();
- }
- }
- }, 1000);
-
- setOnClickListener(this);
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
-
- setOnClickListener(null);
-
- detached = true;
- }
-
- @Override
- public void onClick(View v) {
- Loader loader = tm.getLoader();
- if (loader != null) {
- loader.requestMoreDataAndResetTimer();
- }
-
- ad.notifyDataSetChanged();
- }
-
- private void updateCounterText(ThreadManager threadManager) {
- Loader loader = tm.getLoader();
- if (loader == null)
- return;
-
- int time = Math.round(loader.getTimeUntilLoadMore() / 1000f);
-
- String error = ad.getErrorMessage();
- if (error != null) {
- setText(error);
- } else {
- if (time == 0) {
- setText("Loading");
- } else {
- setText("Loading in " + time);
- }
- }
- }
-}
diff --git a/Clover/app/src/main/res/values/strings.xml b/Clover/app/src/main/res/values/strings.xml
index b8769ea1..9c6a91b5 100644
--- a/Clover/app/src/main/res/values/strings.xml
+++ b/Clover/app/src/main/res/values/strings.xml
@@ -141,6 +141,16 @@ along with this program. If not, see .
- black
+ Board mode
+
+ - Catalog
+ - Paginated
+
+
+ - catalog
+ - pages
+
+
Ask before opening links
Start playing videos immediately
Auto refresh threads
diff --git a/Clover/app/src/main/res/xml/preference.xml b/Clover/app/src/main/res/xml/preference.xml
index 32c97291..d2aebdcc 100644
--- a/Clover/app/src/main/res/xml/preference.xml
+++ b/Clover/app/src/main/res/xml/preference.xml
@@ -52,6 +52,14 @@ along with this program. If not, see .
android:entryValues="@array/preference_themes_values"
android:title="@string/preference_theme"/>
+
+