diff options
author | Andrew Dolgov <[email protected]> | 2011-11-28 20:14:50 +0300 |
---|---|---|
committer | Andrew Dolgov <[email protected]> | 2011-11-28 20:14:50 +0300 |
commit | b150696e7912c6f1732102953e1206d5d82f7189 (patch) | |
tree | 666d73e5f700ffb0fd4bd3f310cb0e2f015ad13e /src/org | |
parent | 8771803965cea6202a84b937ef27981411f6370c (diff) |
implement categories for smallscreen view
Diffstat (limited to 'src/org')
-rw-r--r-- | src/org/fox/ttrss/ArticleFragment.java | 1 | ||||
-rw-r--r-- | src/org/fox/ttrss/FeedCategoriesFragment.java | 316 | ||||
-rw-r--r-- | src/org/fox/ttrss/FeedsFragment.java | 12 | ||||
-rw-r--r-- | src/org/fox/ttrss/MainActivity.java | 99 |
4 files changed, 412 insertions, 16 deletions
diff --git a/src/org/fox/ttrss/ArticleFragment.java b/src/org/fox/ttrss/ArticleFragment.java index 32664fff..9fc2619b 100644 --- a/src/org/fox/ttrss/ArticleFragment.java +++ b/src/org/fox/ttrss/ArticleFragment.java @@ -12,7 +12,6 @@ import android.preference.PreferenceManager; import android.support.v4.app.Fragment;
import android.text.Html;
import android.text.method.LinkMovementMethod;
-import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.LayoutInflater;
diff --git a/src/org/fox/ttrss/FeedCategoriesFragment.java b/src/org/fox/ttrss/FeedCategoriesFragment.java new file mode 100644 index 00000000..8c1cd9b5 --- /dev/null +++ b/src/org/fox/ttrss/FeedCategoriesFragment.java @@ -0,0 +1,316 @@ +package org.fox.ttrss;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.reflect.TypeToken;
+
+public class FeedCategoriesFragment extends Fragment implements OnItemClickListener, OnSharedPreferenceChangeListener {
+ @SuppressWarnings("unused")
+ private final String TAG = this.getClass().getSimpleName();
+ private SharedPreferences m_prefs;
+ private FeedCategoryListAdapter m_adapter;
+ private FeedCategoryList m_cats = new FeedCategoryList();
+ private int m_selectedCatId;
+ private OnCatSelectedListener m_catSelectedListener;
+
+ public interface OnCatSelectedListener {
+ public void onCatSelected(FeedCategory cat);
+ }
+
+ class CatUnreadComparator implements Comparator<FeedCategory> {
+ @Override
+ public int compare(FeedCategory a, FeedCategory b) {
+ if (a.unread != b.unread)
+ return b.unread - a.unread;
+ else
+ return a.title.compareTo(b.title);
+ }
+ }
+
+
+ class CatTitleComparator implements Comparator<FeedCategory> {
+
+ @Override
+ public int compare(FeedCategory a, FeedCategory b) {
+ if (a.id >= 0 && b.id >= 0)
+ return a.title.compareTo(b.title);
+ else
+ return a.id - b.id;
+ }
+
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ if (savedInstanceState != null) {
+ m_selectedCatId = savedInstanceState.getInt("selectedCatId");
+ m_cats = savedInstanceState.getParcelable("cats");
+ }
+
+ View view = inflater.inflate(R.layout.cats_fragment, container, false);
+
+ ListView list = (ListView)view.findViewById(R.id.feeds);
+ m_adapter = new FeedCategoryListAdapter(getActivity(), R.layout.feeds_row, (ArrayList<FeedCategory>)m_cats);
+ list.setAdapter(m_adapter);
+ list.setOnItemClickListener(this);
+
+ if (m_cats == null || m_cats.size() == 0)
+ refresh(false);
+ else
+ view.findViewById(R.id.loading_progress).setVisibility(View.GONE);
+
+ return view;
+ }
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+
+ m_catSelectedListener = (OnCatSelectedListener)activity;
+
+ m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
+ m_prefs.registerOnSharedPreferenceChangeListener(this);
+
+ }
+
+ @Override
+ public void onSaveInstanceState (Bundle out) {
+ super.onSaveInstanceState(out);
+
+ out.putInt("selectedCatId", m_selectedCatId);
+ out.putParcelable("cats", m_cats);
+ }
+
+ public void setLoadingStatus(int status, boolean showProgress) {
+ if (getView() != null) {
+ TextView tv = (TextView)getView().findViewById(R.id.loading_message);
+
+ if (tv != null) {
+ tv.setText(status);
+ }
+
+ View pb = getView().findViewById(R.id.loading_progress);
+
+ if (pb != null) {
+ pb.setVisibility(showProgress ? View.VISIBLE : View.GONE);
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void refresh(boolean background) {
+ CatsRequest req = new CatsRequest(getActivity().getApplicationContext());
+
+ final String sessionId = ((MainActivity)getActivity()).getSessionId();
+ final boolean unreadOnly = ((MainActivity)getActivity()).getUnreadOnly();
+
+ if (sessionId != null) {
+
+ if (!background) {
+ getActivity().runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ setLoadingStatus(R.string.blank, true);
+ }
+ });
+ }
+
+ @SuppressWarnings("serial")
+ HashMap<String,String> map = new HashMap<String,String>() {
+ {
+ put("op", "getCategories");
+ put("sid", sessionId);
+ if (unreadOnly) {
+ put("unread_only", String.valueOf(unreadOnly));
+ }
+ }
+ };
+
+ req.execute(map);
+
+ }
+ }
+
+ private class CatsRequest extends ApiRequest {
+
+ public CatsRequest(Context context) {
+ super(context);
+ }
+
+ protected void onPostExecute(JsonElement result) {
+ if (result != null) {
+ try {
+ JsonObject rv = result.getAsJsonObject();
+
+ Gson gson = new Gson();
+
+ int status = rv.get("status").getAsInt();
+
+ if (status == 0) {
+ JsonArray content = rv.get("content").getAsJsonArray();
+ if (content != null) {
+ Type listType = new TypeToken<List<FeedCategory>>() {}.getType();
+ final List<FeedCategory> cats = gson.fromJson(content, listType);
+
+ m_cats.clear();
+
+ for (FeedCategory c : cats)
+ m_cats.add(c);
+
+ sortCats();
+
+ if (m_cats.size() == 0)
+ setLoadingStatus(R.string.error_no_feeds, false);
+ else
+ setLoadingStatus(R.string.blank, false);
+
+ }
+ } else {
+ MainActivity activity = (MainActivity)getActivity();
+ activity.login();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ setLoadingStatus(R.string.error_invalid_object, false);
+ // report invalid object received
+ }
+ } else {
+ // report null object received, unless we've been awakened from sleep right in the right time
+ // so that current request failed
+ if (m_cats.size() == 0) setLoadingStatus(R.string.error_no_data, false);
+ }
+
+ return;
+ }
+ }
+
+ public void sortCats() {
+ Comparator<FeedCategory> cmp;
+
+ if (m_prefs.getBoolean("sort_feeds_by_unread", false)) {
+ cmp = new CatUnreadComparator();
+ } else {
+ cmp = new CatTitleComparator();
+ }
+
+ Collections.sort(m_cats, cmp);
+ m_adapter.notifyDataSetInvalidated();
+
+ }
+
+ private class FeedCategoryListAdapter extends ArrayAdapter<FeedCategory> {
+ private ArrayList<FeedCategory> items;
+
+ public static final int VIEW_NORMAL = 0;
+ public static final int VIEW_SELECTED = 1;
+
+ public static final int VIEW_COUNT = VIEW_SELECTED+1;
+
+ public FeedCategoryListAdapter(Context context, int textViewResourceId, ArrayList<FeedCategory> items) {
+ super(context, textViewResourceId, items);
+ this.items = items;
+ }
+
+ public int getViewTypeCount() {
+ return VIEW_COUNT;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ FeedCategory cat = items.get(position);
+
+ if (cat.id == m_selectedCatId) {
+ return VIEW_SELECTED;
+ } else {
+ return VIEW_NORMAL;
+ }
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View v = convertView;
+
+ FeedCategory cat = items.get(position);
+
+ if (v == null) {
+ int layoutId = R.layout.feeds_row;
+
+ switch (getItemViewType(position)) {
+ case VIEW_SELECTED:
+ layoutId = R.layout.feeds_row_selected;
+ break;
+ }
+
+ LayoutInflater vi = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ v = vi.inflate(layoutId, null);
+
+ }
+
+ TextView tt = (TextView) v.findViewById(R.id.title);
+
+ if (tt != null) {
+ tt.setText(cat.title);
+ }
+
+ TextView tu = (TextView) v.findViewById(R.id.unread_counter);
+
+ if (tu != null) {
+ tu.setText(String.valueOf(cat.unread));
+ tu.setVisibility((cat.unread > 0) ? View.VISIBLE : View.INVISIBLE);
+ }
+
+ ImageView icon = (ImageView)v.findViewById(R.id.icon);
+
+ if (icon != null) {
+ icon.setImageResource(cat.unread > 0 ? R.drawable.ic_rss : R.drawable.ic_rss_bw);
+ }
+
+ return v;
+ }
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onItemClick(AdapterView<?> av, View view, int position, long id) {
+ ListView list = (ListView)av;
+
+ if (list != null) {
+ FeedCategory cat = (FeedCategory)list.getItemAtPosition(position);
+ m_catSelectedListener.onCatSelected(cat);
+ m_selectedCatId = cat.id;
+ m_adapter.notifyDataSetChanged();
+ }
+ }
+}
diff --git a/src/org/fox/ttrss/FeedsFragment.java b/src/org/fox/ttrss/FeedsFragment.java index 06d48fbe..c3f1f01e 100644 --- a/src/org/fox/ttrss/FeedsFragment.java +++ b/src/org/fox/ttrss/FeedsFragment.java @@ -1,11 +1,9 @@ package org.fox.ttrss;
import java.io.BufferedInputStream;
-import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
-import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.net.MalformedURLException;
import java.net.URL;
@@ -20,11 +18,9 @@ import org.apache.http.HttpResponse; import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
-import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
@@ -56,11 +52,9 @@ import com.google.gson.Gson; import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
public class FeedsFragment extends Fragment implements OnItemClickListener, OnSharedPreferenceChangeListener {
- @SuppressWarnings("unused")
private final String TAG = this.getClass().getSimpleName();
private SharedPreferences m_prefs;
private FeedListAdapter m_adapter;
@@ -166,6 +160,10 @@ public class FeedsFragment extends Fragment implements OnItemClickListener, OnSh final String sessionId = ((MainActivity)getActivity()).getSessionId();
final boolean unreadOnly = ((MainActivity)getActivity()).getUnreadOnly();
+ FeedCategory cat = ((MainActivity)getActivity()).getActiveCategory();
+
+ final int catId = (cat != null) ? cat.id : -4;
+
if (sessionId != null) {
if (!background) {
@@ -181,7 +179,7 @@ public class FeedsFragment extends Fragment implements OnItemClickListener, OnSh {
put("op", "getFeeds");
put("sid", sessionId);
- put("cat_id", "-4");
+ put("cat_id", String.valueOf(catId));
if (unreadOnly) {
put("unread_only", String.valueOf(unreadOnly));
}
diff --git a/src/org/fox/ttrss/MainActivity.java b/src/org/fox/ttrss/MainActivity.java index 763e1fa7..511873b1 100644 --- a/src/org/fox/ttrss/MainActivity.java +++ b/src/org/fox/ttrss/MainActivity.java @@ -27,7 +27,7 @@ import android.widget.TextView; import com.google.gson.JsonElement; import com.google.gson.JsonObject; -public class MainActivity extends FragmentActivity implements FeedsFragment.OnFeedSelectedListener, ArticleOps { +public class MainActivity extends FragmentActivity implements FeedsFragment.OnFeedSelectedListener, ArticleOps, FeedCategoriesFragment.OnCatSelectedListener { private final String TAG = this.getClass().getSimpleName(); private SharedPreferences m_prefs; @@ -35,6 +35,7 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe private String m_sessionId; private Article m_selectedArticle; private Feed m_activeFeed; + private FeedCategory m_activeCategory; private Timer m_refreshTimer; private RefreshTask m_refreshTask; private Menu m_menu; @@ -43,6 +44,7 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe private boolean m_unreadArticlesOnly = true; private boolean m_canLoadMore = true; private boolean m_compatMode = false; + private boolean m_enableCats = false; public void updateHeadlines() { HeadlinesFragment frag = (HeadlinesFragment)getSupportFragmentManager().findFragmentById(R.id.headlines_fragment); @@ -106,7 +108,10 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe @Override public void run() { - refreshFeeds(); + if (!m_enableCats || m_activeCategory != null) + refreshFeeds(); + else + refreshCategories(); } } @@ -120,10 +125,23 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe } } + public synchronized void refreshCategories() { + FeedCategoriesFragment frag = (FeedCategoriesFragment) getSupportFragmentManager().findFragmentById(R.id.cats_fragment); + + Log.d(TAG, "Refreshing categories..."); + + if (frag != null) { + frag.refresh(true); + } + } public void setUnreadOnly(boolean unread) { m_unreadOnly = unread; - refreshFeeds(); + + if (!m_enableCats || m_activeCategory != null ) + refreshFeeds(); + else + refreshCategories(); } public boolean getUnreadOnly() { @@ -175,8 +193,11 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe m_selectedArticle = savedInstanceState.getParcelable("selectedArticle"); m_unreadArticlesOnly = savedInstanceState.getBoolean("unreadArticlesOnly"); m_canLoadMore = savedInstanceState.getBoolean("canLoadMore"); + m_activeCategory = savedInstanceState.getParcelable("activeCategory"); } + m_enableCats = m_prefs.getBoolean("enable_cats", false); + Display display = getWindowManager().getDefaultDisplay(); int orientation = display.getOrientation(); int minWidth = orientation % 2 == 0 ? 1024 : 600; @@ -205,13 +226,22 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe if (m_smallScreenMode) { if (m_selectedArticle != null) { findViewById(R.id.feeds_fragment).setVisibility(View.GONE); + findViewById(R.id.cats_fragment).setVisibility(View.GONE); findViewById(R.id.headlines_fragment).setVisibility(View.GONE); } else if (m_activeFeed != null) { findViewById(R.id.feeds_fragment).setVisibility(View.GONE); findViewById(R.id.article_fragment).setVisibility(View.GONE); + findViewById(R.id.cats_fragment).setVisibility(View.GONE); } else { findViewById(R.id.headlines_fragment).setVisibility(View.GONE); - findViewById(R.id.article_fragment).setVisibility(View.GONE); + //findViewById(R.id.article_fragment).setVisibility(View.GONE); + + if (m_enableCats && m_activeCategory == null) { + findViewById(R.id.feeds_fragment).setVisibility(View.GONE); + findViewById(R.id.cats_fragment).setVisibility(View.VISIBLE); + } else { + findViewById(R.id.cats_fragment).setVisibility(View.GONE); + } } } else { if (m_selectedArticle == null) @@ -252,13 +282,17 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe out.putParcelable("selectedArticle", m_selectedArticle); out.putBoolean("unreadArticlesOnly", m_unreadArticlesOnly); out.putBoolean("canLoadMore", m_canLoadMore); + out.putParcelable("activeCategory", m_activeCategory); } @Override public void onResume() { super.onResume(); - if (!m_prefs.getString("theme", "THEME_DARK").equals(m_themeName)) { + boolean needRefresh = !m_prefs.getString("theme", "THEME_DARK").equals(m_themeName) || + m_prefs.getBoolean("enable_cats", false) != m_enableCats; + + if (needRefresh) { Intent refresh = new Intent(this, MainActivity.class); startActivity(refresh); finish(); @@ -334,6 +368,21 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe m_activeFeed = null; initMainMenu(); + refreshFeeds(); + + } else if (m_activeCategory != null) { + if (m_compatMode) { + findViewById(R.id.main).setAnimation(AnimationUtils.loadAnimation(this, R.anim.slide_right)); + } + + findViewById(R.id.feeds_fragment).setVisibility(View.GONE); + findViewById(R.id.cats_fragment).setVisibility(View.VISIBLE); + + m_activeCategory = null; + + initMainMenu(); + refreshCategories(); + } else { finish(); } @@ -450,6 +499,7 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe initMainMenu(); refreshFeeds(); + } public void setCanLoadMore(boolean canLoadMore) { @@ -554,10 +604,16 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe setLoadingStatus(R.string.loading_message, true); - FeedsFragment frag = new FeedsFragment(); - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - ft.replace(R.id.feeds_fragment, frag); + + if (m_enableCats) { + FeedCategoriesFragment frag = new FeedCategoriesFragment(); + ft.replace(R.id.cats_fragment, frag); + } else { + FeedsFragment frag = new FeedsFragment(); + ft.replace(R.id.feeds_fragment, frag); + } + ft.commit(); loginSuccess(); @@ -625,6 +681,23 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe } } + public void viewCategory(FeedCategory cat) { + m_activeCategory = cat; + + initMainMenu(); + + if (m_smallScreenMode) { + findViewById(R.id.cats_fragment).setVisibility(View.GONE); + findViewById(R.id.feeds_fragment).setVisibility(View.VISIBLE); + } + + FeedsFragment frag = new FeedsFragment(); + + FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); + ft.replace(R.id.feeds_fragment, frag); + ft.commit(); + } + public void openArticle(Article article, int compatAnimation) { m_selectedArticle = article; @@ -668,6 +741,10 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe return m_activeFeed; } + public FeedCategory getActiveCategory() { + return m_activeCategory; + } + public void logout() { if (m_refreshTask != null) { m_refreshTask.cancel(); @@ -749,4 +826,10 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe } return null; } + + @Override + public void onCatSelected(FeedCategory cat) { + m_activeCategory = cat; + viewCategory(cat); + } }
\ No newline at end of file |