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"/> + +