Added option for paginated/catalog board mode

Added itemviewtypes to PostAdapter
captchafix
Florens Douwes 11 years ago
parent d60e3369d1
commit 286b1093d5
  1. 4
      Clover/app/src/main/java/org/floens/chan/core/ChanPreferences.java
  2. 6
      Clover/app/src/main/java/org/floens/chan/core/manager/ThreadManager.java
  3. 11
      Clover/app/src/main/java/org/floens/chan/ui/activity/BoardActivity.java
  4. 4
      Clover/app/src/main/java/org/floens/chan/ui/activity/WatchSettingsActivity.java
  5. 201
      Clover/app/src/main/java/org/floens/chan/ui/adapter/PostAdapter.java
  6. 4
      Clover/app/src/main/java/org/floens/chan/ui/fragment/PostRepliesFragment.java
  7. 23
      Clover/app/src/main/java/org/floens/chan/ui/fragment/SettingsFragment.java
  8. 103
      Clover/app/src/main/java/org/floens/chan/ui/view/ThreadWatchCounterView.java
  9. 10
      Clover/app/src/main/res/values/strings.xml
  10. 8
      Clover/app/src/main/res/xml/preference.xml

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

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

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

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

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

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

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

@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}
}
}

@ -141,6 +141,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<item>black</item>
</string-array>
<string name="preference_board_mode">Board mode</string>
<string-array name="preference_board_modes">
<item>Catalog</item>
<item>Paginated</item>
</string-array>
<string-array name="preference_board_modes_values">
<item>catalog</item>
<item>pages</item>
</string-array>
<string name="preference_open_link_confirmation">Ask before opening links</string>
<string name="preference_autoplay">Start playing videos immediately</string>
<string name="preference_auto_refresh_thread">Auto refresh threads</string>

@ -52,6 +52,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
android:entryValues="@array/preference_themes_values"
android:title="@string/preference_theme"/>
<ListPreference
android:key="preference_board_mode"
android:defaultValue="catalog"
android:dialogTitle="@string/preference_board_mode"
android:entries="@array/preference_board_modes"
android:entryValues="@array/preference_board_modes_values"
android:title="@string/preference_board_mode" />
<CheckBoxPreference
android:defaultValue="true"
android:key="preference_open_link_confirmation"

Loading…
Cancel
Save