diff options
author | Andrew Dolgov <[email protected]> | 2012-09-16 13:25:28 +0400 |
---|---|---|
committer | Andrew Dolgov <[email protected]> | 2012-09-16 13:25:28 +0400 |
commit | ced80be1aea975b59db5a0e6dd14acb054e7910e (patch) | |
tree | f69f8c12151d0ccb9eee7f52d598c6ef626c914c | |
parent | 86a4f6c2dea5700ed3597d9afe280ddb93d56316 (diff) |
initial
35 files changed, 1711 insertions, 6361 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 94bfd20c..e4e00753 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.fox.ttrss" - android:versionCode="97" - android:versionName="0.7.5" > + android:versionCode="100" + android:versionName="0.8.0" > <uses-sdk android:minSdkVersion="8" @@ -19,15 +19,7 @@ android:icon="@drawable/icon" android:label="@string/app_name" > <activity - android:name=".LoginActivity" - android:label="@string/app_name" > - </activity> - <activity - android:name=".offline.OfflineActivity" - android:label="@string/app_name" > - </activity> - <activity - android:name=".MainActivity" + android:name=".OnlineActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> @@ -40,6 +32,21 @@ android:label="@string/preferences" > </activity> + <activity + android:name=".FeedsActivity" + android:label="@string/app_name" > + </activity> + + <activity + android:name=".HeadlinesActivity" + android:label="@string/app_name" > + </activity> + + <activity + android:name=".ArticleActivity" + android:label="@string/app_name" > + </activity> + <service android:name=".offline.OfflineDownloadService" android:enabled="true" /> diff --git a/res/layout-sw600dp-port/headlines.xml b/res/layout-sw600dp-port/headlines.xml new file mode 100644 index 00000000..84d8d654 --- /dev/null +++ b/res/layout-sw600dp-port/headlines.xml @@ -0,0 +1,48 @@ +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/main"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <LinearLayout
+ android:id="@+id/loading_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="?loadingBackground"
+ android:gravity="center"
+ android:orientation="vertical"
+ android:visibility="visible" >
+
+ <TextView
+ android:id="@+id/loading_message"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:text="@string/loading_message"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/fragment_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <FrameLayout
+ android:id="@+id/headlines_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="0.3"
+ android:background="?headlinesBackgroundSolid" >
+ </FrameLayout>
+
+ <FrameLayout
+ android:id="@+id/article_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="0.7"
+ android:background="?articleBackground" >
+ </FrameLayout>
+ </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file diff --git a/res/layout-sw600dp/feeds.xml b/res/layout-sw600dp/feeds.xml new file mode 100644 index 00000000..1bc48b2b --- /dev/null +++ b/res/layout-sw600dp/feeds.xml @@ -0,0 +1,47 @@ +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/main"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <LinearLayout
+ android:id="@+id/loading_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="?loadingBackground"
+ android:gravity="center"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/loading_message"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:text="@string/loading_message"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/fragment_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal" >
+
+ <FrameLayout
+ android:id="@+id/feeds_fragment"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="0.4"
+ android:background="?feedlistBackground" >
+ </FrameLayout>
+
+ <FrameLayout
+ android:id="@+id/headlines_fragment"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="0.6"
+ android:background="?headlinesBackground" >
+ </FrameLayout>
+ </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file diff --git a/res/layout-sw600dp/headlines.xml b/res/layout-sw600dp/headlines.xml new file mode 100644 index 00000000..1d9addbc --- /dev/null +++ b/res/layout-sw600dp/headlines.xml @@ -0,0 +1,48 @@ +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/headlines"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <LinearLayout
+ android:id="@+id/loading_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="?loadingBackground"
+ android:gravity="center"
+ android:orientation="vertical"
+ android:visibility="visible" >
+
+ <TextView
+ android:id="@+id/loading_message"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:text="@string/loading_message"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/fragment_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal" >
+
+ <FrameLayout
+ android:id="@+id/headlines_fragment"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="0.4"
+ android:background="?headlinesBackground" >
+ </FrameLayout>
+
+ <FrameLayout
+ android:id="@+id/article_fragment"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="0.6"
+ android:background="?articleBackground" >
+ </FrameLayout>
+ </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file diff --git a/res/layout/feeds.xml b/res/layout/feeds.xml new file mode 100644 index 00000000..c3f7be59 --- /dev/null +++ b/res/layout/feeds.xml @@ -0,0 +1,27 @@ +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/main"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" >
+
+ <LinearLayout
+ android:id="@+id/loading_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/loading_message"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:text="@string/loading_message" />
+ </LinearLayout>
+
+ <FrameLayout
+ android:id="@+id/feeds_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+ </FrameLayout>
+
+</LinearLayout>
\ No newline at end of file diff --git a/res/layout/headlines.xml b/res/layout/headlines.xml new file mode 100644 index 00000000..60c24b91 --- /dev/null +++ b/res/layout/headlines.xml @@ -0,0 +1,27 @@ +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/headlines"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" >
+
+ <LinearLayout
+ android:id="@+id/loading_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/loading_message"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:text="@string/loading_message" />
+ </LinearLayout>
+
+ <FrameLayout
+ android:id="@+id/fragment_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+ </FrameLayout>
+
+</LinearLayout>
\ No newline at end of file diff --git a/res/layout/online.xml b/res/layout/online.xml new file mode 100644 index 00000000..d94aa147 --- /dev/null +++ b/res/layout/online.xml @@ -0,0 +1,21 @@ +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/online"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" >
+
+ <LinearLayout
+ android:id="@+id/loading_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/loading_message"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:text="@string/loading_message" />
+ </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file diff --git a/res/menu/headlines_menu.xml b/res/menu/headlines_context_menu.xml index 073ecb37..073ecb37 100644 --- a/res/menu/headlines_menu.xml +++ b/res/menu/headlines_context_menu.xml diff --git a/res/menu/main_menu.xml b/res/menu/main_menu.xml index c6e49511..68625729 100644 --- a/res/menu/main_menu.xml +++ b/res/menu/main_menu.xml @@ -2,41 +2,6 @@ <group android:id="@+id/menu_group_logged_in" > - <group android:id="@+id/menu_group_feeds" > - - <!-- - <item - android:id="@+id/back_to_categories" - android:icon="@android:drawable/ic_menu_close_clear_cancel" - android:showAsAction="" - android:title="@string/back_to_categories"/> - --> - - <item - android:id="@+id/show_feeds" - android:icon="@android:drawable/ic_menu_agenda" - android:showAsAction="" - android:title="@string/menu_all_feeds"/> - - <item - android:id="@+id/update_feeds" - android:icon="@android:drawable/ic_menu_rotate" - android:showAsAction="ifRoom" - android:title="@string/update_feeds"/> - - <item - android:id="@+id/go_offline" - android:icon="@drawable/ic_menu_cloud" - android:showAsAction="" - android:title="@string/go_offline"/> - - <item - android:id="@+id/logout" - android:icon="@drawable/ic_menu_exit" - android:showAsAction="" - android:title="@string/logout"/> - </group> - <group android:id="@+id/menu_group_headlines" > <item diff --git a/res/menu/online_menu.xml b/res/menu/online_menu.xml new file mode 100644 index 00000000..d299eb6f --- /dev/null +++ b/res/menu/online_menu.xml @@ -0,0 +1,29 @@ +<menu xmlns:android="http://schemas.android.com/apk/res/android" > + + <group android:id="@+id/menu_group_logged_in" > + + <item + android:id="@+id/logout" + android:icon="@drawable/ic_menu_exit" + android:showAsAction="" + android:title="@string/logout"/> + + </group> + + <group android:id="@+id/menu_group_logged_out" > + + <item + android:id="@+id/login" + android:icon="@android:drawable/ic_menu_rotate" + android:showAsAction="ifRoom|withText" + android:title="@string/login_login"/> + </group> + + <item + android:id="@+id/preferences" + android:icon="@android:drawable/ic_menu_preferences" + android:showAsAction="" + android:title="@string/preferences"/> + + +</menu>
\ No newline at end of file diff --git a/src/org/fox/ttrss/ArticleEventListener.java b/src/org/fox/ttrss/ArticleEventListener.java new file mode 100644 index 00000000..688c10f1 --- /dev/null +++ b/src/org/fox/ttrss/ArticleEventListener.java @@ -0,0 +1,9 @@ +package org.fox.ttrss;
+
+public interface ArticleEventListener {
+
+ void copyToClipboard(String content_url);
+
+ boolean isSmallScreen();
+
+}
diff --git a/src/org/fox/ttrss/ArticleFragment.java b/src/org/fox/ttrss/ArticleFragment.java index c3d83dd0..18569670 100644 --- a/src/org/fox/ttrss/ArticleFragment.java +++ b/src/org/fox/ttrss/ArticleFragment.java @@ -44,7 +44,7 @@ public class ArticleFragment extends Fragment { private SharedPreferences m_prefs;
private Article m_article;
- private OnlineServices m_onlineServices;
+ private ArticleEventListener m_onlineServices;
//private Article m_nextArticle;
//private Article m_prevArticle;
@@ -296,7 +296,7 @@ public class ArticleFragment extends Fragment { super.onAttach(activity);
m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
- m_onlineServices = (OnlineServices)activity;
+ m_onlineServices = (ArticleEventListener)activity;
//m_article = m_onlineServices.getSelectedArticle();
}
diff --git a/src/org/fox/ttrss/ArticlePager.java b/src/org/fox/ttrss/ArticlePager.java index 3027d61b..9818e08c 100644 --- a/src/org/fox/ttrss/ArticlePager.java +++ b/src/org/fox/ttrss/ArticlePager.java @@ -16,7 +16,7 @@ public class ArticlePager extends Fragment { private final String TAG = "ArticlePager";
private PagerAdapter m_adapter;
- private OnlineServices m_onlineServices;
+ private HeadlinesEventListener m_onlineServices;
private HeadlinesFragment m_hf;
private Article m_article;
@@ -85,7 +85,7 @@ public class ArticlePager extends Fragment { article.unread = false;
m_onlineServices.saveArticleUnread(article);
}
- m_onlineServices.setSelectedArticle(article);
+ m_onlineServices.onArticleSelected(article, false);
//Log.d(TAG, "Page #" + position + "/" + m_adapter.getCount());
@@ -104,8 +104,8 @@ public class ArticlePager extends Fragment { public void onAttach(Activity activity) {
super.onAttach(activity);
- m_hf = (HeadlinesFragment) getActivity().getSupportFragmentManager().findFragmentByTag(MainActivity.FRAG_HEADLINES);
- m_onlineServices = (OnlineServices)activity;
+ m_hf = (HeadlinesFragment) getActivity().getSupportFragmentManager().findFragmentByTag(CommonActivity.FRAG_HEADLINES);
+ m_onlineServices = (HeadlinesEventListener)activity;
}
}
diff --git a/src/org/fox/ttrss/CommonActivity.java b/src/org/fox/ttrss/CommonActivity.java index d88775b3..9f67e49d 100644 --- a/src/org/fox/ttrss/CommonActivity.java +++ b/src/org/fox/ttrss/CommonActivity.java @@ -9,6 +9,7 @@ import android.util.DisplayMetrics; import android.util.FloatMath;
import android.util.Log;
import android.view.Display;
+import android.widget.TextView;
import android.widget.Toast;
public class CommonActivity extends FragmentActivity {
@@ -31,6 +32,16 @@ public class CommonActivity extends FragmentActivity { m_smallScreenMode = smallScreen;
}
+ protected void setLoadingStatus(int status, boolean showProgress) {
+ TextView tv = (TextView) findViewById(R.id.loading_message);
+
+ if (tv != null) {
+ tv.setText(status);
+ }
+
+ setProgressBarIndeterminateVisibility(showProgress);
+ }
+
public void toast(int msgId) {
Toast toast = Toast.makeText(CommonActivity.this, msgId, Toast.LENGTH_SHORT);
toast.show();
diff --git a/src/org/fox/ttrss/FeedCategoriesFragment.java b/src/org/fox/ttrss/FeedCategoriesFragment.java index 055659ca..9af914b9 100644 --- a/src/org/fox/ttrss/FeedCategoriesFragment.java +++ b/src/org/fox/ttrss/FeedCategoriesFragment.java @@ -7,6 +7,7 @@ import java.util.Comparator; import java.util.HashMap;
import java.util.List;
+import org.fox.ttrss.types.Feed;
import org.fox.ttrss.types.FeedCategory;
import org.fox.ttrss.types.FeedCategoryList;
@@ -17,9 +18,11 @@ import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
+import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
+import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
@@ -42,7 +45,7 @@ public class FeedCategoriesFragment extends Fragment implements OnItemClickListe private FeedCategoryListAdapter m_adapter;
private FeedCategoryList m_cats = new FeedCategoryList();
private FeedCategory m_selectedCat;
- private OnlineServices m_onlineServices;
+ private FeedsActivity m_activity;
class CatUnreadComparator implements Comparator<FeedCategory> {
@Override
@@ -83,6 +86,45 @@ public class FeedCategoriesFragment extends Fragment implements OnItemClickListe }
@Override
+ public boolean onContextItemSelected(MenuItem item) {
+ AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
+ .getMenuInfo();
+
+ switch (item.getItemId()) {
+ case R.id.browse_articles:
+ if (true) {
+ FeedCategory cat = getCategoryAtPosition(info.position);
+ if (cat != null) {
+ m_activity.onCatSelected(cat, true);
+ //setSelectedCategory(cat);
+ }
+ }
+ return true;
+ case R.id.browse_feeds:
+ if (true) {
+ FeedCategory cat = getCategoryAtPosition(info.position);
+ if (cat != null) {
+ m_activity.onCatSelected(cat, false);
+ //cf.setSelectedCategory(cat);
+ }
+ }
+ return true;
+ case R.id.catchup_category:
+ if (true) {
+ FeedCategory cat = getCategoryAtPosition(info.position);
+ if (cat != null) {
+ m_activity.catchupFeed(new Feed(cat.id, cat.title, true));
+ }
+ }
+ return true;
+
+ default:
+ Log.d(TAG, "onContextItemSelected, unhandled id=" + item.getItemId());
+ return super.onContextItemSelected(item);
+ }
+ }
+
+ @Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
@@ -117,11 +159,6 @@ public class FeedCategoriesFragment extends Fragment implements OnItemClickListe list.setOnItemClickListener(this);
registerForContextMenu(list);
- if (m_cats == null || m_cats.size() == 0)
- refresh(false);
- else
- getActivity().setProgressBarIndeterminateVisibility(false);
-
return view;
}
@@ -129,11 +166,20 @@ public class FeedCategoriesFragment extends Fragment implements OnItemClickListe public void onAttach(Activity activity) {
super.onAttach(activity);
- m_onlineServices = (OnlineServices)activity;
+ m_activity = (FeedsActivity)activity;
m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
m_prefs.registerOnSharedPreferenceChangeListener(this);
+
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ refresh(false);
+ m_activity.initMenu();
}
@Override
@@ -161,8 +207,8 @@ public class FeedCategoriesFragment extends Fragment implements OnItemClickListe public void refresh(boolean background) {
CatsRequest req = new CatsRequest(getActivity().getApplicationContext());
- final String sessionId = m_onlineServices.getSessionId();
- final boolean unreadOnly = m_onlineServices.getUnreadOnly();
+ final String sessionId = m_activity.getSessionId();
+ final boolean unreadOnly = m_activity.getUnreadOnly();
if (sessionId != null) {
@@ -205,7 +251,7 @@ public class FeedCategoriesFragment extends Fragment implements OnItemClickListe m_cats.clear();
- int apiLevel = m_onlineServices.getApiLevel();
+ int apiLevel = m_activity.getApiLevel();
// virtual cats implemented in getCategories since api level 1
if (apiLevel == 0) {
@@ -233,7 +279,7 @@ public class FeedCategoriesFragment extends Fragment implements OnItemClickListe }
if (m_lastError == ApiError.LOGIN_FAILED) {
- m_onlineServices.login();
+ m_activity.login();
} else {
setLoadingStatus(getErrorMessage(), false);
}
@@ -247,7 +293,7 @@ public class FeedCategoriesFragment extends Fragment implements OnItemClickListe if (m_prefs.getBoolean("sort_feeds_by_unread", false)) {
cmp = new CatUnreadComparator();
} else {
- if (m_onlineServices.getApiLevel() >= 3) {
+ if (m_activity.getApiLevel() >= 3) {
cmp = new CatOrderComparator();
} else {
cmp = new CatTitleComparator();
@@ -280,7 +326,7 @@ public class FeedCategoriesFragment extends Fragment implements OnItemClickListe public int getItemViewType(int position) {
FeedCategory cat = items.get(position);
- if (!m_onlineServices.isSmallScreen() && m_selectedCat != null && cat.id == m_selectedCat.id) {
+ if (!m_activity.isSmallScreen() && m_selectedCat != null && cat.id == m_selectedCat.id) {
return VIEW_SELECTED;
} else {
return VIEW_NORMAL;
@@ -344,9 +390,9 @@ public class FeedCategoriesFragment extends Fragment implements OnItemClickListe if (list != null) {
FeedCategory cat = (FeedCategory)list.getItemAtPosition(position);
- m_onlineServices.onCatSelected(cat);
+ m_activity.onCatSelected(cat);
- if (!m_onlineServices.isSmallScreen())
+ if (!m_activity.isSmallScreen())
m_selectedCat = cat;
m_adapter.notifyDataSetChanged();
diff --git a/src/org/fox/ttrss/FeedsActivity.java b/src/org/fox/ttrss/FeedsActivity.java new file mode 100644 index 00000000..5cc1d176 --- /dev/null +++ b/src/org/fox/ttrss/FeedsActivity.java @@ -0,0 +1,212 @@ +package org.fox.ttrss;
+
+import java.util.HashMap;
+
+import org.fox.ttrss.types.Article;
+import org.fox.ttrss.types.ArticleList;
+import org.fox.ttrss.types.Feed;
+import org.fox.ttrss.types.FeedCategory;
+
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentTransaction;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.Window;
+
+public class FeedsActivity extends OnlineActivity implements HeadlinesEventListener, ArticleEventListener {
+ private final String TAG = this.getClass().getSimpleName();
+
+ protected SharedPreferences m_prefs;
+
+ private boolean m_unreadOnly = true;
+ private boolean m_unreadArticlesOnly = true;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ m_prefs = PreferenceManager
+ .getDefaultSharedPreferences(getApplicationContext());
+
+ if (m_prefs.getString("theme", "THEME_DARK").equals("THEME_DARK")) {
+ setTheme(R.style.DarkTheme);
+ } else {
+ setTheme(R.style.LightTheme);
+ }
+
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.feeds);
+
+ setSmallScreen(findViewById(R.id.headlines_fragment) == null);
+
+ if (savedInstanceState == null) {
+ FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+
+ if (m_prefs.getBoolean("enable_cats", false)) {
+ ft.replace(R.id.feeds_fragment, new FeedCategoriesFragment(), FRAG_CATS);
+ } else {
+ ft.replace(R.id.feeds_fragment, new FeedsFragment(), FRAG_FEEDS);
+ }
+
+ ft.commit();
+ } else if (isSmallScreen()) {
+ Fragment frag = getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE);
+ if (frag != null) {
+ FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+ ft.remove(frag);
+ ft.commit();
+ }
+ }
+ }
+
+ public boolean getUnreadOnly() {
+ return m_unreadOnly;
+ }
+
+ @Override
+ protected void initMenu() {
+ super.initMenu();
+ if (m_menu != null) {
+ Fragment ff = getSupportFragmentManager().findFragmentByTag(FRAG_FEEDS);
+ Fragment cf = getSupportFragmentManager().findFragmentByTag(FRAG_CATS);
+ Fragment af = getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE);
+
+ m_menu.setGroupVisible(R.id.menu_group_feeds, ff != null || cf != null);
+
+ m_menu.setGroupVisible(R.id.menu_group_article, af != null);
+
+ HeadlinesFragment hf = (HeadlinesFragment)getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES);
+
+ m_menu.setGroupVisible(R.id.menu_group_headlines, hf != null && hf.getSelectedArticles().size() == 0);
+ m_menu.setGroupVisible(R.id.menu_group_headlines_selection, hf != null && hf.getSelectedArticles().size() != 0);
+ }
+ }
+
+
+ public void onFeedSelected(Feed feed) {
+ FragmentTransaction ft = getSupportFragmentManager()
+ .beginTransaction();
+
+ HeadlinesFragment hf = new HeadlinesFragment(feed);
+
+ if (isSmallScreen()) {
+ ft.replace(R.id.feeds_fragment, hf, FRAG_HEADLINES);
+ ft.addToBackStack(null);
+ } else {
+ ft.replace(R.id.headlines_fragment, hf, FRAG_HEADLINES);
+ }
+ ft.commit();
+ }
+
+ public void onCatSelected(FeedCategory cat, boolean openAsFeed) {
+
+ FragmentTransaction ft = getSupportFragmentManager()
+ .beginTransaction();
+
+ if (!openAsFeed) {
+ FeedsFragment ff = new FeedsFragment(cat);
+
+ ft.replace(R.id.feeds_fragment, ff, FRAG_FEEDS);
+ } else {
+ Feed feed = new Feed(cat.id, cat.title, true);
+ onFeedSelected(feed);
+ }
+
+ ft.addToBackStack(null);
+
+ ft.commit();
+ }
+
+ public void onCatSelected(FeedCategory cat) {
+ onCatSelected(cat, m_prefs.getBoolean("browse_cats_like_feeds", false));
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ default:
+ Log.d(TAG, "onOptionsItemSelected, unhandled id=" + item.getItemId());
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+ @Override
+ protected void loginSuccess() {
+ setLoadingStatus(R.string.blank, false);
+ findViewById(R.id.loading_container).setVisibility(View.GONE);
+
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle out) {
+ super.onSaveInstanceState(out);
+
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ }
+
+ @Override
+ public boolean getUnreadArticlesOnly() {
+ return m_unreadArticlesOnly;
+ }
+
+ @Override
+ public void onArticleListSelectionChange(ArticleList m_selectedArticles) {
+ initMenu();
+ }
+
+ public void onArticleSelected(Article article, boolean open) {
+ if (article.unread) {
+ article.unread = false;
+ saveArticleUnread(article);
+ }
+
+ if (open) {
+ if (isSmallScreen()) {
+ FragmentTransaction ft = getSupportFragmentManager()
+ .beginTransaction();
+
+ Fragment frag = new ArticlePager(article);
+
+ ft.hide(getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES));
+ ft.add(R.id.feeds_fragment, frag, FRAG_ARTICLE);
+ ft.addToBackStack(null);
+
+ ft.commit();
+ } else {
+ Intent intent = new Intent(FeedsActivity.this, HeadlinesActivity.class);
+ intent.putExtra("sessionId", m_sessionId);
+ intent.putExtra("apiLevel", m_apiLevel);
+
+ HeadlinesFragment hf = (HeadlinesFragment)getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES);
+
+ intent.putExtra("feed", hf.getFeed());
+ intent.putParcelableArrayListExtra("articles", hf.getAllArticles());
+ intent.putExtra("activeArticle", article);
+ intent.putExtra("article", article);
+
+ //intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
+
+ startActivityForResult(intent, 0);
+ }
+ } else {
+ HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES);
+ if (hf != null) hf.setActiveArticle(article);
+ }
+ }
+
+ @Override
+ public void onArticleSelected(Article article) {
+ onArticleSelected(article, true);
+ }
+
+}
diff --git a/src/org/fox/ttrss/FeedsEventListener.java b/src/org/fox/ttrss/FeedsEventListener.java new file mode 100644 index 00000000..8e6b7bce --- /dev/null +++ b/src/org/fox/ttrss/FeedsEventListener.java @@ -0,0 +1,5 @@ +package org.fox.ttrss;
+
+public interface FeedsEventListener {
+
+}
diff --git a/src/org/fox/ttrss/FeedsFragment.java b/src/org/fox/ttrss/FeedsFragment.java index 030005fe..1153172c 100644 --- a/src/org/fox/ttrss/FeedsFragment.java +++ b/src/org/fox/ttrss/FeedsFragment.java @@ -45,6 +45,7 @@ import android.util.Log; import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
+import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
@@ -65,7 +66,7 @@ public class FeedsFragment extends Fragment implements OnItemClickListener, OnSh private SharedPreferences m_prefs;
private FeedListAdapter m_adapter;
private FeedList m_feeds = new FeedList();
- private OnlineServices m_onlineServices;
+ private FeedsActivity m_activity;
private Feed m_selectedFeed;
private FeedCategory m_activeCategory;
private static final String ICON_PATH = "/data/org.fox.ttrss/icons/";
@@ -120,6 +121,26 @@ public class FeedsFragment extends Fragment implements OnItemClickListener, OnSh }
}
+
+ @Override
+ public boolean onContextItemSelected(MenuItem item) {
+ AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
+ .getMenuInfo();
+ switch (item.getItemId()) {
+ case R.id.catchup_feed:
+ if (true) {
+ Feed feed = getFeedAtPosition(info.position);
+ if (feed != null) {
+ m_activity.catchupFeed(feed);
+ }
+ }
+ return true;
+
+ default:
+ Log.d(TAG, "onContextItemSelected, unhandled id=" + item.getItemId());
+ return super.onContextItemSelected(item);
+ }
+ }
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
@@ -159,11 +180,6 @@ public class FeedsFragment extends Fragment implements OnItemClickListener, OnSh m_enableFeedIcons = m_prefs.getBoolean("download_feed_icons", false);
- if (m_feeds == null || m_feeds.size() == 0)
- refresh(false);
- else
- getActivity().setProgressBarIndeterminateVisibility(false);
-
return view;
}
@@ -179,12 +195,19 @@ public class FeedsFragment extends Fragment implements OnItemClickListener, OnSh m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
m_prefs.registerOnSharedPreferenceChangeListener(this);
- m_onlineServices = (OnlineServices)activity;
-
- //m_selectedFeed = m_onlineServices.getActiveFeed();
+ m_activity = (FeedsActivity)activity;
}
@Override
+ public void onResume() {
+ super.onResume();
+
+ refresh(false);
+
+ m_activity.initMenu();
+ }
+
+ @Override
public void onSaveInstanceState (Bundle out) {
super.onSaveInstanceState(out);
@@ -200,9 +223,9 @@ public class FeedsFragment extends Fragment implements OnItemClickListener, OnSh if (list != null) {
Feed feed = (Feed)list.getItemAtPosition(position);
- m_onlineServices.onFeedSelected(feed);
+ m_activity.onFeedSelected(feed);
- if (!m_onlineServices.isSmallScreen())
+ if (!m_activity.isSmallScreen())
m_selectedFeed = feed;
m_adapter.notifyDataSetChanged();
@@ -215,8 +238,8 @@ public class FeedsFragment extends Fragment implements OnItemClickListener, OnSh final int catId = (m_activeCategory != null) ? m_activeCategory.id : -4;
- final String sessionId = m_onlineServices.getSessionId();
- final boolean unreadOnly = m_onlineServices.getUnreadOnly();
+ final String sessionId = m_activity.getSessionId();
+ final boolean unreadOnly = m_activity.getUnreadOnly();
FeedsRequest req = new FeedsRequest(getActivity().getApplicationContext(), catId);
@@ -292,7 +315,7 @@ public class FeedsFragment extends Fragment implements OnItemClickListener, OnSh }
};
- final String sessionId = m_onlineServices.getSessionId();
+ final String sessionId = m_activity.getSessionId();
HashMap<String,String> map = new HashMap<String,String>() {
{
@@ -347,7 +370,7 @@ public class FeedsFragment extends Fragment implements OnItemClickListener, OnSh }
if (m_lastError == ApiError.LOGIN_FAILED) {
- m_onlineServices.login();
+ m_activity.login();
} else {
setLoadingStatus(getErrorMessage(), false);
}
@@ -375,7 +398,7 @@ public class FeedsFragment extends Fragment implements OnItemClickListener, OnSh public int getItemViewType(int position) {
Feed feed = items.get(position);
- if (!m_onlineServices.isSmallScreen() && m_selectedFeed != null && feed.id == m_selectedFeed.id) {
+ if (!m_activity.isSmallScreen() && m_selectedFeed != null && feed.id == m_selectedFeed.id) {
return VIEW_SELECTED;
} else {
return VIEW_NORMAL;
@@ -449,7 +472,7 @@ public class FeedsFragment extends Fragment implements OnItemClickListener, OnSh if (m_prefs.getBoolean("sort_feeds_by_unread", false)) {
cmp = new FeedUnreadComparator();
} else {
- if (m_onlineServices.getApiLevel() >= 3) {
+ if (m_activity.getApiLevel() >= 3) {
cmp = new FeedOrderComparator();
} else {
cmp = new FeedTitleComparator();
diff --git a/src/org/fox/ttrss/HeadlinesActivity.java b/src/org/fox/ttrss/HeadlinesActivity.java new file mode 100644 index 00000000..dd2a5a8c --- /dev/null +++ b/src/org/fox/ttrss/HeadlinesActivity.java @@ -0,0 +1,160 @@ +package org.fox.ttrss;
+
+import java.util.ArrayList;
+
+import org.fox.ttrss.types.Article;
+import org.fox.ttrss.types.ArticleList;
+import org.fox.ttrss.types.Feed;
+
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentTransaction;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+
+public class HeadlinesActivity extends OnlineActivity implements HeadlinesEventListener, ArticleEventListener {
+private final String TAG = this.getClass().getSimpleName();
+
+ protected SharedPreferences m_prefs;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ m_prefs = PreferenceManager
+ .getDefaultSharedPreferences(getApplicationContext());
+
+ if (m_prefs.getString("theme", "THEME_DARK").equals("THEME_DARK")) {
+ setTheme(R.style.DarkTheme);
+ } else {
+ setTheme(R.style.LightTheme);
+ }
+
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.headlines);
+
+ if (!isCompatMode()) {
+ getActionBar().setDisplayHomeAsUpEnabled(true);
+ }
+
+ setSmallScreen(findViewById(R.id.headlines_fragment) == null);
+
+ if (savedInstanceState == null) {
+ FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+
+ Intent i = getIntent();
+
+ if (i.getExtras() != null) {
+ Feed feed = i.getParcelableExtra("feed");
+ Article activeArticle = i.getParcelableExtra("activeArticle");
+ Article article = i.getParcelableExtra("article");
+
+ ArrayList<Article> alist = i.getParcelableArrayListExtra("articles");
+ ArticleList articles = new ArticleList();
+
+ for (Article a : alist)
+ articles.add(a);
+
+ HeadlinesFragment hf = new HeadlinesFragment(feed, activeArticle, articles);
+
+ ft.replace(R.id.headlines_fragment, hf, FRAG_HEADLINES);
+
+ ArticlePager af = new ArticlePager(article);
+
+ ft.replace(R.id.article_fragment, af, FRAG_ARTICLE);
+ }
+
+ ft.commit();
+ }
+ }
+
+ @Override
+ protected void loginSuccess() {
+ Log.d(TAG, "loginSuccess");
+
+ setLoadingStatus(R.string.blank, false);
+ findViewById(R.id.loading_container).setVisibility(View.GONE);
+
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle out) {
+ super.onSaveInstanceState(out);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ finish();
+ return true;
+ default:
+ Log.d(TAG, "onOptionsItemSelected, unhandled id=" + item.getItemId());
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ }
+
+ @Override
+ public boolean getUnreadArticlesOnly() {
+ // TODO Auto-generated method stub
+ return true;
+ }
+
+ @Override
+ protected void initMenu() {
+ super.initMenu();
+
+ if (m_menu != null) {
+ m_menu.setGroupVisible(R.id.menu_group_feeds, false);
+
+ HeadlinesFragment hf = (HeadlinesFragment)getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES);
+
+ m_menu.setGroupVisible(R.id.menu_group_headlines, hf != null && hf.getSelectedArticles().size() == 0);
+ m_menu.setGroupVisible(R.id.menu_group_headlines_selection, hf != null && hf.getSelectedArticles().size() != 0);
+
+ Fragment af = getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE);
+
+ m_menu.setGroupVisible(R.id.menu_group_article, af != null);
+ }
+ }
+
+ @Override
+ public void onArticleListSelectionChange(ArticleList m_selectedArticles) {
+ initMenu();
+ }
+
+ @Override
+ public void onArticleSelected(Article article) {
+ onArticleSelected(article, true);
+ }
+
+ @Override
+ public void onArticleSelected(Article article, boolean open) {
+
+ if (open) {
+ FragmentTransaction ft = getSupportFragmentManager()
+ .beginTransaction();
+
+ Fragment frag = new ArticlePager(article);
+
+ ft.replace(R.id.article_fragment, frag, FRAG_ARTICLE);
+ //ft.addToBackStack(null);
+
+ ft.commit();
+ } else {
+ HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES);
+ if (hf != null) hf.setActiveArticle(article);
+ }
+
+ }
+}
diff --git a/src/org/fox/ttrss/HeadlinesEventListener.java b/src/org/fox/ttrss/HeadlinesEventListener.java new file mode 100644 index 00000000..14f0ef92 --- /dev/null +++ b/src/org/fox/ttrss/HeadlinesEventListener.java @@ -0,0 +1,14 @@ +package org.fox.ttrss;
+
+import org.fox.ttrss.types.Article;
+import org.fox.ttrss.types.ArticleList;
+
+public interface HeadlinesEventListener {
+
+ boolean getUnreadArticlesOnly();
+ void onArticleListSelectionChange(ArticleList m_selectedArticles);
+ void onArticleSelected(Article article);
+ void saveArticleUnread(Article article);
+ void onArticleSelected(Article article, boolean b);
+
+}
diff --git a/src/org/fox/ttrss/HeadlinesFragment.java b/src/org/fox/ttrss/HeadlinesFragment.java index 4cb77858..9534db66 100644 --- a/src/org/fox/ttrss/HeadlinesFragment.java +++ b/src/org/fox/ttrss/HeadlinesFragment.java @@ -34,6 +34,7 @@ import android.util.Log; import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
+import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
@@ -70,14 +71,16 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, private boolean m_canLoadMore = false;
private boolean m_combinedMode = true;
private String m_searchQuery = "";
+ private boolean m_noRefresh = false;
private SharedPreferences m_prefs;
private ArticleListAdapter m_adapter;
private ArticleList m_articles = new ArticleList();
private ArticleList m_selectedArticles = new ArticleList();
+ private HeadlinesEventListener m_listener;
- private OnlineServices m_onlineServices;
+ private OnlineActivity m_activity;
private ImageGetter m_dummyGetter = new ImageGetter() {
@@ -87,7 +90,6 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, }
};
-
public ArticleList getSelectedArticles() {
return m_selectedArticles;
}
@@ -96,15 +98,125 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, m_feed = feed;
}
+ public HeadlinesFragment(Feed feed, Article activeArticle, ArticleList articles) {
+ m_feed = feed;
+ m_activeArticle = activeArticle;
+ m_articles = articles;
+ m_noRefresh = true;
+ }
+
public HeadlinesFragment() {
//
}
@Override
+ public boolean onContextItemSelected(MenuItem item) {
+ AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
+ .getMenuInfo();
+
+ switch (item.getItemId()) {
+ case R.id.selection_toggle_marked:
+ if (true) {
+ ArticleList selected = getSelectedArticles();
+
+ if (selected.size() > 0) {
+ for (Article a : selected)
+ a.marked = !a.marked;
+
+ m_activity.toggleArticlesMarked(selected);
+ //updateHeadlines();
+ } else {
+ Article article = getArticleAtPosition(info.position);
+ if (article != null) {
+ article.marked = !article.marked;
+ m_activity.saveArticleMarked(article);
+ //updateHeadlines();
+ }
+ }
+ m_adapter.notifyDataSetChanged();
+ }
+ return true;
+ case R.id.selection_toggle_published:
+ if (true) {
+ ArticleList selected = getSelectedArticles();
+
+ if (selected.size() > 0) {
+ for (Article a : selected)
+ a.published = !a.published;
+
+ m_activity.toggleArticlesPublished(selected);
+ //updateHeadlines();
+ } else {
+ Article article = getArticleAtPosition(info.position);
+ if (article != null) {
+ article.published = !article.published;
+ m_activity.saveArticlePublished(article);
+ //updateHeadlines();
+ }
+ }
+ m_adapter.notifyDataSetChanged();
+ }
+ return true;
+ case R.id.selection_toggle_unread:
+ if (true) {
+ ArticleList selected = getSelectedArticles();
+
+ if (selected.size() > 0) {
+ for (Article a : selected)
+ a.unread = !a.unread;
+
+ m_activity.toggleArticlesUnread(selected);
+ //updateHeadlines();
+ } else {
+ Article article = getArticleAtPosition(info.position);
+ if (article != null) {
+ article.unread = !article.unread;
+ m_activity.saveArticleUnread(article);
+ //updateHeadlines();
+ }
+ }
+ m_adapter.notifyDataSetChanged();
+ }
+ return true;
+ case R.id.share_article:
+ if (true) {
+ Article article = getArticleAtPosition(info.position);
+ if (article != null)
+ m_activity.shareArticle(article);
+ }
+ return true;
+ case R.id.catchup_above:
+ if (true) {
+ Article article = getArticleAtPosition(info.position);
+ if (article != null) {
+ ArticleList articles = getAllArticles();
+ ArticleList tmp = new ArticleList();
+ for (Article a : articles) {
+ a.unread = false;
+ tmp.add(a);
+ if (article.id == a.id)
+ break;
+ }
+ if (tmp.size() > 0) {
+ m_activity.toggleArticlesUnread(tmp);
+ //updateHeadlines();
+ }
+ }
+ m_adapter.notifyDataSetChanged();
+ }
+ return true;
+ default:
+ Log.d(TAG, "onContextItemSelected, unhandled id=" + item.getItemId());
+ return super.onContextItemSelected(item);
+ }
+ }
+
+
+ @Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
- getActivity().getMenuInflater().inflate(R.menu.headlines_menu, menu);
+ getActivity().getMenuInflater().inflate(R.menu.headlines_context_menu, menu);
if (m_selectedArticles.size() > 0) {
menu.setHeaderTitle(R.string.headline_context_multiple);
@@ -116,8 +228,8 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, menu.setGroupVisible(R.id.menu_group_single_article, true);
}
- menu.findItem(R.id.set_labels).setEnabled(m_onlineServices.getApiLevel() >= 1);
- menu.findItem(R.id.article_set_note).setEnabled(m_onlineServices.getApiLevel() >= 1);
+ menu.findItem(R.id.set_labels).setEnabled(m_activity.getApiLevel() >= 1);
+ menu.findItem(R.id.article_set_note).setEnabled(m_activity.getApiLevel() >= 1);
super.onCreateContextMenu(menu, v, menuInfo);
@@ -146,24 +258,32 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, //list.setEmptyView(view.findViewById(R.id.no_headlines));
registerForContextMenu(list);
- if (m_onlineServices.isSmallScreen() || m_onlineServices.isPortrait())
+ if (m_activity.isSmallScreen() || m_activity.isPortrait())
view.findViewById(R.id.headlines_fragment).setPadding(0, 0, 0, 0);
Log.d(TAG, "onCreateView, feed=" + m_feed);
- if (m_feed != null && (m_articles == null || m_articles.size() == 0))
- refresh(false);
- else
- getActivity().setProgressBarIndeterminateVisibility(false);
-
return view;
}
@Override
+ public void onResume() {
+ super.onResume();
+
+ if (!m_noRefresh) {
+ refresh(false);
+ m_noRefresh = false;
+ }
+
+ m_activity.initMenu();
+ }
+
+ @Override
public void onAttach(Activity activity) {
super.onAttach(activity);
m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
- m_onlineServices = (OnlineServices) activity;
+ m_activity = (OnlineActivity) activity;
+ m_listener = (HeadlinesEventListener) activity;
m_combinedMode = m_prefs.getBoolean("combined_mode", false);
}
@@ -179,9 +299,9 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, if (article.id >= 0) {
if (m_combinedMode) {
article.unread = false;
- m_onlineServices.saveArticleUnread(article);
+ m_activity.saveArticleUnread(article);
} else {
- m_onlineServices.onArticleSelected(article);
+ m_listener.onArticleSelected(article);
}
m_activeArticle = article;
@@ -196,8 +316,8 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, HeadlinesRequest req = new HeadlinesRequest(getActivity().getApplicationContext());
- final String sessionId = m_onlineServices.getSessionId();
- final boolean showUnread = m_onlineServices.getUnreadArticlesOnly();
+ final String sessionId = m_activity.getSessionId();
+ final boolean showUnread = m_listener.getUnreadArticlesOnly();
final boolean isCat = m_feed.is_cat;
int skip = 0;
@@ -319,7 +439,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, }
if (m_lastError == ApiError.LOGIN_FAILED) {
- m_onlineServices.login();
+ m_activity.login();
} else {
setLoadingStatus(getErrorMessage(), false);
}
@@ -428,7 +548,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, article.marked = !article.marked;
m_adapter.notifyDataSetChanged();
- m_onlineServices.saveArticleMarked(article);
+ m_activity.saveArticleMarked(article);
}
});
}
@@ -445,7 +565,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, article.published = !article.published;
m_adapter.notifyDataSetChanged();
- m_onlineServices.saveArticlePublished(article);
+ m_activity.saveArticlePublished(article);
}
});
}
@@ -533,7 +653,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, Attachment attachment = (Attachment) spinner.getSelectedItem();
if (attachment != null) {
- m_onlineServices.copyToClipboard(attachment.content_url);
+ m_activity.copyToClipboard(attachment.content_url);
}
}
});
@@ -590,7 +710,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, m_selectedArticles.remove(article);
}
- m_onlineServices.onArticleListSelectionChange(m_selectedArticles);
+ m_listener.onArticleListSelectionChange(m_selectedArticles);
Log.d(TAG, "num selected: " + m_selectedArticles.size());
}
@@ -710,5 +830,9 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, }
}
+ public Feed getFeed() {
+ return m_feed;
+ }
+
}
diff --git a/src/org/fox/ttrss/MainActivity.java b/src/org/fox/ttrss/MainActivity.java deleted file mode 100644 index 1ac736e2..00000000 --- a/src/org/fox/ttrss/MainActivity.java +++ /dev/null @@ -1,2313 +0,0 @@ -package org.fox.ttrss; - -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Timer; -import java.util.TimerTask; - -import org.fox.ttrss.offline.OfflineActivity; -import org.fox.ttrss.offline.OfflineDownloadService; -import org.fox.ttrss.offline.OfflineUploadService; -import org.fox.ttrss.types.Article; -import org.fox.ttrss.types.ArticleList; -import org.fox.ttrss.types.Feed; -import org.fox.ttrss.types.FeedCategory; -import org.fox.ttrss.types.Label; -import org.fox.ttrss.util.AppRater; - -import android.animation.LayoutTransition; -import android.annotation.SuppressLint; -import android.app.ActionBar; -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.DialogInterface.OnMultiChoiceClickListener; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.SharedPreferences; -import android.database.Cursor; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentTransaction; -import android.util.Log; -import android.view.ActionMode; -import android.view.KeyEvent; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.view.Window; -import android.widget.AdapterView.AdapterContextMenuInfo; -import android.widget.ArrayAdapter; -import android.widget.EditText; -import android.widget.SearchView; -import android.widget.ShareActionProvider; -import android.widget.TextView; -import android.widget.Toast; - -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.reflect.TypeToken; - -public class MainActivity extends CommonActivity implements OnlineServices { - private final String TAG = this.getClass().getSimpleName(); - - private SharedPreferences m_prefs; - private String m_themeName = ""; - 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; - private boolean m_unreadOnly = true; - private boolean m_unreadArticlesOnly = true; - private boolean m_enableCats = false; - private int m_apiLevel = 0; - private boolean m_isLoggingIn = false; - private boolean m_isOffline = false; - private int m_offlineModeStatus = 0; - private int m_selectedProduct = -1; - private long m_lastRefresh = 0; - - private ActionMode m_headlinesActionMode; - private HeadlinesActionModeCallback m_headlinesActionModeCallback; - private NavigationListener m_navigationListener; - private NavigationAdapter m_navigationAdapter; - private ArrayList<NavigationEntry> m_navigationEntries = new ArrayList<NavigationEntry>(); - - private class NavigationListener implements ActionBar.OnNavigationListener { - @Override - public boolean onNavigationItemSelected(int itemPosition, long itemId) { - Log.d(TAG, "onNavigationItemSelected: " + itemPosition); - - NavigationEntry entry = m_navigationAdapter.getItem(itemPosition); - entry._onItemSelected(itemPosition, m_navigationAdapter.getCount()-1); - - return false; - } - } - - private class ArticleNavigationEntry extends NavigationEntry { - public ArticleNavigationEntry(Article article) { - super(article.title); - } - - @Override - public void onItemSelected() { - - } - } - - private class RootNavigationEntry extends NavigationEntry { - public RootNavigationEntry(String title) { - super(title); - } - - @Override - public void onItemSelected() { - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - - m_activeFeed = null; - m_selectedArticle = null; - m_activeCategory = null; - - if (isSmallScreen()) { - - if (m_enableCats) { - ft.replace(R.id.fragment_container, new FeedCategoriesFragment(), FRAG_CATS); - } else { - ft.replace(R.id.fragment_container, new FeedsFragment(), FRAG_FEEDS); - } - - Fragment hf = getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - if (hf != null) ft.remove(hf); - - Fragment af = getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); - if (af != null) ft.remove(af); - - } else { - if (m_enableCats) { - ft.replace(R.id.feeds_fragment, new FeedCategoriesFragment(), FRAG_CATS); - } else { - ft.replace(R.id.feeds_fragment, new FeedsFragment(), FRAG_FEEDS); - } - - findViewById(R.id.article_fragment).setVisibility(View.GONE); - findViewById(R.id.feeds_fragment).setVisibility(View.VISIBLE); - - ft.replace(R.id.headlines_fragment, new DummyFragment(), ""); - } - - ft.commit(); - initMainMenu(); - } - } - - private class CategoryNavigationEntry extends NavigationEntry { - FeedCategory m_category = null; - - public CategoryNavigationEntry(FeedCategory category) { - super(category.title); - - m_category = category; - } - - @Override - public void onItemSelected() { - m_selectedArticle = null; - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - - if (isSmallScreen()) { - - Fragment hf = getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - if (hf != null) ft.remove(hf); - - Fragment af = getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); - if (af != null) ft.remove(af); - - if (m_activeFeed.is_cat) { - FeedCategoriesFragment cats = (FeedCategoriesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_CATS); - - if (cats != null) { - ft.show(cats); - cats.setSelectedCategory(null); - } - } else { - FeedsFragment feeds = (FeedsFragment) getSupportFragmentManager().findFragmentByTag(FRAG_FEEDS); - - if (feeds != null) { - ft.show(feeds); - feeds.setSelectedFeed(null); - } - } - - } else { - findViewById(R.id.article_fragment).setVisibility(View.GONE); - findViewById(R.id.feeds_fragment).setVisibility(View.VISIBLE); - - updateHeadlines(); - - //ft.replace(R.id.headlines_fragment, new DummyFragment(), ""); - } - ft.commit(); - - m_activeFeed = null; - refresh(); - initMainMenu(); - } - } - - private class FeedNavigationEntry extends NavigationEntry { - Feed m_feed = null; - - public FeedNavigationEntry(Feed feed) { - super(feed.title); - - m_feed = feed; - } - - @Override - public void onItemSelected() { - - m_selectedArticle = null; - - if (!isSmallScreen()) - findViewById(R.id.article_fragment).setVisibility(View.GONE); - - viewFeed(m_feed, false); - } - } - - private abstract class NavigationEntry { - private String title = null; - private int timesCalled = 0; - - public void _onItemSelected(int position, int size) { - Log.d(TAG, "_onItemSelected; TC=" + timesCalled + " P/S=" + position + "/" + size); - - if (position == size && timesCalled == 0) { - ++timesCalled; - } else { - onItemSelected(); - } - } - - public NavigationEntry(String title) { - this.title = title; - } - - public String toString() { - return title; - } - - public abstract void onItemSelected(); - } - - private class NavigationAdapter extends ArrayAdapter<NavigationEntry> { - public NavigationAdapter(Context context, int textViewResourceId, ArrayList<NavigationEntry> items) { - super(context, textViewResourceId, items); - } - } - - private class HeadlinesActionModeCallback implements ActionMode.Callback { - - @Override - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - return false; - } - - @Override - public void onDestroyActionMode(ActionMode mode) { - deselectAllArticles(); - m_headlinesActionMode = null; - } - - @Override - public boolean onCreateActionMode(ActionMode mode, Menu menu) { - - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.headlines_action_menu, menu); - - return true; - } - - @Override - public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - onOptionsItemSelected(item); - return false; - } - }; - - private BroadcastReceiver m_broadcastReceiver = new BroadcastReceiver() { - - @Override - public void onReceive(Context content, Intent intent) { - - if (intent.getAction().equals(OfflineDownloadService.INTENT_ACTION_SUCCESS)) { - - m_offlineModeStatus = 2; - - switchOffline(); - - } else if (intent.getAction().equals(OfflineUploadService.INTENT_ACTION_SUCCESS)) { - //Log.d(TAG, "offline upload service reports success"); - - refresh(); - - toast(R.string.offline_sync_success); - } - - } - }; - - public void updateHeadlines() { - HeadlinesFragment frag = (HeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - if (frag != null) { - frag.setActiveArticle(m_selectedArticle); - } - } - - @Override - public int getApiLevel() { - return m_apiLevel; - } - - private boolean hasPendingOfflineData() { - try { - Cursor c = getReadableDb().query("articles", - new String[] { "COUNT(*)" }, "modified = 1", null, null, null, - null); - if (c.moveToFirst()) { - int modified = c.getInt(0); - c.close(); - - return modified > 0; - } - } catch (IllegalStateException e) { - // db is closed? ugh - } - - return false; - } - - private boolean hasOfflineData() { - try { - Cursor c = getReadableDb().query("articles", - new String[] { "COUNT(*)" }, null, null, null, null, null); - if (c.moveToFirst()) { - int modified = c.getInt(0); - c.close(); - - return modified > 0; - } - } catch (IllegalStateException e) { - // db is closed? - } - - return false; - } - - @SuppressWarnings({ "unchecked", "serial" }) - public void saveArticleUnread(final Article article) { - ApiRequest req = new ApiRequest(getApplicationContext()); - - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", m_sessionId); - put("op", "updateArticle"); - put("article_ids", String.valueOf(article.id)); - put("mode", article.unread ? "1" : "0"); - put("field", "2"); - } - }; - - req.execute(map); - } - - @SuppressWarnings({ "unchecked", "serial" }) - public void saveArticleMarked(final Article article) { - ApiRequest req = new ApiRequest(getApplicationContext()) { - protected void onPostExecute(JsonElement result) { - toast(article.marked ? R.string.notify_article_marked : R.string.notify_article_unmarked); - } - }; - - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", m_sessionId); - put("op", "updateArticle"); - put("article_ids", String.valueOf(article.id)); - put("mode", article.marked ? "1" : "0"); - put("field", "0"); - } - }; - - req.execute(map); - } - - @SuppressWarnings({ "unchecked", "serial" }) - public void saveArticlePublished(final Article article) { - - ApiRequest req = new ApiRequest(getApplicationContext()) { - protected void onPostExecute(JsonElement result) { - toast(article.published ? R.string.notify_article_published : R.string.notify_article_unpublished); - } - }; - - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", m_sessionId); - put("op", "updateArticle"); - put("article_ids", String.valueOf(article.id)); - put("mode", article.published ? "1" : "0"); - put("field", "1"); - } - }; - - req.execute(map); - } - - @SuppressWarnings({ "unchecked", "serial" }) - public void saveArticleNote(final Article article, final String note) { - ApiRequest req = new ApiRequest(getApplicationContext()) { - protected void onPostExecute(JsonElement result) { - toast(R.string.notify_article_note_set); - } - }; - - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", m_sessionId); - put("op", "updateArticle"); - put("article_ids", String.valueOf(article.id)); - put("mode", "1"); - put("data", note); - put("field", "3"); - } - }; - - req.execute(map); - } - - public static String articlesToIdString(ArticleList articles) { - String tmp = ""; - - for (Article a : articles) - tmp += String.valueOf(a.id) + ","; - - return tmp.replaceAll(",$", ""); - } - - @SuppressWarnings("unchecked") - public void catchupFeed(final Feed feed) { - Log.d(TAG, "catchupFeed=" + feed); - - ApiRequest req = new ApiRequest(getApplicationContext()) { - protected void onPostExecute(JsonElement result) { - refresh(); - } - - }; - - @SuppressWarnings("serial") - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", m_sessionId); - put("op", "catchupFeed"); - put("feed_id", String.valueOf(feed.id)); - if (feed.is_cat) - put("is_cat", "1"); - } - }; - - req.execute(map); - } - - @SuppressWarnings("unchecked") - private void toggleArticlesMarked(final ArticleList articles) { - ApiRequest req = new ApiRequest(getApplicationContext()); - - @SuppressWarnings("serial") - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", m_sessionId); - put("op", "updateArticle"); - put("article_ids", articlesToIdString(articles)); - put("mode", "2"); - put("field", "0"); - } - }; - - req.execute(map); - } - - @SuppressWarnings("unchecked") - private void toggleArticlesUnread(final ArticleList articles) { - ApiRequest req = new ApiRequest(getApplicationContext()); - - @SuppressWarnings("serial") - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", m_sessionId); - put("op", "updateArticle"); - put("article_ids", articlesToIdString(articles)); - put("mode", "2"); - put("field", "2"); - } - }; - - req.execute(map); - refresh(); - } - - @SuppressWarnings("unchecked") - private void toggleArticlesPublished(final ArticleList articles) { - ApiRequest req = new ApiRequest(getApplicationContext()); - - @SuppressWarnings("serial") - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", m_sessionId); - put("op", "updateArticle"); - put("article_ids", articlesToIdString(articles)); - put("mode", "2"); - put("field", "1"); - } - }; - - req.execute(map); - } - - private class RefreshTask extends TimerTask { - - @Override - public void run() { - ConnectivityManager cm = (ConnectivityManager) getApplicationContext() - .getSystemService(Context.CONNECTIVITY_SERVICE); - - if (cm.getBackgroundDataSetting()) { - NetworkInfo networkInfo = cm.getActiveNetworkInfo(); - if (networkInfo != null && networkInfo.isAvailable() - && networkInfo.isConnected()) { - - runOnUiThread(new Runnable() { - @Override - public void run() { - refresh(); - } - }); - - } - } - } - } - - private synchronized void refresh() { - Date date = new Date(); - - if (m_sessionId != null && date.getTime() - m_lastRefresh > 5000) { - - FeedsFragment ff = (FeedsFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_FEEDS); - - if (ff != null) { - Log.d(TAG, "Refreshing feeds/" + m_activeFeed); - ff.refresh(true); - } - - FeedCategoriesFragment cf = (FeedCategoriesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_CATS); - - if (cf != null) { - Log.d(TAG, "Refreshing categories/" + m_activeCategory); - cf.refresh(true); - } - - m_lastRefresh = date.getTime(); - } - } - - /* private synchronized void refreshHeadlines() { - if (m_sessionId != null) { - HeadlinesFragment frag = (HeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - - Log.d(TAG, "Refreshing headlines..."); - - if (frag != null) { - frag.refresh(true); - } - } - } */ - - private void setUnreadOnly(boolean unread) { - m_unreadOnly = unread; - m_lastRefresh = 0; - refresh(); - } - - @Override - public boolean getUnreadOnly() { - return m_unreadOnly; - } - - @Override - public boolean getUnreadArticlesOnly() { - return m_unreadArticlesOnly; - } - - @Override - public String getSessionId() { - return m_sessionId; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - m_prefs = PreferenceManager - .getDefaultSharedPreferences(getApplicationContext()); - - if (m_prefs.getString("theme", "THEME_DARK").equals("THEME_DARK")) { - setTheme(R.style.DarkTheme); - } else { - setTheme(R.style.LightTheme); - } - - super.onCreate(savedInstanceState); - - if (OfflineDownloadService.INTENT_ACTION_CANCEL.equals(getIntent().getAction())) { - cancelOfflineSync(); - } - - //Log.d(TAG, "started with intent action=" + intentAction); - - requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); - - m_themeName = m_prefs.getString("theme", "THEME_DARK"); - - if (savedInstanceState != null) { - m_sessionId = savedInstanceState.getString("sessionId"); - m_unreadOnly = savedInstanceState.getBoolean("unreadOnly"); - m_activeFeed = savedInstanceState.getParcelable("activeFeed"); - m_selectedArticle = savedInstanceState - .getParcelable("selectedArticle"); - m_unreadArticlesOnly = savedInstanceState - .getBoolean("unreadArticlesOnly"); - m_activeCategory = savedInstanceState - .getParcelable("activeCategory"); - m_apiLevel = savedInstanceState.getInt("apiLevel"); - m_offlineModeStatus = savedInstanceState.getInt("offlineModeStatus"); - } - - m_enableCats = m_prefs.getBoolean("enable_cats", false); - - setContentView(R.layout.main); - - setSmallScreen(findViewById(R.id.headlines_fragment) == null); - - IntentFilter filter = new IntentFilter(); - filter.addAction(OfflineDownloadService.INTENT_ACTION_SUCCESS); - filter.addAction(OfflineUploadService.INTENT_ACTION_SUCCESS); - filter.addCategory(Intent.CATEGORY_DEFAULT); - - registerReceiver(m_broadcastReceiver, filter); - - SharedPreferences localPrefs = getSharedPreferences("localprefs", Context.MODE_PRIVATE); - - m_isOffline = localPrefs.getBoolean("offline_mode_active", false); - - Log.d(TAG, "m_isOffline=" + m_isOffline); - - if (!isCompatMode()) { - - if (!isSmallScreen()) { - findViewById(R.id.feeds_fragment).setVisibility(m_selectedArticle != null && (isPortrait() || isSmallTablet()) ? View.GONE : View.VISIBLE); - findViewById(R.id.article_fragment).setVisibility(m_selectedArticle != null ? View.VISIBLE : View.GONE); - } - - LayoutTransition transitioner = new LayoutTransition(); - ((ViewGroup) findViewById(R.id.fragment_container)).setLayoutTransition(transitioner); - - m_navigationAdapter = new NavigationAdapter(this, android.R.layout.simple_spinner_dropdown_item, m_navigationEntries); - - m_headlinesActionModeCallback = new HeadlinesActionModeCallback(); - m_navigationListener = new NavigationListener(); - - getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); - getActionBar().setListNavigationCallbacks(m_navigationAdapter, m_navigationListener); - } - - if (isSmallScreen()) { - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - - // temporary workaround against viewpager going a bit crazy when restoring after rotation - if (m_selectedArticle != null) { - ft.remove(getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE)); - m_selectedArticle = null; - } - - if (m_activeFeed != null) { - if (m_activeFeed.is_cat) { - ft.hide(getSupportFragmentManager().findFragmentByTag(FRAG_CATS)); - } else { - ft.hide(getSupportFragmentManager().findFragmentByTag(FRAG_FEEDS)); - } - } - ft.commit(); - } - - if (m_isOffline) { - Intent offline = new Intent(MainActivity.this, - OfflineActivity.class); - startActivity(offline); - finish(); - } else { - //AppRater.showRateDialog(this, null); - AppRater.appLaunched(this); - - if (m_sessionId != null) { - loginSuccess(); - } else { - //login(); -- handled in onResume() - } - } - } - - private void switchOffline() { - if (m_offlineModeStatus == 2) { - - AlertDialog.Builder builder = new AlertDialog.Builder( - MainActivity.this) - .setMessage(R.string.dialog_offline_success) - .setPositiveButton(R.string.dialog_offline_go, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - - m_offlineModeStatus = 0; - - SharedPreferences localPrefs = getSharedPreferences("localprefs", Context.MODE_PRIVATE); - SharedPreferences.Editor editor = localPrefs.edit(); - editor.putBoolean("offline_mode_active", true); - editor.commit(); - - Intent refresh = new Intent( - MainActivity.this, - OfflineActivity.class); - startActivity(refresh); - finish(); - } - }) - .setNegativeButton(R.string.dialog_cancel, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - - m_offlineModeStatus = 0; - - } - }); - - AlertDialog dlg = builder.create(); - dlg.show(); - - } else if (m_offlineModeStatus == 0) { - - AlertDialog.Builder builder = new AlertDialog.Builder(this) - .setMessage(R.string.dialog_offline_switch_prompt) - .setPositiveButton(R.string.dialog_offline_go, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - - if (m_sessionId != null) { - Log.d(TAG, "offline: starting"); - - m_offlineModeStatus = 1; - - Intent intent = new Intent( - MainActivity.this, - OfflineDownloadService.class); - intent.putExtra("sessionId", m_sessionId); - - startService(intent); - } - } - }) - .setNegativeButton(R.string.dialog_cancel, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - // - } - }); - - AlertDialog dlg = builder.create(); - dlg.show(); - } else if (m_offlineModeStatus == 1) { - cancelOfflineSync(); - } - } - - private void cancelOfflineSync() { - AlertDialog.Builder builder = new AlertDialog.Builder(this) - .setMessage(R.string.dialog_offline_sync_in_progress) - .setNegativeButton(R.string.dialog_offline_sync_stop, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - - if (m_sessionId != null) { - Log.d(TAG, "offline: stopping"); - - m_offlineModeStatus = 0; - - Intent intent = new Intent( - MainActivity.this, - OfflineDownloadService.class); - - stopService(intent); - - dialog.dismiss(); - - restart(); - } - } - }) - .setPositiveButton(R.string.dialog_offline_sync_continue, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - - dialog.dismiss(); - - restart(); - } - }); - - AlertDialog dlg = builder.create(); - dlg.show(); - } - - private void switchOfflineSuccess() { - logout(); - // setLoadingStatus(R.string.blank, false); - - SharedPreferences.Editor editor = m_prefs.edit(); - editor.putBoolean("offline_mode_active", true); - editor.commit(); - - Intent offline = new Intent(MainActivity.this, OfflineActivity.class); - startActivity(offline); - finish(); - - } - - private void setLoadingStatus(int status, boolean showProgress) { - TextView tv = (TextView) findViewById(R.id.loading_message); - - if (tv != null) { - tv.setText(status); - } - - setProgressBarIndeterminateVisibility(showProgress); - } - - @Override - public void onSaveInstanceState(Bundle out) { - super.onSaveInstanceState(out); - - out.putString("sessionId", m_sessionId); - out.putBoolean("unreadOnly", m_unreadOnly); - out.putParcelable("activeFeed", m_activeFeed); - out.putParcelable("selectedArticle", m_selectedArticle); - out.putBoolean("unreadArticlesOnly", m_unreadArticlesOnly); - out.putParcelable("activeCategory", m_activeCategory); - out.putInt("apiLevel", m_apiLevel); - out.putInt("offlineModeStatus", m_offlineModeStatus); - } - - @Override - public void onResume() { - super.onResume(); - - boolean needRefresh = !m_prefs.getString("theme", "THEME_DARK").equals( - m_themeName) - || m_prefs.getBoolean("enable_cats", false) != m_enableCats; - - if (needRefresh) { - restart(); - } else if (m_sessionId != null) { - m_refreshTask = new RefreshTask(); - m_refreshTimer = new Timer("Refresh"); - - m_refreshTimer.schedule(m_refreshTask, 60 * 1000L, 120 * 1000L); - } else { - if (!m_isLoggingIn) { - login(); - } - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.main_menu, menu); - - m_menu = menu; - - initMainMenu(); - - MenuItem item = menu.findItem(R.id.show_feeds); - - if (getUnreadOnly()) { - item.setTitle(R.string.menu_all_feeds); - } else { - item.setTitle(R.string.menu_unread_feeds); - } - - /* - * item = menu.findItem(R.id.show_all_articles); - * - * if (getUnreadArticlesOnly()) { - * item.setTitle(R.string.show_all_articles); } else { - * item.setTitle(R.string.show_unread_articles); } - */ - - return true; - } - - private void setMenuLabel(int id, int labelId) { - MenuItem mi = m_menu.findItem(id); - - if (mi != null) { - mi.setTitle(labelId); - } - } - - @Override - public void onBackPressed() { - goBack(true); - } - - private void closeCategory() { - m_activeCategory = null; - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - if (isSmallScreen()) { - ft.replace(R.id.fragment_container, new FeedCategoriesFragment(), FRAG_CATS); - } else { - ft.replace(R.id.feeds_fragment, new FeedCategoriesFragment(), FRAG_CATS); - } - ft.commit(); - - initMainMenu(); - refresh(); - } - - private void deselectAllArticles() { - HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - - if (hf != null) { - ArticleList selected = hf.getSelectedArticles(); - if (selected.size() > 0) { - selected.clear(); - initMainMenu(); - updateHeadlines(); - } - } - } - - private void goBack(boolean allowQuit) { - if (isSmallScreen()) { - if (m_selectedArticle != null) { - closeArticle(); - } else if (m_activeFeed != null) { - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - if (m_activeFeed.is_cat) { - - Fragment headlines = getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - FeedCategoriesFragment cats = (FeedCategoriesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_CATS); - - ft.show(cats); - ft.remove(headlines); - - } else { - Fragment headlines = getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - FeedsFragment feeds = (FeedsFragment) getSupportFragmentManager().findFragmentByTag(FRAG_FEEDS); - - ft.show(feeds); - ft.remove(headlines); - } - ft.commit(); - - m_activeFeed = null; - - refresh(); - - initMainMenu(); - - } else if (m_activeCategory != null) { - closeCategory(); - } else if (allowQuit) { - finish(); - } - } else { - if (m_selectedArticle != null) { - closeArticle(); - refresh(); - } else if (m_activeFeed != null) { - closeFeed(); - } else if (m_activeCategory != null) { - closeCategory(); - } else if (allowQuit) { - finish(); - } - } - } - - - private void closeFeed() { - if (m_activeFeed != null) { - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - ft.replace(R.id.headlines_fragment, new DummyFragment(), ""); - ft.commit(); - - if (m_activeFeed.is_cat) { - FeedCategoriesFragment cats = (FeedCategoriesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_CATS); - if (cats != null) { - cats.setSelectedCategory(null); - } - } else { - FeedsFragment feeds = (FeedsFragment) getSupportFragmentManager().findFragmentByTag(FRAG_FEEDS); - if (feeds != null) { - feeds.setSelectedFeed(null); - } - } - - m_activeFeed = null; - - initMainMenu(); - } - } - - - @SuppressWarnings("unchecked") - @Override - public boolean onOptionsItemSelected(MenuItem item) { - final HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - - switch (item.getItemId()) { - case R.id.close_feed: - if (m_activeFeed != null) { - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - ft.replace(R.id.headlines_fragment, new DummyFragment(), ""); - ft.commit(); - - if (m_activeFeed.is_cat) { - FeedCategoriesFragment cats = (FeedCategoriesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_CATS); - cats.setSelectedCategory(null); - } else { - FeedsFragment feeds = (FeedsFragment) getSupportFragmentManager().findFragmentByTag(FRAG_FEEDS); - feeds.setSelectedFeed(null); - } - - m_activeFeed = null; - - initMainMenu(); - } - return true; - case R.id.close_article: - closeArticle(); - return true; - case android.R.id.home: - goBack(false); - return true; - case R.id.search: - if (hf != null && isCompatMode()) { - Dialog dialog = new Dialog(this); - - final EditText edit = new EditText(this); - - AlertDialog.Builder builder = new AlertDialog.Builder(this) - .setTitle(R.string.search) - .setPositiveButton(getString(R.string.search), - new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, - int which) { - - String query = edit.getText().toString().trim(); - - hf.setSearchQuery(query); - - } - }) - .setNegativeButton(getString(R.string.cancel), - new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, - int which) { - - // - - } - }).setView(edit); - - dialog = builder.create(); - dialog.show(); - } - - return true; - case R.id.preferences: - Intent intent = new Intent(MainActivity.this, - PreferencesActivity.class); - startActivityForResult(intent, 0); - return true; - case R.id.update_feeds: - m_lastRefresh = 0; - refresh(); - return true; - case R.id.logout: - logout(); - return true; - case R.id.login: - login(); - return true; - case R.id.go_offline: - switchOffline(); - return true; - case R.id.article_set_note: - if (m_selectedArticle != null) { - editArticleNote(m_selectedArticle); - } - return true; - case R.id.headlines_select: - if (hf != null) { - Dialog dialog = new Dialog(this); - AlertDialog.Builder builder = new AlertDialog.Builder(this) - .setTitle(R.string.headlines_select_dialog) - .setSingleChoiceItems( - new String[] { - getString(R.string.headlines_select_all), - getString(R.string.headlines_select_unread), - getString(R.string.headlines_select_none) }, - 0, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, - int which) { - switch (which) { - case 0: - hf.setSelection(HeadlinesFragment.ArticlesSelection.ALL); - break; - case 1: - hf.setSelection(HeadlinesFragment.ArticlesSelection.UNREAD); - break; - case 2: - hf.setSelection(HeadlinesFragment.ArticlesSelection.NONE); - break; - } - dialog.cancel(); - initMainMenu(); - } - }); - - dialog = builder.create(); - dialog.show(); - } - return true; - case R.id.headlines_mark_as_read: - if (hf != null) { - ArticleList articles = hf.getUnreadArticles(); - - for (Article a : articles) - a.unread = false; - - updateHeadlines(); - - ApiRequest req = new ApiRequest(getApplicationContext()); - - final String articleIds = articlesToIdString(articles); - - @SuppressWarnings("serial") - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", m_sessionId); - put("op", "updateArticle"); - put("article_ids", articleIds); - put("mode", "0"); - put("field", "2"); - } - }; - - req.execute(map); - refresh(); - } - return true; - case R.id.share_article: - if (android.os.Build.VERSION.SDK_INT < 14) { - shareArticle(m_selectedArticle); - } - return true; - case R.id.toggle_marked: - if (m_selectedArticle != null) { - m_selectedArticle.marked = !m_selectedArticle.marked; - saveArticleMarked(m_selectedArticle); - updateHeadlines(); - } - return true; - case R.id.selection_select_none: - deselectAllArticles(); - return true; - case R.id.selection_toggle_unread: - if (hf != null) { - ArticleList selected = hf.getSelectedArticles(); - - if (selected.size() > 0) { - for (Article a : selected) - a.unread = !a.unread; - - toggleArticlesUnread(selected); - updateHeadlines(); - } - refresh(); - } - return true; - case R.id.selection_toggle_marked: - if (hf != null) { - ArticleList selected = hf.getSelectedArticles(); - - if (selected.size() > 0) { - for (Article a : selected) - a.marked = !a.marked; - - toggleArticlesMarked(selected); - updateHeadlines(); - } - } - return true; - case R.id.selection_toggle_published: - if (hf != null) { - ArticleList selected = hf.getSelectedArticles(); - - if (selected.size() > 0) { - for (Article a : selected) - a.published = !a.published; - - toggleArticlesPublished(selected); - updateHeadlines(); - } - } - return true; - case R.id.toggle_published: - if (m_selectedArticle != null) { - m_selectedArticle.published = !m_selectedArticle.published; - saveArticlePublished(m_selectedArticle); - updateHeadlines(); - } - return true; - case R.id.catchup_above: - if (hf != null) { - if (m_selectedArticle != null) { - ArticleList articles = hf.getAllArticles(); - ArticleList tmp = new ArticleList(); - for (Article a : articles) { - a.unread = false; - tmp.add(a); - if (m_selectedArticle.id == a.id) - break; - } - if (tmp.size() > 0) { - toggleArticlesUnread(tmp); - updateHeadlines(); - } - } - } - return true; - case R.id.set_unread: - if (m_selectedArticle != null) { - m_selectedArticle.unread = true; - saveArticleUnread(m_selectedArticle); - updateHeadlines(); - } - return true; - case R.id.show_feeds: - setUnreadOnly(!getUnreadOnly()); - - if (getUnreadOnly()) { - item.setTitle(R.string.menu_all_feeds); - } else { - item.setTitle(R.string.menu_unread_feeds); - } - - return true; - case R.id.set_labels: - if (m_selectedArticle != null) { - editArticleLabels(m_selectedArticle); - } - return true; - default: - Log.d(TAG, - "onOptionsItemSelected, unhandled id=" + item.getItemId()); - return super.onOptionsItemSelected(item); - } - } - - private void editArticleNote(final Article article) { - String note = ""; - - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(article.title); - final EditText topicEdit = new EditText(this); - topicEdit.setText(note); - builder.setView(topicEdit); - - builder.setPositiveButton(R.string.article_set_note, new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - saveArticleNote(article, topicEdit.getText().toString().trim()); - article.published = true; - saveArticlePublished(article); - updateHeadlines(); - } - }); - - builder.setNegativeButton(R.string.dialog_cancel, new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - // - } - }); - - AlertDialog dialog = builder.create(); - dialog.show(); - } - - private void editArticleLabels(Article article) { - final int articleId = article.id; - - ApiRequest req = new ApiRequest(getApplicationContext()) { - @Override - protected void onPostExecute(JsonElement result) { - if (result != null) { - Type listType = new TypeToken<List<Label>>() {}.getType(); - final List<Label> labels = new Gson().fromJson(result, listType); - - CharSequence[] items = new CharSequence[labels.size()]; - final int[] itemIds = new int[labels.size()]; - boolean[] checkedItems = new boolean[labels.size()]; - - for (int i = 0; i < labels.size(); i++) { - items[i] = labels.get(i).caption; - itemIds[i] = labels.get(i).id; - checkedItems[i] = labels.get(i).checked; - } - - Dialog dialog = new Dialog(MainActivity.this); - AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this) - .setTitle(R.string.article_set_labels) - .setMultiChoiceItems(items, checkedItems, new OnMultiChoiceClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which, final boolean isChecked) { - final int labelId = itemIds[which]; - - @SuppressWarnings("serial") - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", m_sessionId); - put("op", "setArticleLabel"); - put("label_id", String.valueOf(labelId)); - put("article_ids", String.valueOf(articleId)); - if (isChecked) put("assign", "true"); - } - }; - - ApiRequest req = new ApiRequest(m_context); - req.execute(map); - - } - }).setPositiveButton(R.string.dialog_close, new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.cancel(); - } - }); - - dialog = builder.create(); - dialog.show(); - - } - } - }; - - @SuppressWarnings("serial") - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", m_sessionId); - put("op", "getLabels"); - put("article_id", String.valueOf(articleId)); - } - }; - - req.execute(map); - } - - private Intent getShareIntent(Article article) { - Intent intent = new Intent(Intent.ACTION_SEND); - - intent.setType("text/plain"); - intent.putExtra(Intent.EXTRA_SUBJECT, article.title); - intent.putExtra(Intent.EXTRA_TEXT, article.link); - - return intent; - } - - private void shareArticle(Article article) { - if (article != null) { - - Intent intent = getShareIntent(article); - - startActivity(Intent.createChooser(intent, - getString(R.string.share_article))); - } - } - - private void closeArticle() { - m_selectedArticle = null; - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - - if (isSmallScreen()) { - ft.remove(getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE)); - ft.show(getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES)); - } else { - findViewById(R.id.feeds_fragment).setVisibility(View.VISIBLE); - findViewById(R.id.article_fragment).setVisibility(View.GONE); - ft.replace(R.id.article_fragment, new DummyFragment(), FRAG_ARTICLE); - - updateHeadlines(); - } - ft.commit(); - - initMainMenu(); - } - - private void updateTitle() { - if (!isCompatMode()) { - - m_navigationAdapter.clear(); - - if (m_activeCategory != null || (m_activeFeed != null && (isSmallScreen() || isPortrait()))) { - getActionBar().setDisplayShowTitleEnabled(false); - getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); - - m_navigationAdapter.add(new RootNavigationEntry(getString(R.string.app_name))); - - if (m_activeCategory != null) - m_navigationAdapter.add(new CategoryNavigationEntry(m_activeCategory)); - - if (m_activeFeed != null) - m_navigationAdapter.add(new FeedNavigationEntry(m_activeFeed)); - - //if (m_selectedArticle != null) - // m_navigationAdapter.add(new ArticleNavigationEntry(m_selectedArticle)); - - getActionBar().setSelectedNavigationItem(getActionBar().getNavigationItemCount()); - - } else { - getActionBar().setDisplayShowTitleEnabled(true); - getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); - getActionBar().setTitle(R.string.app_name); - } - - if (isSmallScreen()) { - getActionBar().setDisplayHomeAsUpEnabled(m_selectedArticle != null || m_activeCategory != null || m_activeFeed != null); - } else { - getActionBar().setDisplayHomeAsUpEnabled(m_selectedArticle != null || m_activeCategory != null); - } - - } else { - if (m_activeFeed != null) { - setTitle(m_activeFeed.title); - } else if (m_activeCategory != null) { - setTitle(m_activeCategory.title); - } else { - setTitle(R.string.app_name); - } - } - } - - @SuppressLint({ "NewApi", "NewApi", "NewApi" }) - public void initMainMenu() { - if (m_menu != null) { - - m_menu.setGroupVisible(R.id.menu_group_feeds, false); - m_menu.setGroupVisible(R.id.menu_group_headlines, false); - m_menu.setGroupVisible(R.id.menu_group_headlines_selection, false); - m_menu.setGroupVisible(R.id.menu_group_article, false); - - if (m_sessionId != null) { - - m_menu.setGroupVisible(R.id.menu_group_logged_in, true); - m_menu.setGroupVisible(R.id.menu_group_logged_out, false); - - HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - - int numSelected = 0; - - if (hf != null) - numSelected = hf.getSelectedArticles().size(); - - if (numSelected != 0) { - if (isCompatMode()) { - m_menu.setGroupVisible(R.id.menu_group_headlines_selection, true); - } else { - if (m_headlinesActionMode == null) - m_headlinesActionMode = startActionMode(m_headlinesActionModeCallback); - } - - } else if (m_selectedArticle != null) { - m_menu.setGroupVisible(R.id.menu_group_article, true); - m_menu.findItem(R.id.close_article).setVisible(!isSmallScreen()); - - if (android.os.Build.VERSION.SDK_INT >= 14) { - ShareActionProvider shareProvider = (ShareActionProvider) m_menu.findItem(R.id.share_article).getActionProvider(); - - if (m_selectedArticle != null) { - Log.d(TAG, "setting up share provider"); - shareProvider.setShareIntent(getShareIntent(m_selectedArticle)); - - if (!m_prefs.getBoolean("tablet_article_swipe", false) && !isSmallScreen()) { - m_menu.findItem(R.id.share_article).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); - } - } - } - - } else if (m_activeFeed != null) { - m_menu.setGroupVisible(R.id.menu_group_headlines, true); - m_menu.findItem(R.id.close_feed).setVisible(!isSmallScreen()); - - MenuItem search = m_menu.findItem(R.id.search); - - search.setEnabled(m_apiLevel >= 2); - - if (!isCompatMode()) { - SearchView searchView = (SearchView) search.getActionView(); - searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { - private String query = ""; - - @Override - public boolean onQueryTextSubmit(String query) { - HeadlinesFragment frag = (HeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - - if (frag != null) { - frag.setSearchQuery(query); - this.query = query; - } - - return false; - } - - @Override - public boolean onQueryTextChange(String newText) { - if (newText.equals("") && !newText.equals(this.query)) { - HeadlinesFragment frag = (HeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - - if (frag != null) { - frag.setSearchQuery(newText); - this.query = newText; - } - } - - return false; - } - }); - } - - } else { - m_menu.setGroupVisible(R.id.menu_group_feeds, true); - } - - if (numSelected == 0 && m_headlinesActionMode != null) { - m_headlinesActionMode.finish(); - } - - //Log.d(TAG, "isCompatMode=" + isCompatMode()); - - - m_menu.findItem(R.id.set_labels).setEnabled(m_apiLevel >= 1); - m_menu.findItem(R.id.article_set_note).setEnabled(m_apiLevel >= 1); - - } else { - m_menu.setGroupVisible(R.id.menu_group_logged_in, false); - m_menu.setGroupVisible(R.id.menu_group_logged_out, true); - } - } - - updateTitle(); - } - - @Override - public void onPause() { - super.onPause(); - - if (m_refreshTask != null) { - m_refreshTask.cancel(); - m_refreshTask = null; - } - - if (m_refreshTimer != null) { - m_refreshTimer.cancel(); - m_refreshTimer = null; - } - - } - - @Override - public void onDestroy() { - super.onDestroy(); - - unregisterReceiver(m_broadcastReceiver); - } - - private void syncOfflineData() { - Log.d(TAG, "offlineSync: starting"); - - Intent intent = new Intent( - MainActivity.this, - OfflineUploadService.class); - - intent.putExtra("sessionId", m_sessionId); - - startService(intent); - } - - private void loginSuccess() { - findViewById(R.id.loading_container).setVisibility(View.GONE); - setProgressBarIndeterminateVisibility(false); - - m_isOffline = false; - - initMainMenu(); - - if (m_refreshTask != null) { - m_refreshTask.cancel(); - m_refreshTask = null; - } - - if (m_refreshTimer != null) { - m_refreshTimer.cancel(); - m_refreshTimer = null; - } - - m_refreshTask = new RefreshTask(); - m_refreshTimer = new Timer("Refresh"); - - m_refreshTimer.schedule(m_refreshTask, 60 * 1000L, 120 * 1000L); - } - - - private class LoginRequest extends ApiRequest { - public LoginRequest(Context context) { - super(context); - } - - @SuppressWarnings("unchecked") - protected void onPostExecute(JsonElement result) { - m_isLoggingIn = false; - - if (result != null) { - try { - JsonObject content = result.getAsJsonObject(); - if (content != null) { - m_sessionId = content.get("session_id").getAsString(); - - Log.d(TAG, "Authenticated!"); - - ApiRequest req = new ApiRequest(m_context) { - protected void onPostExecute(JsonElement result) { - m_apiLevel = 0; - - if (result != null) { - try { - m_apiLevel = result.getAsJsonObject() - .get("level").getAsInt(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - Log.d(TAG, "Received API level: " + m_apiLevel); - - if (hasPendingOfflineData()) - syncOfflineData(); - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - - if (m_enableCats) { - FeedCategoriesFragment frag = new FeedCategoriesFragment(); - if (isSmallScreen()) { - ft.replace(R.id.fragment_container, frag, FRAG_CATS); - } else { - ft.replace(R.id.feeds_fragment, frag, FRAG_CATS); - } - - } else { - FeedsFragment frag = new FeedsFragment(); - if (isSmallScreen()) { - ft.replace(R.id.fragment_container, frag, FRAG_FEEDS); - } else { - ft.replace(R.id.feeds_fragment, frag, FRAG_FEEDS); - } - } - - try { - ft.commit(); - } catch (IllegalStateException e) { - e.printStackTrace(); - } - - loginSuccess(); - - } - }; - - @SuppressWarnings("serial") - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", m_sessionId); - put("op", "getApiLevel"); - } - }; - - req.execute(map); - - setLoadingStatus(R.string.loading_message, true); - - return; - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - - m_sessionId = null; - - setLoadingStatus(getErrorMessage(), false); - - if (hasOfflineData()) { - - AlertDialog.Builder builder = new AlertDialog.Builder( - MainActivity.this) - .setMessage(R.string.dialog_offline_prompt) - .setPositiveButton(R.string.dialog_offline_go, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - switchOfflineSuccess(); - } - }) - .setNegativeButton(R.string.dialog_cancel, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - // - } - }); - - AlertDialog dlg = builder.create(); - dlg.show(); - } - - // m_menu.findItem(R.id.login).setVisible(true); - } - - } - - @Override - public void onFeedSelected(Feed feed) { - viewFeed(feed, false); - } - - public void viewFeed(Feed feed, boolean append) { - Log.d(TAG, "viewFeeed/" + feed.id); - - m_activeFeed = feed; - - if (!append) { - //m_selectedArticle = null; - - if (m_menu != null) { - MenuItem search = m_menu.findItem(R.id.search); - - if (search != null && !isCompatMode()) { - SearchView sv = (SearchView) search.getActionView(); - sv.setQuery("", false); - } - } - - HeadlinesFragment hf = new HeadlinesFragment(feed); - - FragmentTransaction ft = getSupportFragmentManager() - .beginTransaction(); - - if (isSmallScreen()) { - Fragment cats = getSupportFragmentManager().findFragmentByTag(FRAG_CATS); - if (cats != null) ft.hide(cats); - - Fragment feeds = getSupportFragmentManager().findFragmentByTag(FRAG_FEEDS); - if (feeds != null) ft.hide(feeds); - - ft.add(R.id.fragment_container, hf, FRAG_HEADLINES); - } else { - //findViewById(R.id.article_fragment).setVisibility(View.GONE); - findViewById(R.id.headlines_fragment).setVisibility(View.VISIBLE); - ft.replace(R.id.headlines_fragment, hf, FRAG_HEADLINES); - } - ft.commit(); - - } else { - HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - if (hf != null) { - hf.refresh(true); - } - } - - initMainMenu(); - } - - public void viewCategory(FeedCategory cat, boolean openAsFeed) { - - Log.d(TAG, "viewCategory"); - - if (!openAsFeed) { - m_activeCategory = cat; - - FeedsFragment frag = new FeedsFragment(cat); - - FragmentTransaction ft = getSupportFragmentManager() - .beginTransaction(); - - if (isSmallScreen()) { - ft.replace(R.id.fragment_container, frag, FRAG_FEEDS); - } else { - ft.replace(R.id.feeds_fragment, frag, FRAG_FEEDS); - } - ft.commit(); - - } else { - Feed feed = new Feed(cat.id, cat.title, true); - - if (m_menu != null) { - MenuItem search = m_menu.findItem(R.id.search); - - if (search != null && !isCompatMode()) { - SearchView sv = (SearchView) search.getActionView(); - sv.setQuery("", false); - } - } - viewFeed(feed, false); - } - - initMainMenu(); - } - - @Override - public void onArticleSelected(Article article) { - openArticle(article); - } - - public void openArticle(Article article) { - m_selectedArticle = article; - - if (article.unread) { - article.unread = false; - saveArticleUnread(article); - } - - initMainMenu(); - - Fragment frag; - - if (isSmallScreen() || m_prefs.getBoolean("tablet_article_swipe", false)) { - frag = new ArticlePager(article); - } else { - frag = new ArticleFragment(article); - } - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - if (isSmallScreen()) { - ft.hide(getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES)); - ft.add(R.id.fragment_container, frag, FRAG_ARTICLE); - } else { - findViewById(R.id.feeds_fragment).setVisibility(isPortrait() || isSmallTablet() ? View.GONE : View.VISIBLE); - findViewById(R.id.article_fragment).setVisibility(View.VISIBLE); - ft.replace(R.id.article_fragment, frag, FRAG_ARTICLE); - - if (!isPortrait()) refresh(); - } - ft.commit(); - } - - /* private Feed getActiveFeed() { - return m_activeFeed; - } - - private FeedCategory getActiveCategory() { - return m_activeCategory; - } */ - - private void logout() { - if (m_refreshTask != null) { - m_refreshTask.cancel(); - m_refreshTask = null; - } - - if (m_refreshTimer != null) { - m_refreshTimer.cancel(); - m_refreshTimer = null; - } - - m_sessionId = null; - - findViewById(R.id.loading_container).setVisibility(View.VISIBLE); - - TextView tv = (TextView) findViewById(R.id.loading_message); - - if (tv != null) { - tv.setText(R.string.login_ready); - } - - initMainMenu(); - } - - @Override - @SuppressWarnings({ "unchecked", "serial" }) - public void login() { - - logout(); - - if (m_prefs.getString("ttrss_url", "").trim().length() == 0) { - - setLoadingStatus(R.string.login_need_configure, false); - - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setMessage(R.string.dialog_need_configure_prompt) - .setCancelable(false) - .setPositiveButton(R.string.dialog_open_preferences, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - // launch preferences - - Intent intent = new Intent(MainActivity.this, - PreferencesActivity.class); - startActivityForResult(intent, 0); - } - }) - .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - dialog.cancel(); - } - }); - AlertDialog alert = builder.create(); - alert.show(); - - } else { - - LoginRequest ar = new LoginRequest(getApplicationContext()); - - HashMap<String, String> map = new HashMap<String, String>() { - { - put("op", "login"); - put("user", m_prefs.getString("login", "").trim()); - put("password", m_prefs.getString("password", "").trim()); - } - }; - - ar.execute(map); - - setLoadingStatus(R.string.login_in_progress, true); - - m_isLoggingIn = true; - } - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - AdapterContextMenuInfo info = (AdapterContextMenuInfo) item - .getMenuInfo(); - - HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - FeedsFragment ff = (FeedsFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_FEEDS); - FeedCategoriesFragment cf = (FeedCategoriesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_CATS); - - switch (item.getItemId()) { - case R.id.article_link_copy: - if (true) { - Article article = null; - - if (m_selectedArticle != null) { - article = m_selectedArticle; - } else if (info != null) { - article = hf.getArticleAtPosition(info.position); - } - - if (article != null) { - copyToClipboard(article.link); - } - } - return true; - case R.id.article_link_share: - if (m_selectedArticle != null) { - shareArticle(m_selectedArticle); - } - return true; - case R.id.set_labels: - if (true) { - Article article = null; - - if (m_selectedArticle != null) { - article = m_selectedArticle; - } else if (info != null) { - article = hf.getArticleAtPosition(info.position); - } - - if (article != null) { - editArticleLabels(article); - } - } - return true; - case R.id.article_set_note: - if (true) { - Article article = null; - - if (m_selectedArticle != null) { - article = m_selectedArticle; - } else if (info != null) { - article = hf.getArticleAtPosition(info.position); - } - - if (article != null) { - editArticleNote(article); - } - } - return true; - case R.id.browse_articles: - if (cf != null) { - FeedCategory cat = cf.getCategoryAtPosition(info.position); - if (cat != null) { - viewCategory(cat, true); - cf.setSelectedCategory(cat); - } - } - return true; - case R.id.browse_feeds: - if (cf != null) { - FeedCategory cat = cf.getCategoryAtPosition(info.position); - if (cat != null) { - viewCategory(cat, false); - cf.setSelectedCategory(cat); - } - } - return true; - case R.id.catchup_category: - if (cf != null) { - FeedCategory cat = cf.getCategoryAtPosition(info.position); - if (cat != null) { - catchupFeed(new Feed(cat.id, cat.title, true)); - } - } - return true; - case R.id.catchup_feed: - if (ff != null) { - Feed feed = ff.getFeedAtPosition(info.position); - if (feed != null) { - catchupFeed(feed); - } - } - return true; - case R.id.selection_toggle_marked: - if (hf != null) { - ArticleList selected = hf.getSelectedArticles(); - - if (selected.size() > 0) { - for (Article a : selected) - a.marked = !a.marked; - - toggleArticlesMarked(selected); - updateHeadlines(); - } else { - Article article = hf.getArticleAtPosition(info.position); - if (article != null) { - article.marked = !article.marked; - saveArticleMarked(article); - updateHeadlines(); - } - } - } - return true; - case R.id.selection_toggle_published: - if (hf != null) { - ArticleList selected = hf.getSelectedArticles(); - - if (selected.size() > 0) { - for (Article a : selected) - a.published = !a.published; - - toggleArticlesPublished(selected); - updateHeadlines(); - } else { - Article article = hf.getArticleAtPosition(info.position); - if (article != null) { - article.published = !article.published; - saveArticlePublished(article); - updateHeadlines(); - } - } - } - return true; - case R.id.selection_toggle_unread: - if (hf != null) { - ArticleList selected = hf.getSelectedArticles(); - - if (selected.size() > 0) { - for (Article a : selected) - a.unread = !a.unread; - - toggleArticlesUnread(selected); - updateHeadlines(); - } else { - Article article = hf.getArticleAtPosition(info.position); - if (article != null) { - article.unread = !article.unread; - saveArticleUnread(article); - updateHeadlines(); - } - } - } - return true; - case R.id.share_article: - if (hf != null) { - Article article = hf.getArticleAtPosition(info.position); - if (article != null) - shareArticle(article); - } - return true; - case R.id.catchup_above: - if (hf != null) { - Article article = hf.getArticleAtPosition(info.position); - if (article != null) { - ArticleList articles = hf.getAllArticles(); - ArticleList tmp = new ArticleList(); - for (Article a : articles) { - a.unread = false; - tmp.add(a); - if (article.id == a.id) - break; - } - if (tmp.size() > 0) { - toggleArticlesUnread(tmp); - updateHeadlines(); - } - } - } - return true; - /* - * case R.id.set_unread: if (hf != null) { Article article = - * hf.getArticleAtPosition(info.position); if (article != null) { - * article.unread = true; saveArticleUnread(article); } } break; - */ - default: - Log.d(TAG, - "onContextItemSelected, unhandled id=" + item.getItemId()); - return super.onContextItemSelected(item); - } - } - - private Article getRelativeArticle(Article article, RelativeArticle ra) { - HeadlinesFragment frag = (HeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - if (frag != null) { - ArticleList articles = frag.getAllArticles(); - for (int i = 0; i < articles.size(); i++) { - Article a = articles.get(i); - - if (a.id == article.id) { - if (ra == RelativeArticle.AFTER) { - try { - return articles.get(i + 1); - } catch (IndexOutOfBoundsException e) { - return null; - } - } else { - try { - return articles.get(i - 1); - } catch (IndexOutOfBoundsException e) { - return null; - } - } - } - } - } - return null; - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - int action = event.getAction(); - int keyCode = event.getKeyCode(); - switch (keyCode) { - case KeyEvent.KEYCODE_VOLUME_DOWN: - if (action == KeyEvent.ACTION_DOWN) { - HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - - if (hf != null && m_activeFeed != null) { - Article base = hf.getActiveArticle(); - - Article next = base != null ? getRelativeArticle(base, - RelativeArticle.AFTER) : hf.getArticleAtPosition(0); - - if (next != null) { - hf.setActiveArticle(next); - - boolean combinedMode = m_prefs.getBoolean( - "combined_mode", false); - - if (combinedMode || m_selectedArticle == null) { - next.unread = false; - saveArticleUnread(next); - } else { - openArticle(next); - } - } - } - } - return true; - case KeyEvent.KEYCODE_VOLUME_UP: - if (action == KeyEvent.ACTION_UP) { - HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - - if (hf != null && m_activeFeed != null) { - Article base = hf.getActiveArticle(); - - Article prev = base != null ? getRelativeArticle(base, - RelativeArticle.BEFORE) : hf - .getArticleAtPosition(0); - - if (prev != null) { - hf.setActiveArticle(prev); - - boolean combinedMode = m_prefs.getBoolean( - "combined_mode", false); - - if (combinedMode || m_selectedArticle == null) { - prev.unread = false; - saveArticleUnread(prev); - } else { - openArticle(prev); - } - } - } - - } - return true; - default: - return super.dispatchKeyEvent(event); - } - } - - @Override - public void onCatSelected(FeedCategory cat) { - Log.d(TAG, "onCatSelected"); - boolean browse = m_prefs.getBoolean("browse_cats_like_feeds", false); - - viewCategory(cat, browse && cat.id >= 0); - } - - @Override - public void setSelectedArticle(Article article) { - m_selectedArticle = article; - updateHeadlines(); - initMainMenu(); - } - - public void restart() { - Intent refresh = new Intent(MainActivity.this, MainActivity.class); - refresh.putExtra("sessionId", m_sessionId); - startActivity(refresh); - finish(); - } - - @Override - public void onArticleListSelectionChange(ArticleList selection) { - initMainMenu(); - } -}
\ No newline at end of file diff --git a/src/org/fox/ttrss/OnlineActivity.java b/src/org/fox/ttrss/OnlineActivity.java new file mode 100644 index 00000000..71c4a278 --- /dev/null +++ b/src/org/fox/ttrss/OnlineActivity.java @@ -0,0 +1,526 @@ +package org.fox.ttrss;
+
+import java.util.HashMap;
+
+import org.fox.ttrss.types.Article;
+import org.fox.ttrss.types.ArticleList;
+import org.fox.ttrss.types.Feed;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.support.v4.app.FragmentTransaction;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.Window;
+import android.widget.SearchView;
+
+public class OnlineActivity extends CommonActivity {
+ private final String TAG = this.getClass().getSimpleName();
+
+ protected String m_sessionId;
+ protected SharedPreferences m_prefs;
+ protected int m_apiLevel = 0;
+ protected Menu m_menu;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ m_prefs = PreferenceManager
+ .getDefaultSharedPreferences(getApplicationContext());
+
+ if (m_prefs.getString("theme", "THEME_DARK").equals("THEME_DARK")) {
+ setTheme(R.style.DarkTheme);
+ } else {
+ setTheme(R.style.LightTheme);
+ }
+
+ super.onCreate(savedInstanceState);
+
+ requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+
+ setProgressBarIndeterminateVisibility(false);
+
+ if (getIntent().getExtras() != null) {
+ Intent i = getIntent();
+
+ m_sessionId = i.getStringExtra("sessionId");
+ m_apiLevel = i.getIntExtra("apiLevel", -1);
+ }
+
+ if (savedInstanceState != null) {
+ m_sessionId = savedInstanceState.getString("sessionId");
+ m_apiLevel = savedInstanceState.getInt("apiLevel");
+ }
+
+ Log.d(TAG, "m_sessionId=" + m_sessionId);
+ Log.d(TAG, "m_apiLevel=" + m_apiLevel);
+
+ setContentView(R.layout.online);
+ }
+
+ protected void login() {
+ if (m_prefs.getString("ttrss_url", "").trim().length() == 0) {
+
+ setLoadingStatus(R.string.login_need_configure, false);
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setMessage(R.string.dialog_need_configure_prompt)
+ .setCancelable(false)
+ .setPositiveButton(R.string.dialog_open_preferences, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ // launch preferences
+
+ Intent intent = new Intent(OnlineActivity.this,
+ PreferencesActivity.class);
+ startActivityForResult(intent, 0);
+ }
+ })
+ .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ dialog.cancel();
+ }
+ });
+ AlertDialog alert = builder.create();
+ alert.show();
+
+ } else {
+
+ LoginRequest ar = new LoginRequest(getApplicationContext());
+
+ HashMap<String, String> map = new HashMap<String, String>() {
+ {
+ put("op", "login");
+ put("user", m_prefs.getString("login", "").trim());
+ put("password", m_prefs.getString("password", "").trim());
+ }
+ };
+
+ ar.execute(map);
+
+ setLoadingStatus(R.string.login_in_progress, true);
+ }
+ }
+
+ protected void loginSuccess() {
+ setLoadingStatus(R.string.blank, false);
+ findViewById(R.id.loading_container).setVisibility(View.GONE);
+
+ initMenu();
+
+ Intent intent = new Intent(OnlineActivity.this, FeedsActivity.class);
+ intent.putExtra("sessionId", m_sessionId);
+ intent.putExtra("apiLevel", m_apiLevel);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
+
+ startActivityForResult(intent, 0);
+
+ finish();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.logout:
+ logout();
+ return true;
+ case R.id.login:
+ login();
+ return true;
+ case R.id.preferences:
+ Intent intent = new Intent(OnlineActivity.this,
+ PreferencesActivity.class);
+ startActivityForResult(intent, 0);
+ return true;
+ default:
+ Log.d(TAG, "onOptionsItemSelected, unhandled id=" + item.getItemId());
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+ protected void logout() {
+ m_sessionId = null;
+
+ findViewById(R.id.loading_container).setVisibility(View.VISIBLE);
+ setLoadingStatus(R.string.login_ready, false);
+
+ initMenu();
+ }
+
+ protected void loginFailure() {
+ m_sessionId = null;
+ initMenu();
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle out) {
+ super.onSaveInstanceState(out);
+
+ out.putString("sessionId", m_sessionId);
+ out.putInt("apiLevel", m_apiLevel);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ if (m_sessionId == null) {
+ login();
+ } else {
+ loginSuccess();
+ }
+ }
+
+ public Menu getMenu() {
+ return m_menu;
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.main_menu, menu);
+
+ m_menu = menu;
+
+ initMenu();
+
+ return true;
+ }
+
+ protected String getSessionId() {
+ return m_sessionId;
+ }
+
+ protected int getApiLevel() {
+ return m_apiLevel;
+ }
+
+ @SuppressWarnings({ "unchecked", "serial" })
+ public void saveArticleUnread(final Article article) {
+ ApiRequest req = new ApiRequest(getApplicationContext());
+
+ HashMap<String, String> map = new HashMap<String, String>() {
+ {
+ put("sid", m_sessionId);
+ put("op", "updateArticle");
+ put("article_ids", String.valueOf(article.id));
+ put("mode", article.unread ? "1" : "0");
+ put("field", "2");
+ }
+ };
+
+ req.execute(map);
+ }
+
+ @SuppressWarnings({ "unchecked", "serial" })
+ public void saveArticleMarked(final Article article) {
+ ApiRequest req = new ApiRequest(getApplicationContext()) {
+ protected void onPostExecute(JsonElement result) {
+ toast(article.marked ? R.string.notify_article_marked : R.string.notify_article_unmarked);
+ }
+ };
+
+ HashMap<String, String> map = new HashMap<String, String>() {
+ {
+ put("sid", m_sessionId);
+ put("op", "updateArticle");
+ put("article_ids", String.valueOf(article.id));
+ put("mode", article.marked ? "1" : "0");
+ put("field", "0");
+ }
+ };
+
+ req.execute(map);
+ }
+
+ @SuppressWarnings({ "unchecked", "serial" })
+ public void saveArticlePublished(final Article article) {
+
+ ApiRequest req = new ApiRequest(getApplicationContext()) {
+ protected void onPostExecute(JsonElement result) {
+ toast(article.published ? R.string.notify_article_published : R.string.notify_article_unpublished);
+ }
+ };
+
+ HashMap<String, String> map = new HashMap<String, String>() {
+ {
+ put("sid", m_sessionId);
+ put("op", "updateArticle");
+ put("article_ids", String.valueOf(article.id));
+ put("mode", article.published ? "1" : "0");
+ put("field", "1");
+ }
+ };
+
+ req.execute(map);
+ }
+
+ @SuppressWarnings({ "unchecked", "serial" })
+ public void saveArticleNote(final Article article, final String note) {
+ ApiRequest req = new ApiRequest(getApplicationContext()) {
+ protected void onPostExecute(JsonElement result) {
+ toast(R.string.notify_article_note_set);
+ }
+ };
+
+ HashMap<String, String> map = new HashMap<String, String>() {
+ {
+ put("sid", m_sessionId);
+ put("op", "updateArticle");
+ put("article_ids", String.valueOf(article.id));
+ put("mode", "1");
+ put("data", note);
+ put("field", "3");
+ }
+ };
+
+ req.execute(map);
+ }
+
+ public static String articlesToIdString(ArticleList articles) {
+ String tmp = "";
+
+ for (Article a : articles)
+ tmp += String.valueOf(a.id) + ",";
+
+ return tmp.replaceAll(",$", "");
+ }
+
+ public void shareArticle(Article article) {
+ if (article != null) {
+
+ Intent intent = getShareIntent(article);
+
+ startActivity(Intent.createChooser(intent,
+ getString(R.string.share_article)));
+ }
+ }
+
+ private Intent getShareIntent(Article article) {
+ Intent intent = new Intent(Intent.ACTION_SEND);
+
+ intent.setType("text/plain");
+ intent.putExtra(Intent.EXTRA_SUBJECT, article.title);
+ intent.putExtra(Intent.EXTRA_TEXT, article.link);
+
+ return intent;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void catchupFeed(final Feed feed) {
+ Log.d(TAG, "catchupFeed=" + feed);
+
+ ApiRequest req = new ApiRequest(getApplicationContext()) {
+ protected void onPostExecute(JsonElement result) {
+ // refresh?
+ }
+ };
+
+ @SuppressWarnings("serial")
+ HashMap<String, String> map = new HashMap<String, String>() {
+ {
+ put("sid", m_sessionId);
+ put("op", "catchupFeed");
+ put("feed_id", String.valueOf(feed.id));
+ if (feed.is_cat)
+ put("is_cat", "1");
+ }
+ };
+
+ req.execute(map);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void toggleArticlesMarked(final ArticleList articles) {
+ ApiRequest req = new ApiRequest(getApplicationContext());
+
+ @SuppressWarnings("serial")
+ HashMap<String, String> map = new HashMap<String, String>() {
+ {
+ put("sid", m_sessionId);
+ put("op", "updateArticle");
+ put("article_ids", articlesToIdString(articles));
+ put("mode", "2");
+ put("field", "0");
+ }
+ };
+
+ req.execute(map);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void toggleArticlesUnread(final ArticleList articles) {
+ ApiRequest req = new ApiRequest(getApplicationContext());
+
+ @SuppressWarnings("serial")
+ HashMap<String, String> map = new HashMap<String, String>() {
+ {
+ put("sid", m_sessionId);
+ put("op", "updateArticle");
+ put("article_ids", articlesToIdString(articles));
+ put("mode", "2");
+ put("field", "2");
+ }
+ };
+
+ req.execute(map);
+ //refresh();
+ }
+
+ @SuppressWarnings("unchecked")
+ public void toggleArticlesPublished(final ArticleList articles) {
+ ApiRequest req = new ApiRequest(getApplicationContext());
+
+ @SuppressWarnings("serial")
+ HashMap<String, String> map = new HashMap<String, String>() {
+ {
+ put("sid", m_sessionId);
+ put("op", "updateArticle");
+ put("article_ids", articlesToIdString(articles));
+ put("mode", "2");
+ put("field", "1");
+ }
+ };
+
+ req.execute(map);
+ }
+
+
+ protected void initMenu() {
+ Log.d(TAG, "initMenu:" + m_menu);
+
+ if (m_menu != null) {
+ if (m_sessionId != null) {
+ m_menu.setGroupVisible(R.id.menu_group_logged_in, true);
+ m_menu.setGroupVisible(R.id.menu_group_logged_out, false);
+ } else {
+ m_menu.setGroupVisible(R.id.menu_group_logged_in, false);
+ m_menu.setGroupVisible(R.id.menu_group_logged_out, true);
+ }
+
+ m_menu.setGroupVisible(R.id.menu_group_headlines, false);
+ m_menu.setGroupVisible(R.id.menu_group_headlines_selection, false);
+ m_menu.setGroupVisible(R.id.menu_group_article, false);
+ m_menu.setGroupVisible(R.id.menu_group_feeds, false);
+
+ m_menu.findItem(R.id.set_labels).setEnabled(m_apiLevel >= 1);
+ m_menu.findItem(R.id.article_set_note).setEnabled(m_apiLevel >= 1);
+
+ m_menu.findItem(R.id.close_feed).setVisible(!isSmallScreen());
+ m_menu.findItem(R.id.close_article).setVisible(!isSmallScreen());
+
+ MenuItem search = m_menu.findItem(R.id.search);
+ search.setEnabled(m_apiLevel >= 2);
+
+ if (!isCompatMode()) {
+ SearchView searchView = (SearchView) search.getActionView();
+ searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
+ private String query = "";
+
+ @Override
+ public boolean onQueryTextSubmit(String query) {
+ HeadlinesFragment frag = (HeadlinesFragment) getSupportFragmentManager()
+ .findFragmentByTag(FRAG_HEADLINES);
+
+ if (frag != null) {
+ frag.setSearchQuery(query);
+ this.query = query;
+ }
+
+ return false;
+ }
+
+ @Override
+ public boolean onQueryTextChange(String newText) {
+ if (newText.equals("") && !newText.equals(this.query)) {
+ HeadlinesFragment frag = (HeadlinesFragment) getSupportFragmentManager()
+ .findFragmentByTag(FRAG_HEADLINES);
+
+ if (frag != null) {
+ frag.setSearchQuery(newText);
+ this.query = newText;
+ }
+ }
+
+ return false;
+ }
+ });
+ }
+ }
+ }
+
+ private class LoginRequest extends ApiRequest {
+ public LoginRequest(Context context) {
+ super(context);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void onPostExecute(JsonElement result) {
+ if (result != null) {
+ try {
+ JsonObject content = result.getAsJsonObject();
+ if (content != null) {
+ m_sessionId = content.get("session_id").getAsString();
+
+ Log.d(TAG, "Authenticated!");
+
+ ApiRequest req = new ApiRequest(m_context) {
+ protected void onPostExecute(JsonElement result) {
+ m_apiLevel = 0;
+
+ if (result != null) {
+ try {
+ m_apiLevel = result.getAsJsonObject()
+ .get("level").getAsInt();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ Log.d(TAG, "Received API level: " + m_apiLevel);
+
+ FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+
+ loginSuccess();
+ return;
+ }
+ };
+
+ @SuppressWarnings("serial")
+ HashMap<String, String> map = new HashMap<String, String>() {
+ {
+ put("sid", m_sessionId);
+ put("op", "getApiLevel");
+ }
+ };
+
+ req.execute(map);
+
+ setLoadingStatus(R.string.loading_message, true);
+
+ return;
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ m_sessionId = null;
+ setLoadingStatus(getErrorMessage(), false);
+
+ loginFailure();
+ }
+
+ }
+}
diff --git a/src/org/fox/ttrss/OnlineServices.java b/src/org/fox/ttrss/OnlineServices.java deleted file mode 100644 index 112f9722..00000000 --- a/src/org/fox/ttrss/OnlineServices.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.fox.ttrss;
-
-import org.fox.ttrss.types.Article;
-import org.fox.ttrss.types.ArticleList;
-import org.fox.ttrss.types.Feed;
-import org.fox.ttrss.types.FeedCategory;
-
-public interface OnlineServices {
- public enum RelativeArticle { BEFORE, AFTER };
-
- public void saveArticleUnread(final Article article);
- public void saveArticleMarked(final Article article);
- public void saveArticlePublished(final Article article);
- public void setSelectedArticle(Article article);
- public boolean getUnreadArticlesOnly();
-
- public void onCatSelected(FeedCategory cat);
- public void onFeedSelected(Feed feed);
- public void onArticleSelected(Article article);
- public void onArticleListSelectionChange(ArticleList selection);
-
- //public void initMainMenu();
- public void login();
- public String getSessionId();
- public boolean isSmallScreen();
- public boolean getUnreadOnly();
- public int getApiLevel();
- public boolean isPortrait();
-
- public void copyToClipboard(String str);
-}
-
diff --git a/src/org/fox/ttrss/offline/OfflineActivity.java b/src/org/fox/ttrss/offline/OfflineActivity.java deleted file mode 100644 index 4e48a4da..00000000 --- a/src/org/fox/ttrss/offline/OfflineActivity.java +++ /dev/null @@ -1,1523 +0,0 @@ -package org.fox.ttrss.offline; - -import java.util.ArrayList; - -import org.fox.ttrss.CommonActivity; -import org.fox.ttrss.DummyFragment; -import org.fox.ttrss.FeedCategoriesFragment; -import org.fox.ttrss.FeedsFragment; -import org.fox.ttrss.MainActivity; -import org.fox.ttrss.OnlineServices; -import org.fox.ttrss.OnlineServices.RelativeArticle; -import org.fox.ttrss.PreferencesActivity; -import org.fox.ttrss.R; - -import android.animation.LayoutTransition; -import android.app.ActionBar; -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.NotificationManager; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.Intent; -import android.content.SharedPreferences; -import android.database.Cursor; -import android.database.sqlite.SQLiteStatement; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.provider.BaseColumns; -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentTransaction; -import android.util.Log; -import android.view.ActionMode; -import android.view.KeyEvent; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView.AdapterContextMenuInfo; -import android.widget.ArrayAdapter; -import android.widget.EditText; -import android.widget.SearchView; -import android.widget.ShareActionProvider; -import android.widget.Toast; - -public class OfflineActivity extends CommonActivity implements - OfflineServices { - private final String TAG = this.getClass().getSimpleName(); - - private SharedPreferences m_prefs; - private String m_themeName = ""; - private Menu m_menu; - private boolean m_unreadOnly = true; - private boolean m_unreadArticlesOnly = true; - private boolean m_enableCats = false; - - private int m_activeFeedId = 0; - private boolean m_activeFeedIsCat = false; - private int m_activeCatId = -1; - private int m_selectedArticleId = 0; - - private ActionMode m_headlinesActionMode; - private HeadlinesActionModeCallback m_headlinesActionModeCallback; - private NavigationListener m_navigationListener; - private NavigationAdapter m_navigationAdapter; - private ArrayList<NavigationEntry> m_navigationEntries = new ArrayList<NavigationEntry>(); - - private class RootNavigationEntry extends NavigationEntry { - public RootNavigationEntry(String title) { - super(title); - } - - @Override - public void onItemSelected() { - - m_activeFeedId = 0; - m_selectedArticleId = 0; - m_activeCatId = -1; - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - - if (isSmallScreen()) { - - if (m_enableCats) { - ft.replace(R.id.fragment_container, new OfflineFeedCategoriesFragment(), FRAG_CATS); - } else { - ft.replace(R.id.fragment_container, new OfflineFeedsFragment(), FRAG_FEEDS); - } - - Fragment hf = getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - if (hf != null) ft.remove(hf); - - Fragment af = getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); - if (af != null) ft.remove(af); - - } else { - if (m_enableCats) { - ft.replace(R.id.feeds_fragment, new OfflineFeedCategoriesFragment(), FRAG_CATS); - } else { - ft.replace(R.id.feeds_fragment, new OfflineFeedsFragment(), FRAG_FEEDS); - } - - ft.replace(R.id.headlines_fragment, new DummyFragment(), ""); - - findViewById(R.id.feeds_fragment).setVisibility(View.VISIBLE); - //findViewById(R.id.article_fragment).setVisibility(View.GONE); - - ft.replace(R.id.article_fragment, new DummyFragment(), ""); - } - - ft.commit(); - - initMainMenu(); - } - } - - private class CategoryNavigationEntry extends NavigationEntry { - int m_category = -1; - - public CategoryNavigationEntry(int category, String title) { - super(title); - - m_category = category; - } - - @Override - public void onItemSelected() { - m_selectedArticleId = 0; - m_activeFeedId = 0; - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - - if (isSmallScreen()) { - - Fragment hf = getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - if (hf != null) ft.remove(hf); - - Fragment af = getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); - if (af != null) ft.remove(af); - - if (m_activeFeedIsCat) { - ft.replace(R.id.fragment_container, new OfflineFeedCategoriesFragment()); - } else { - ft.replace(R.id.fragment_container, new OfflineFeedsFragment(m_category)); - } - - } else { - ft.replace(R.id.article_fragment, new DummyFragment(), ""); - - findViewById(R.id.feeds_fragment).setVisibility(View.VISIBLE); - //findViewById(R.id.article_fragment).setVisibility(View.GONE); - - //ft.replace(R.id.headlines_fragment, new DummyFragment(), ""); - } - - ft.commit(); - - m_activeFeedId = 0; - refreshViews(); - initMainMenu(); - } - } - - - private class FeedNavigationEntry extends NavigationEntry { - int m_feed = 0; - - public FeedNavigationEntry(int feed, String title) { - super(title); - - m_feed = feed; - } - - @Override - public void onItemSelected() { - - m_selectedArticleId = 0; - - if (!isSmallScreen()) - findViewById(R.id.article_fragment).setVisibility(View.GONE); - - viewFeed(m_feed, false); - } - } - - private abstract class NavigationEntry { - private String title = null; - private int timesCalled = 0; - - public void _onItemSelected(int position, int size) { - Log.d(TAG, "_onItemSelected; TC=" + timesCalled + " P/S=" + position + "/" + size); - - if (position == size && timesCalled == 0) { - ++timesCalled; - } else { - onItemSelected(); - } - } - - public NavigationEntry(String title) { - this.title = title; - } - - public String toString() { - return title; - } - - public abstract void onItemSelected(); - } - - private class NavigationAdapter extends ArrayAdapter<NavigationEntry> { - public NavigationAdapter(Context context, int textViewResourceId, ArrayList<NavigationEntry> items) { - super(context, textViewResourceId, items); - } - } - - private class NavigationListener implements ActionBar.OnNavigationListener { - @Override - public boolean onNavigationItemSelected(int itemPosition, long itemId) { - Log.d(TAG, "onNavigationItemSelected: " + itemPosition); - - NavigationEntry entry = m_navigationAdapter.getItem(itemPosition); - entry._onItemSelected(itemPosition, m_navigationAdapter.getCount()-1); - - return false; - } - } - - private class HeadlinesActionModeCallback implements ActionMode.Callback { - - @Override - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - return false; - } - - @Override - public void onDestroyActionMode(ActionMode mode) { - deselectAllArticles(); - m_headlinesActionMode = null; - } - - @Override - public boolean onCreateActionMode(ActionMode mode, Menu menu) { - - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.headlines_action_menu, menu); - - return true; - } - - @Override - public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - onOptionsItemSelected(item); - return false; - } - }; - - @Override - public void onCreate(Bundle savedInstanceState) { - m_prefs = PreferenceManager - .getDefaultSharedPreferences(getApplicationContext()); - - if (m_prefs.getString("theme", "THEME_DARK").equals("THEME_DARK")) { - setTheme(R.style.DarkTheme); - } else { - setTheme(R.style.LightTheme); - } - - super.onCreate(savedInstanceState); - - //requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); - - NotificationManager nmgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); - nmgr.cancel(OfflineDownloadService.NOTIFY_DOWNLOADING); - - m_themeName = m_prefs.getString("theme", "THEME_DARK"); - - if (savedInstanceState != null) { - m_unreadOnly = savedInstanceState.getBoolean("unreadOnly"); - m_unreadArticlesOnly = savedInstanceState - .getBoolean("unreadArticlesOnly"); - m_activeFeedId = savedInstanceState.getInt("offlineActiveFeedId"); - m_selectedArticleId = savedInstanceState.getInt("offlineArticleId"); - m_activeFeedIsCat = savedInstanceState.getBoolean("activeFeedIsCat"); - m_activeCatId = savedInstanceState.getInt("activeCatId"); - } - - m_enableCats = m_prefs.getBoolean("enable_cats", false); - - setContentView(R.layout.main); - - setSmallScreen(findViewById(R.id.headlines_fragment) == null); - - if (!isCompatMode()) { - if (!isSmallScreen()) { - findViewById(R.id.feeds_fragment).setVisibility(m_selectedArticleId != 0 && (isPortrait() || isSmallTablet()) ? View.GONE : View.VISIBLE); - findViewById(R.id.article_fragment).setVisibility(m_selectedArticleId != 0 ? View.VISIBLE : View.GONE); - } - - LayoutTransition transitioner = new LayoutTransition(); - ((ViewGroup) findViewById(R.id.fragment_container)).setLayoutTransition(transitioner); - - m_navigationAdapter = new NavigationAdapter(this, android.R.layout.simple_spinner_dropdown_item, m_navigationEntries); - - m_headlinesActionModeCallback = new HeadlinesActionModeCallback(); - m_navigationListener = new NavigationListener(); - - getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); - getActionBar().setListNavigationCallbacks(m_navigationAdapter, m_navigationListener); - - m_headlinesActionModeCallback = new HeadlinesActionModeCallback(); - } - - initMainMenu(); - - findViewById(R.id.loading_container).setVisibility(View.GONE); - - if (isSmallScreen()) { - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - - // temporary workaround against viewpager going a bit crazy when restoring after rotation - if (m_selectedArticleId != 0) { - ft.remove(getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE)); - m_selectedArticleId = 0; - } - ft.commit(); - } - - if (m_activeFeedId == 0 && !m_activeFeedIsCat) { - FragmentTransaction ft = getSupportFragmentManager() - .beginTransaction(); - - Fragment frag = null; - String tag = null; - - if (m_enableCats) { - frag = new OfflineFeedCategoriesFragment(); - tag = FRAG_CATS; - } else { - frag = new OfflineFeedsFragment(); - tag = FRAG_FEEDS; - } - - if (isSmallScreen()) { - ft.replace(R.id.fragment_container, frag, tag); - } else { - ft.replace(R.id.feeds_fragment, frag, tag); - } - - ft.commit(); - } - - - } - - private void switchOnline() { - SharedPreferences localPrefs = getSharedPreferences("localprefs", Context.MODE_PRIVATE); - SharedPreferences.Editor editor = localPrefs.edit(); - editor.putBoolean("offline_mode_active", false); - editor.commit(); - - Intent refresh = new Intent(this, MainActivity.class); - startActivity(refresh); - finish(); - } - - @Override - public int getActiveFeedId() { - return m_activeFeedId; - } - - /* private void setLoadingStatus(int status, boolean showProgress) { - TextView tv = (TextView) findViewById(R.id.loading_message); - - if (tv != null) { - tv.setText(status); - } - - setProgressBarIndeterminateVisibility(showProgress); - } */ - - @Override - public void onSaveInstanceState(Bundle out) { - super.onSaveInstanceState(out); - - out.putBoolean("unreadOnly", m_unreadOnly); - out.putBoolean("unreadArticlesOnly", m_unreadArticlesOnly); - out.putInt("offlineActiveFeedId", m_activeFeedId); - out.putInt("offlineArticleId", m_selectedArticleId); - out.putBoolean("activeFeedIsCat", m_activeFeedIsCat); - out.putInt("activeCatId", m_activeCatId); - } - - private void setUnreadOnly(boolean unread) { - m_unreadOnly = unread; - - refreshViews(); - - /* - * if (!m_enableCats || m_activeCategory != null ) refreshFeeds(); else - * refreshCategories(); - */ - } - - @Override - public boolean getUnreadOnly() { - return m_unreadOnly; - } - - @Override - public void onResume() { - super.onResume(); - - 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, OfflineActivity.class); - startActivity(refresh); - finish(); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.offline_menu, menu); - - m_menu = menu; - - initMainMenu(); - - MenuItem item = menu.findItem(R.id.show_feeds); - - if (getUnreadOnly()) { - item.setTitle(R.string.menu_all_feeds); - } else { - item.setTitle(R.string.menu_unread_feeds); - } - - return true; - } - - private void goBack(boolean allowQuit) { - if (isSmallScreen()) { - if (m_selectedArticleId != 0) { - closeArticle(); - } else if (m_activeFeedId != 0) { - m_activeFeedId = 0; - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - - if (m_activeFeedIsCat) { - ft.replace(R.id.fragment_container, new OfflineFeedCategoriesFragment(), FRAG_CATS); - } else { - ft.replace(R.id.fragment_container, new OfflineFeedsFragment(m_activeCatId), FRAG_FEEDS); - } - ft.commit(); - - refreshViews(); - initMainMenu(); - } else if (m_activeCatId != -1) { - closeCategory(); - } else if (allowQuit) { - finish(); - } - } else { - if (m_selectedArticleId != 0) { - closeArticle(); - /* } else if (m_activeFeedId != 0) { - m_activeFeedId = 0; - - OfflineFeedsFragment ff = (OfflineFeedsFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_FEEDS); - - OfflineFeedCategoriesFragment cf = (OfflineFeedCategoriesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_CATS); - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - ft.replace(R.id.headlines_fragment, new DummyFragment(), ""); - ft.commit(); - - if (ff != null) { - ff.setSelectedFeedId(0); - } - - if (cf != null) { - cf.setSelectedFeedId(-1); - } - - refreshViews(); - initMainMenu(); */ - } else if (m_activeCatId != -1) { - closeCategory(); - } else if (allowQuit) { - finish(); - } - } - } - - @Override - public void onBackPressed() { - goBack(true); - } - - /* - * @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if - * (keyCode == KeyEvent.KEYCODE_BACK) { - * - * if (isSmallScreen()) { if (m_selectedArticleId != 0) { closeArticle(); - * } else if (m_activeFeedId != 0) { if (isCompatMode()) { - * findViewById(R.id.main).setAnimation(AnimationUtils.loadAnimation(this, - * R.anim.slide_right)); } - */ - - /* - * if (m_activeFeed != null && m_activeFeed.is_cat) { - * findViewById(R.id.headlines_fragment).setVisibility(View.GONE); - * findViewById(R.id.cats_fragment).setVisibility(View.VISIBLE); - * - * refreshCategories(); } else { - *//* - * findViewById(R.id.headlines_fragment).setVisibility(View.GONE); - * findViewById(R.id.feeds_fragment).setVisibility(View.VISIBLE); //} - * m_activeFeedId = 0; refreshViews(); initMainMenu(); - * - * } else { finish(); } } else { if (m_selectedArticleId != 0) { - * closeArticle(); } else { finish(); } } - * - * return false; } return super.onKeyDown(keyCode, event); } - */ - - private Cursor getArticleById(int articleId) { - Cursor c = getReadableDb().query("articles", null, - BaseColumns._ID + "=?", - new String[] { String.valueOf(articleId) }, null, null, null); - - c.moveToFirst(); - - return c; - } - - private Cursor getFeedById(int feedId) { - Cursor c = getReadableDb().query("feeds", null, - BaseColumns._ID + "=?", - new String[] { String.valueOf(feedId) }, null, null, null); - - c.moveToFirst(); - - return c; - } - - private Cursor getCatById(int catId) { - Cursor c = getReadableDb().query("categories", null, - BaseColumns._ID + "=?", - new String[] { String.valueOf(catId) }, null, null, null); - - c.moveToFirst(); - - return c; - } - - private Intent getShareIntent(Cursor article) { - String title = article.getString(article.getColumnIndex("title")); - String link = article.getString(article.getColumnIndex("link")); - - Intent intent = new Intent(Intent.ACTION_SEND); - - intent.setType("text/plain"); - intent.putExtra(Intent.EXTRA_SUBJECT, title); - intent.putExtra(Intent.EXTRA_TEXT, link); - - return intent; - } - - private void shareArticle(int articleId) { - - Cursor article = getArticleById(articleId); - - if (article != null) { - shareArticle(article); - article.close(); - } - } - - private void shareArticle(Cursor article) { - if (article != null) { - Intent intent = getShareIntent(article); - - startActivity(Intent.createChooser(intent, - getString(R.id.share_article))); - } - } - - private void refreshHeadlines() { - OfflineHeadlinesFragment ohf = (OfflineHeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - - if (ohf != null) { - ohf.refresh(); - } - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - final OfflineHeadlinesFragment ohf = (OfflineHeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - - switch (item.getItemId()) { - case R.id.close_feed: - if (m_activeFeedId != 0 || m_activeFeedIsCat) { - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - ft.replace(R.id.headlines_fragment, new DummyFragment(), ""); - ft.commit(); - - if (m_activeFeedIsCat) { - OfflineFeedCategoriesFragment cats = (OfflineFeedCategoriesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_CATS); - cats.setSelectedFeedId(-1); - } else { - OfflineFeedsFragment feeds = (OfflineFeedsFragment) getSupportFragmentManager().findFragmentByTag(FRAG_FEEDS); - feeds.setSelectedFeedId(0); - } - - m_activeFeedId = 0; - - initMainMenu(); - } - return true; - case R.id.close_article: - closeArticle(); - return true; - case android.R.id.home: - goBack(false); - return true; - case R.id.search: - if (ohf != null && isCompatMode()) { - Dialog dialog = new Dialog(this); - - final EditText edit = new EditText(this); - - AlertDialog.Builder builder = new AlertDialog.Builder(this) - .setTitle(R.string.search) - .setPositiveButton(getString(R.string.search), - new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, - int which) { - - String query = edit.getText().toString().trim(); - - ohf.setSearchQuery(query); - - } - }) - .setNegativeButton(getString(R.string.cancel), - new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, - int which) { - - // - - } - }).setView(edit); - - dialog = builder.create(); - dialog.show(); - } - - return true; - case R.id.preferences: - Intent intent = new Intent(this, PreferencesActivity.class); - startActivityForResult(intent, 0); - return true; - case R.id.go_online: - switchOnline(); - return true; - case R.id.headlines_select: - if (ohf != null) { - Dialog dialog = new Dialog(this); - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(R.string.headlines_select_dialog); - - builder.setSingleChoiceItems(new String[] { - getString(R.string.headlines_select_all), - getString(R.string.headlines_select_unread), - getString(R.string.headlines_select_none) }, 0, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, - int which) { - switch (which) { - case 0: - SQLiteStatement stmtSelectAll = getWritableDb() - .compileStatement( - "UPDATE articles SET selected = 1 WHERE feed_id = ?"); - stmtSelectAll.bindLong(1, m_activeFeedId); - stmtSelectAll.execute(); - stmtSelectAll.close(); - break; - case 1: - SQLiteStatement stmtSelectUnread = getWritableDb() - .compileStatement( - "UPDATE articles SET selected = 1 WHERE feed_id = ? AND unread = 1"); - stmtSelectUnread - .bindLong(1, m_activeFeedId); - stmtSelectUnread.execute(); - stmtSelectUnread.close(); - break; - case 2: - deselectAllArticles(); - break; - } - - refreshViews(); - initMainMenu(); - - dialog.cancel(); - } - }); - - dialog = builder.create(); - dialog.show(); - } - return true; - case R.id.headlines_mark_as_read: - if (m_activeFeedId != 0) { - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET unread = 0 WHERE feed_id = ?"); - stmt.bindLong(1, m_activeFeedId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - return true; - case R.id.share_article: - if (android.os.Build.VERSION.SDK_INT < 14) { - shareArticle(m_selectedArticleId); - } - return true; - case R.id.toggle_marked: - if (m_selectedArticleId != 0) { - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET marked = NOT marked WHERE " - + BaseColumns._ID + " = ?"); - stmt.bindLong(1, m_selectedArticleId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - return true; - case R.id.selection_select_none: - deselectAllArticles(); - return true; - case R.id.selection_toggle_unread: - if (getSelectedArticleCount() > 0 && m_activeFeedId != 0) { - SQLiteStatement stmt = getWritableDb() - .compileStatement( - "UPDATE articles SET unread = NOT unread WHERE selected = 1 AND feed_id = ?"); - stmt.bindLong(1, m_activeFeedId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - return true; - case R.id.selection_toggle_marked: - if (getSelectedArticleCount() > 0 && m_activeFeedId != 0) { - SQLiteStatement stmt = getWritableDb() - .compileStatement( - "UPDATE articles SET marked = NOT marked WHERE selected = 1 AND feed_id = ?"); - stmt.bindLong(1, m_activeFeedId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - return true; - case R.id.selection_toggle_published: - if (getSelectedArticleCount() > 0 && m_activeFeedId != 0) { - SQLiteStatement stmt = getWritableDb() - .compileStatement( - "UPDATE articles SET published = NOT published WHERE selected = 1 AND feed_id = ?"); - stmt.bindLong(1, m_activeFeedId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - return true; - case R.id.toggle_published: - if (m_selectedArticleId != 0) { - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET published = NOT published WHERE " - + BaseColumns._ID + " = ?"); - stmt.bindLong(1, m_selectedArticleId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - return true; - case R.id.catchup_above: - if (m_selectedArticleId != 0 && m_activeFeedId != 0) { - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET unread = 0 WHERE updated >= " - + "(SELECT updated FROM articles WHERE " - + BaseColumns._ID + " = ?) AND feed_id = ?"); - stmt.bindLong(1, m_selectedArticleId); - stmt.bindLong(2, m_activeFeedId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - return true; - case R.id.set_unread: - if (m_selectedArticleId != 0) { - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET unread = 1 WHERE " - + BaseColumns._ID + " = ?"); - stmt.bindLong(1, m_selectedArticleId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - return true; - case R.id.show_feeds: - setUnreadOnly(!getUnreadOnly()); - - if (getUnreadOnly()) { - item.setTitle(R.string.menu_all_feeds); - } else { - item.setTitle(R.string.menu_unread_feeds); - } - - return true; - default: - Log.d(TAG, - "onOptionsItemSelected, unhandled id=" + item.getItemId()); - return super.onOptionsItemSelected(item); - } - } - - private void refreshFeeds() { - OfflineFeedsFragment frag = (OfflineFeedsFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_FEEDS); - - if (frag != null) { - frag.refresh(); - } - } - - private void refreshCats() { - OfflineFeedCategoriesFragment frag = (OfflineFeedCategoriesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_CATS); - - if (frag != null) { - frag.refresh(); - } - } - - private void closeArticle() { - m_selectedArticleId = 0; - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - - if (isSmallScreen()) { - ft.remove(getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE)); - ft.show(getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES)); - } else { - findViewById(R.id.feeds_fragment).setVisibility(View.VISIBLE); - findViewById(R.id.article_fragment).setVisibility(View.GONE); - ft.replace(R.id.article_fragment, new DummyFragment(), FRAG_ARTICLE); - } - ft.commit(); - - initMainMenu(); - - refreshViews(); - } - - private int getSelectedArticleCount() { - Cursor c = getReadableDb().query("articles", - new String[] { "COUNT(*)" }, "selected = 1", null, null, null, - null); - c.moveToFirst(); - int selected = c.getInt(0); - c.close(); - - return selected; - } - - @Override - public void initMainMenu() { - if (m_menu != null) { - int numSelected = getSelectedArticleCount(); - - m_menu.setGroupVisible(R.id.menu_group_feeds, false); - m_menu.setGroupVisible(R.id.menu_group_headlines, false); - m_menu.setGroupVisible(R.id.menu_group_headlines_selection, false); - m_menu.setGroupVisible(R.id.menu_group_article, false); - - if (numSelected != 0) { - if (isCompatMode()) { - m_menu.setGroupVisible(R.id.menu_group_headlines_selection, true); - } else { - if (m_headlinesActionMode == null) - m_headlinesActionMode = startActionMode(m_headlinesActionModeCallback); - } - } else if (m_selectedArticleId != 0) { - m_menu.setGroupVisible(R.id.menu_group_article, true); - m_menu.findItem(R.id.close_article).setVisible(!isSmallScreen()); - - if (android.os.Build.VERSION.SDK_INT >= 14) { - ShareActionProvider shareProvider = (ShareActionProvider) m_menu.findItem(R.id.share_article).getActionProvider(); - - if (m_selectedArticleId != 0) { - Log.d(TAG, "setting up share provider"); - shareProvider.setShareIntent(getShareIntent(getArticleById(m_selectedArticleId))); - - if (!m_prefs.getBoolean("tablet_article_swipe", false) && !isSmallScreen()) { - m_menu.findItem(R.id.share_article).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); - } - } - } - } else if (m_activeFeedId != 0) { - m_menu.setGroupVisible(R.id.menu_group_headlines, true); - m_menu.findItem(R.id.close_feed).setVisible(!isSmallScreen()); - - MenuItem search = m_menu.findItem(R.id.search); - - if (!isCompatMode()) { - SearchView searchView = (SearchView) search.getActionView(); - searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { - private String query = ""; - - @Override - public boolean onQueryTextSubmit(String query) { - OfflineHeadlinesFragment frag = (OfflineHeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - - if (frag != null) { - frag.setSearchQuery(query); - this.query = query; - } - - return false; - } - - @Override - public boolean onQueryTextChange(String newText) { - if (newText.equals("") && !newText.equals(this.query)) { - OfflineHeadlinesFragment frag = (OfflineHeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - - if (frag != null) { - frag.setSearchQuery(newText); - this.query = newText; - } - } - - return false; - } - }); - } - - } else { - m_menu.setGroupVisible(R.id.menu_group_feeds, true); - } - - if (numSelected == 0 && m_headlinesActionMode != null) { - m_headlinesActionMode.finish(); - } - } - - updateTitle(); - } - - @Override - public void onPause() { - super.onPause(); - - } - - @Override - public void onDestroy() { - super.onDestroy(); - } - - private void refreshViews() { - refreshFeeds(); - refreshCats(); - refreshHeadlines(); - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - AdapterContextMenuInfo info = (AdapterContextMenuInfo) item - .getMenuInfo(); - - OfflineHeadlinesFragment hf = (OfflineHeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - OfflineFeedsFragment ff = (OfflineFeedsFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_FEEDS); - OfflineFeedCategoriesFragment cf = (OfflineFeedCategoriesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_CATS); - - switch (item.getItemId()) { - case R.id.article_link_copy: - if (m_selectedArticleId != 0) { - Cursor article = null; - - if (m_selectedArticleId != 0) { - article = getArticleById(m_selectedArticleId); - } else if (info != null) { - article = hf.getArticleAtPosition(info.position); - } - - if (article != null) { - copyToClipboard(article.getString(article.getColumnIndex("link"))); - article.close(); - } - } - return true; - case R.id.article_link_share: - if (m_selectedArticleId != 0) { - shareArticle(m_selectedArticleId); - } - return true; - - case R.id.browse_articles: - if (cf != null) { - int catId = cf.getCatIdAtPosition(info.position); - viewFeed(catId, true); - } - return true; - case R.id.browse_feeds: - if (cf != null) { - int catId = cf.getCatIdAtPosition(info.position); - viewCategory(catId, false); - } - return true; - case R.id.catchup_category: - if (cf != null) { - int catId = cf.getCatIdAtPosition(info.position); - - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET unread = 0 WHERE feed_id IN (SELECT "+ - BaseColumns._ID+" FROM feeds WHERE cat_id = ?)"); - stmt.bindLong(1, catId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - return true; - case R.id.catchup_feed: - if (ff != null) { - int feedId = ff.getFeedIdAtPosition(info.position); - - if (feedId != 0) { - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET unread = 0 WHERE feed_id = ?"); - stmt.bindLong(1, feedId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - } - return true; - case R.id.selection_toggle_unread: - if (getSelectedArticleCount() > 0 && m_activeFeedId != 0) { - SQLiteStatement stmt = getWritableDb() - .compileStatement( - "UPDATE articles SET unread = NOT unread WHERE selected = 1 AND feed_id = ?"); - stmt.bindLong(1, m_activeFeedId); - stmt.execute(); - stmt.close(); - refreshViews(); - } else { - int articleId = hf.getArticleIdAtPosition(info.position); - if (articleId != 0) { - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET unread = NOT unread WHERE " - + BaseColumns._ID + " = ?"); - stmt.bindLong(1, articleId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - } - return true; - case R.id.selection_toggle_marked: - if (getSelectedArticleCount() > 0 && m_activeFeedId != 0) { - SQLiteStatement stmt = getWritableDb() - .compileStatement( - "UPDATE articles SET marked = NOT marked WHERE selected = 1 AND feed_id = ?"); - stmt.bindLong(1, m_activeFeedId); - stmt.execute(); - stmt.close(); - refreshViews(); - } else { - int articleId = hf.getArticleIdAtPosition(info.position); - if (articleId != 0) { - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET marked = NOT marked WHERE " - + BaseColumns._ID + " = ?"); - stmt.bindLong(1, articleId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - } - return true; - case R.id.selection_toggle_published: - if (getSelectedArticleCount() > 0 && m_activeFeedId != 0) { - SQLiteStatement stmt = getWritableDb() - .compileStatement( - "UPDATE articles SET published = NOT published WHERE selected = 1 AND feed_id = ?"); - stmt.bindLong(1, m_activeFeedId); - stmt.execute(); - stmt.close(); - refreshViews(); - } else { - int articleId = hf.getArticleIdAtPosition(info.position); - if (articleId != 0) { - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET published = NOT published WHERE " - + BaseColumns._ID + " = ?"); - stmt.bindLong(1, articleId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - } - return true; - case R.id.share_article: - Cursor article = hf.getArticleAtPosition(info.position); - - if (article != null) { - shareArticle(article); - } - return true; - case R.id.catchup_above: - int articleId = hf.getArticleIdAtPosition(info.position); - - if (articleId != 0 && m_activeFeedId != 0) { - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET unread = 0 WHERE updated >= " - + "(SELECT updated FROM articles WHERE " - + BaseColumns._ID + " = ?) AND feed_id = ?"); - stmt.bindLong(1, articleId); - stmt.bindLong(2, m_activeFeedId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - return true; - default: - Log.d(TAG, - "onContextItemSelected, unhandled id=" + item.getItemId()); - return super.onContextItemSelected(item); - } - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - int action = event.getAction(); - int keyCode = event.getKeyCode(); - switch (keyCode) { - case KeyEvent.KEYCODE_VOLUME_DOWN: - if (action == KeyEvent.ACTION_DOWN) { - - OfflineHeadlinesFragment ohf = (OfflineHeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - - int nextId = getRelativeArticleId(m_selectedArticleId, - m_activeFeedId, RelativeArticle.AFTER); - - if (nextId != 0 && ohf != null) { - if (m_prefs.getBoolean("combined_mode", false)) { - ohf.setActiveArticleId(nextId); - - SQLiteStatement stmt = getWritableDb() - .compileStatement( - "UPDATE articles SET unread = 0 " - + "WHERE " + BaseColumns._ID - + " = ?"); - - stmt.bindLong(1, nextId); - stmt.execute(); - stmt.close(); - - } else { - openArticle(nextId, 0); - } - } - } - return true; - case KeyEvent.KEYCODE_VOLUME_UP: - if (action == KeyEvent.ACTION_UP) { - - OfflineHeadlinesFragment ohf = (OfflineHeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - - int prevId = getRelativeArticleId(m_selectedArticleId, - m_activeFeedId, RelativeArticle.BEFORE); - - if (prevId != 0 && ohf != null) { - if (m_prefs.getBoolean("combined_mode", false)) { - ohf.setActiveArticleId(prevId); - - SQLiteStatement stmt = getWritableDb() - .compileStatement( - "UPDATE articles SET unread = 0 " - + "WHERE " + BaseColumns._ID - + " = ?"); - - stmt.bindLong(1, prevId); - stmt.execute(); - stmt.close(); - - } else { - openArticle(prevId, 0); - } - } - } - return true; - default: - return super.dispatchKeyEvent(event); - } - } - - private void deselectAllArticles() { - getWritableDb().execSQL("UPDATE articles SET selected = 0 "); - } - - @Override - public int getRelativeArticleId(int baseId, int feedId, - OnlineServices.RelativeArticle mode) { - - Cursor c; - - /* - * if (baseId == 0) { c = getReadableDb().query("articles", null, - * "feed_id = ?", new String[] { String.valueOf(feedId) }, null, null, - * "updated DESC LIMIT 1"); - * - * if (c.moveToFirst()) { baseId = c.getInt(0); } - * - * c.close(); - * - * return baseId; } - */ - - if (mode == RelativeArticle.BEFORE) { - c = getReadableDb().query( - "articles", - null, - "updated > (SELECT updated FROM articles WHERE " - + BaseColumns._ID + " = ?) AND feed_id = ?", - new String[] { String.valueOf(baseId), - String.valueOf(feedId) }, null, null, - "updated LIMIT 1"); - - } else { - c = getReadableDb().query( - "articles", - null, - "updated < (SELECT updated FROM articles WHERE " - + BaseColumns._ID + " = ?) AND feed_id = ?", - new String[] { String.valueOf(baseId), - String.valueOf(feedId) }, null, null, - "updated DESC LIMIT 1"); - } - - int id = 0; - - if (c.moveToFirst()) { - id = c.getInt(0); - } - - c.close(); - - return id; - } - - public void onCatSelected(int catId) { - Log.d(TAG, "onCatSelected"); - boolean browse = m_prefs.getBoolean("browse_cats_like_feeds", false); - - viewCategory(catId, browse); - } - - public void viewCategory(int cat, boolean openAsFeed) { - - Log.d(TAG, "viewCategory"); - - if (!openAsFeed) { - OfflineFeedsFragment frag = new OfflineFeedsFragment(cat); - - FragmentTransaction ft = getSupportFragmentManager() - .beginTransaction(); - - if (isSmallScreen()) { - ft.replace(R.id.fragment_container, frag, FRAG_FEEDS); - } else { - ft.replace(R.id.feeds_fragment, frag, FRAG_FEEDS); - } - ft.commit(); - - m_activeCatId = cat; - - } else { - if (m_menu != null) { - MenuItem search = m_menu.findItem(R.id.search); - - if (search != null && !isCompatMode()) { - SearchView sv = (SearchView) search.getActionView(); - sv.setQuery("", false); - } - } - viewFeed(cat, true); - } - - initMainMenu(); - } - - @Override - public void onFeedSelected(int feedId) { - viewFeed(feedId); - } - - public void viewFeed(int feedId) { - viewFeed(feedId, false); - } - - public void viewFeed(int feedId, boolean isCat) { - m_activeFeedId = feedId; - m_activeFeedIsCat = isCat; - - initMainMenu(); - - deselectAllArticles(); - - if (m_menu != null) { - MenuItem search = m_menu.findItem(R.id.search); - - if (search != null && !isCompatMode()) { - SearchView sv = (SearchView) search.getActionView(); - sv.setQuery("", false); - } - } - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - OfflineHeadlinesFragment frag = new OfflineHeadlinesFragment(feedId, isCat); - - if (isSmallScreen()) { - ft.replace(R.id.fragment_container, frag, FRAG_HEADLINES); - } else { - findViewById(R.id.headlines_fragment).setVisibility(View.VISIBLE); - ft.replace(R.id.headlines_fragment, frag, FRAG_HEADLINES); - } - ft.commit(); - - } - - @Override - public void openArticle(int articleId, int compatAnimation) { - m_selectedArticleId = articleId; - - initMainMenu(); - - /* OfflineHeadlinesFragment hf = (OfflineHeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - - if (hf != null) { - hf.setActiveArticleId(articleId); - } */ - - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET unread = 0 " + "WHERE " + BaseColumns._ID - + " = ?"); - - stmt.bindLong(1, articleId); - stmt.execute(); - stmt.close(); - - Fragment frag; - - if (isSmallScreen() || m_prefs.getBoolean("tablet_article_swipe", false)) { - frag = new OfflineArticlePager(articleId); - } else { - frag = new OfflineArticleFragment(articleId); - } - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - - if (isSmallScreen()) { - ft.hide(getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES)); - ft.add(R.id.fragment_container, frag, FRAG_ARTICLE); - } else { - findViewById(R.id.feeds_fragment).setVisibility(isPortrait() || isSmallTablet() ? View.GONE : View.VISIBLE); - findViewById(R.id.article_fragment).setVisibility(View.VISIBLE); - ft.replace(R.id.article_fragment, frag, FRAG_ARTICLE); - - refreshViews(); - } - - ft.commit(); - } - - @Override - public int getSelectedArticleId() { - return m_selectedArticleId; - } - - @Override - public void setSelectedArticleId(int articleId) { - m_selectedArticleId = articleId; - initMainMenu(); - refreshViews(); - } - - private void closeCategory() { - m_activeCatId = -1; - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - if (isSmallScreen()) { - ft.replace(R.id.fragment_container, new OfflineFeedCategoriesFragment(), FRAG_CATS); - } else { - ft.replace(R.id.feeds_fragment, new OfflineFeedCategoriesFragment(), FRAG_CATS); - } - ft.commit(); - - initMainMenu(); - - refreshViews(); - } - - @Override - public boolean activeFeedIsCat() { - return m_activeFeedIsCat; - } - - private void updateTitle() { - if (!isCompatMode()) { - - m_navigationAdapter.clear(); - - if (m_activeCatId != -1 || (m_activeFeedId != 0 && (isSmallScreen() || isPortrait()))) { - getActionBar().setDisplayShowTitleEnabled(false); - getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); - - m_navigationAdapter.add(new RootNavigationEntry(getString(R.string.app_name))); - - if (m_activeCatId != -1) { - Cursor cat = getCatById(m_activeCatId); - String title = cat.getString(cat.getColumnIndex("title")); - m_navigationAdapter.add(new CategoryNavigationEntry(m_activeCatId, title)); - cat.close(); - } - - if (m_activeFeedId != 0) { - Cursor feed = null; - if (m_activeFeedIsCat) { - feed = getCatById(m_activeFeedId); - } else { - feed = getFeedById(m_activeFeedId); - } - String title = feed.getString(feed.getColumnIndex("title")); - m_navigationAdapter.add(new FeedNavigationEntry(m_activeFeedId, title)); - feed.close(); - } - - //if (m_selectedArticle != null) - // m_navigationAdapter.add(new ArticleNavigationEntry(m_selectedArticle)); - - getActionBar().setSelectedNavigationItem(getActionBar().getNavigationItemCount()); - - } else { - getActionBar().setDisplayShowTitleEnabled(true); - getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); - getActionBar().setTitle(R.string.app_name); - } - - if (isSmallScreen()) { - getActionBar().setDisplayHomeAsUpEnabled(m_selectedArticleId != 0 || m_activeFeedId != 0 || m_activeCatId != -1); - } else { - getActionBar().setDisplayHomeAsUpEnabled(m_selectedArticleId != 0 || m_activeCatId != -1); - } - - } else { - if (m_activeFeedId != 0) { - if (!m_activeFeedIsCat) { - Cursor feed = getFeedById(m_activeFeedId); - - if (feed != null) { - setTitle(feed.getString(feed.getColumnIndex("title"))); - feed.close(); - } - } else { - Cursor cat = getCatById(m_activeFeedId); - - if (cat != null) { - setTitle(cat.getString(cat.getColumnIndex("title"))); - cat.close(); - } - } - } else if (m_activeCatId != -1) { - Cursor cat = getCatById(m_activeCatId); - - if (cat != null) { - setTitle(cat.getString(cat.getColumnIndex("title"))); - cat.close(); - } - - } else { - setTitle(R.string.app_name); - } - - } - } -}
\ No newline at end of file diff --git a/src/org/fox/ttrss/offline/OfflineArticleFragment.java b/src/org/fox/ttrss/offline/OfflineArticleFragment.java deleted file mode 100644 index ebe11fc8..00000000 --- a/src/org/fox/ttrss/offline/OfflineArticleFragment.java +++ /dev/null @@ -1,238 +0,0 @@ -package org.fox.ttrss.offline;
-
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import org.fox.ttrss.R;
-import org.fox.ttrss.util.ImageCacheService;
-import org.jsoup.Jsoup;
-import org.jsoup.nodes.Document;
-import org.jsoup.nodes.Element;
-import org.jsoup.select.Elements;
-
-import android.app.Activity;
-import android.content.SharedPreferences;
-import android.database.Cursor;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.provider.BaseColumns;
-import android.support.v4.app.Fragment;
-import android.text.Html;
-import android.text.method.LinkMovementMethod;
-import android.util.TypedValue;
-import android.view.ContextMenu;
-import android.view.ContextMenu.ContextMenuInfo;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.webkit.WebSettings;
-import android.webkit.WebView;
-import android.webkit.WebSettings.LayoutAlgorithm;
-import android.widget.TextView;
-
-public class OfflineArticleFragment extends Fragment {
- @SuppressWarnings("unused")
- private final String TAG = this.getClass().getSimpleName();
-
- private SharedPreferences m_prefs;
- private int m_articleId;
- private Cursor m_cursor;
- private OfflineServices m_offlineServices;
-
- public OfflineArticleFragment() {
- super();
- }
-
- public OfflineArticleFragment(int articleId) {
- super();
- m_articleId = articleId;
- }
-
- @Override
- public void onCreateContextMenu(ContextMenu menu, View v,
- ContextMenuInfo menuInfo) {
-
- getActivity().getMenuInflater().inflate(R.menu.article_link_context_menu, menu);
- menu.setHeaderTitle(m_cursor.getString(m_cursor.getColumnIndex("title")));
-
- super.onCreateContextMenu(menu, v, menuInfo);
-
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-
- if (savedInstanceState != null) {
- m_articleId = savedInstanceState.getInt("articleId");
- }
-
- View view = inflater.inflate(R.layout.article_fragment, container, false);
-
- m_cursor = m_offlineServices.getReadableDb().query("articles LEFT JOIN feeds ON (feed_id = feeds."+BaseColumns._ID+")",
- new String[] { "articles.*", "feeds.title AS feed_title" }, "articles." + BaseColumns._ID + "=?",
- new String[] { String.valueOf(m_articleId) }, null, null, null);
-
- m_cursor.moveToFirst();
-
- if (m_cursor.isFirst()) {
-
- TextView title = (TextView)view.findViewById(R.id.title);
-
- if (title != null) {
-
- String titleStr;
-
- if (m_cursor.getString(m_cursor.getColumnIndex("title")).length() > 200)
- titleStr = m_cursor.getString(m_cursor.getColumnIndex("title")).substring(0, 200) + "...";
- else
- titleStr = m_cursor.getString(m_cursor.getColumnIndex("title"));
-
- title.setMovementMethod(LinkMovementMethod.getInstance());
- title.setText(Html.fromHtml("<a href=\""+m_cursor.getString(m_cursor.getColumnIndex("link")).trim().replace("\"", "\\\"")+"\">" + titleStr + "</a>"));
- registerForContextMenu(title);
- }
-
- WebView web = (WebView)view.findViewById(R.id.content);
-
- if (web != null) {
-
- String content;
- String cssOverride = "";
-
- WebSettings ws = web.getSettings();
- ws.setSupportZoom(true);
- ws.setBuiltInZoomControls(true);
-
- web.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
-
- TypedValue tv = new TypedValue();
- getActivity().getTheme().resolveAttribute(R.attr.linkColor, tv, true);
-
- // prevent flicker in ics
- if (android.os.Build.VERSION.SDK_INT >= 11) {
- web.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
- }
-
- if (m_prefs.getString("theme", "THEME_DARK").equals("THEME_DARK")) {
- cssOverride = "body { background : transparent; color : #e0e0e0}";
- //view.setBackgroundColor(android.R.color.black);
- web.setBackgroundColor(getResources().getColor(android.R.color.transparent));
- } else {
- cssOverride = "";
- }
-
- String hexColor = String.format("#%06X", (0xFFFFFF & tv.data));
- cssOverride += " a:link {color: "+hexColor+";} a:visited { color: "+hexColor+";}";
-
- String articleContent = m_cursor.getString(m_cursor.getColumnIndex("content"));
- Document doc = Jsoup.parse(articleContent);
-
- if (doc != null) {
- if (m_prefs.getBoolean("offline_image_cache_enabled", false)) {
-
- Elements images = doc.select("img");
-
- for (Element img : images) {
- String url = img.attr("src");
-
- if (ImageCacheService.isUrlCached(url)) {
- img.attr("src", "file://" + ImageCacheService.getCacheFileName(url));
- }
- }
- }
-
- // thanks webview for crashing on <video> tag
- Elements videos = doc.select("video");
-
- for (Element video : videos)
- video.remove();
-
- articleContent = doc.toString();
- }
-
- view.findViewById(R.id.attachments_holder).setVisibility(View.GONE);
-
- String align = m_prefs.getBoolean("justify_article_text", true) ? "text-align : justified" : "";
-
- switch (Integer.parseInt(m_prefs.getString("font_size", "0"))) {
- case 0:
- cssOverride += "body { "+align+"; font-size : 14px; } ";
- break;
- case 1:
- cssOverride += "body { "+align+"; font-size : 18px; } ";
- break;
- case 2:
- cssOverride += "body { "+align+"; font-size : 21px; } ";
- break;
- }
-
- content =
- "<html>" +
- "<head>" +
- "<meta content=\"text/html; charset=utf-8\" http-equiv=\"content-type\">" +
- "<style type=\"text/css\">" +
- "body { padding : 0px; margin : 0px; }" +
- cssOverride +
- "</style>" +
- "</head>" +
- "<body>" + articleContent + "</body></html>";
-
- try {
- web.loadDataWithBaseURL(null, content, "text/html", "utf-8", null);
- } catch (RuntimeException e) {
- e.printStackTrace();
- }
-
-
- }
-
- TextView dv = (TextView)view.findViewById(R.id.date);
-
- if (dv != null) {
- Date d = new Date(m_cursor.getInt(m_cursor.getColumnIndex("updated")) * 1000L);
- SimpleDateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy, HH:mm");
- dv.setText(df.format(d));
- }
-
- TextView tagv = (TextView)view.findViewById(R.id.tags);
-
- if (tagv != null) {
- int feedTitleIndex = m_cursor.getColumnIndex("feed_title");
-
- if (feedTitleIndex != -1 && m_offlineServices.activeFeedIsCat()) {
- tagv.setText(m_cursor.getString(feedTitleIndex));
- } else {
- String tagsStr = m_cursor.getString(m_cursor.getColumnIndex("tags"));
- tagv.setText(tagsStr);
- }
- }
- }
-
- return view;
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
-
- m_cursor.close();
- }
-
- @Override
- public void onSaveInstanceState (Bundle out) {
- super.onSaveInstanceState(out);
-
- out.putInt("articleId", m_articleId);
- }
-
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
-
- m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
-
- m_offlineServices = (OfflineServices)activity;
- }
-
-
-}
diff --git a/src/org/fox/ttrss/offline/OfflineArticlePager.java b/src/org/fox/ttrss/offline/OfflineArticlePager.java deleted file mode 100644 index 104d9f4f..00000000 --- a/src/org/fox/ttrss/offline/OfflineArticlePager.java +++ /dev/null @@ -1,109 +0,0 @@ -package org.fox.ttrss.offline;
-
-import org.fox.ttrss.R;
-
-import android.app.Activity;
-import android.database.sqlite.SQLiteStatement;
-import android.os.Bundle;
-import android.provider.BaseColumns;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentStatePagerAdapter;
-import android.support.v4.view.ViewPager;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-public class OfflineArticlePager extends Fragment {
-
- private PagerAdapter m_adapter;
- private OfflineServices m_offlineServices;
- private OfflineHeadlinesFragment m_hf;
- private int m_articleId;
-
- private class PagerAdapter extends FragmentStatePagerAdapter {
-
- public PagerAdapter(FragmentManager fm) {
- super(fm);
- }
-
- @Override
- public Fragment getItem(int position) {
- int articleId = m_hf.getArticleIdAtPosition(position);
-
- if (articleId != 0) {
- return new OfflineArticleFragment(articleId);
- }
-
- return null;
- }
-
- @Override
- public int getCount() {
- return m_hf.getArticleCount();
- }
-
- }
-
- public OfflineArticlePager() {
- super();
- }
-
- public OfflineArticlePager(int articleId) {
- super();
-
- m_articleId = articleId;
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.article_pager, container, false);
-
- m_adapter = new PagerAdapter(getActivity().getSupportFragmentManager());
-
- ViewPager pager = (ViewPager) view.findViewById(R.id.article_pager);
-
- int position = m_hf.getArticleIdPosition(m_articleId);
-
- pager.setAdapter(m_adapter);
- pager.setCurrentItem(position);
- pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
-
- @Override
- public void onPageScrollStateChanged(int arg0) {
- }
-
- @Override
- public void onPageScrolled(int arg0, float arg1, int arg2) {
- }
-
- @Override
- public void onPageSelected(int position) {
- int articleId = m_hf.getArticleIdAtPosition(position);
-
- if (articleId != 0) {
- m_offlineServices.setSelectedArticleId(articleId);
-
- SQLiteStatement stmt = m_offlineServices.getWritableDb().compileStatement(
- "UPDATE articles SET unread = 0 " + "WHERE " + BaseColumns._ID
- + " = ?");
-
- stmt.bindLong(1, articleId);
- stmt.execute();
- stmt.close();
- }
- }
- });
-
- return view;
- }
-
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
-
- m_hf = (OfflineHeadlinesFragment) getActivity().getSupportFragmentManager().findFragmentByTag(OfflineActivity.FRAG_HEADLINES);
- m_offlineServices = (OfflineServices)activity;
- }
-
-}
diff --git a/src/org/fox/ttrss/offline/OfflineDownloadService.java b/src/org/fox/ttrss/offline/OfflineDownloadService.java deleted file mode 100644 index b757082f..00000000 --- a/src/org/fox/ttrss/offline/OfflineDownloadService.java +++ /dev/null @@ -1,452 +0,0 @@ -package org.fox.ttrss.offline;
-
-import java.lang.reflect.Type;
-import java.util.HashMap;
-import java.util.List;
-
-import org.fox.ttrss.ApiRequest;
-import org.fox.ttrss.MainActivity;
-import org.fox.ttrss.R;
-import org.fox.ttrss.types.Article;
-import org.fox.ttrss.types.Feed;
-import org.fox.ttrss.types.FeedCategory;
-import org.fox.ttrss.util.DatabaseHelper;
-import org.fox.ttrss.util.ImageCacheService;
-import org.jsoup.Jsoup;
-import org.jsoup.nodes.Document;
-import org.jsoup.nodes.Element;
-import org.jsoup.select.Elements;
-
-import android.app.ActivityManager;
-import android.app.ActivityManager.RunningServiceInfo;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteStatement;
-import android.os.Binder;
-import android.os.IBinder;
-import android.preference.PreferenceManager;
-import android.provider.BaseColumns;
-import android.util.Log;
-
-import com.google.gson.Gson;
-import com.google.gson.JsonElement;
-import com.google.gson.reflect.TypeToken;
-
-public class OfflineDownloadService extends Service {
-
- private final String TAG = this.getClass().getSimpleName();
-
- public static final int NOTIFY_DOWNLOADING = 1;
- public static final String INTENT_ACTION_SUCCESS = "org.fox.ttrss.intent.action.DownloadComplete";
- public static final String INTENT_ACTION_CANCEL = "org.fox.ttrss.intent.action.Cancel";
-
- private static final int OFFLINE_SYNC_SEQ = 40;
- private static final int OFFLINE_SYNC_MAX = 500;
-
- private SQLiteDatabase m_writableDb;
- private SQLiteDatabase m_readableDb;
- private int m_articleOffset = 0;
- private String m_sessionId;
- private NotificationManager m_nmgr;
-
- private boolean m_downloadInProgress = false;
- private boolean m_downloadImages = false;
- private int m_syncMax;
- private SharedPreferences m_prefs;
- private boolean m_canProceed = true;
-
- private final IBinder m_binder = new LocalBinder();
-
- public class LocalBinder extends Binder {
- OfflineDownloadService getService() {
- return OfflineDownloadService.this;
- }
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- return m_binder;
- }
-
- @Override
- public void onCreate() {
- super.onCreate();
- m_nmgr = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
- m_prefs = PreferenceManager
- .getDefaultSharedPreferences(getApplicationContext());
-
- m_downloadImages = m_prefs.getBoolean("offline_image_cache_enabled", false);
- m_syncMax = m_prefs.getInt("offline_sync_max", OFFLINE_SYNC_MAX);
-
- initDatabase();
- }
-
- private void updateNotification(String msg) {
- Notification notification = new Notification(R.drawable.icon,
- getString(R.string.notify_downloading_title), System.currentTimeMillis());
-
- Intent intent = new Intent(this, MainActivity.class);
- intent.setAction(INTENT_ACTION_CANCEL);
-
- PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
- intent, 0);
-
- notification.flags |= Notification.FLAG_ONGOING_EVENT;
- notification.flags |= Notification.FLAG_ONLY_ALERT_ONCE;
-
- notification.setLatestEventInfo(this, getString(R.string.notify_downloading_title), msg, contentIntent);
-
- m_nmgr.notify(NOTIFY_DOWNLOADING, notification);
- }
-
- private void updateNotification(int msgResId) {
- updateNotification(getString(msgResId));
- }
-
- private void downloadFailed() {
- m_readableDb.close();
- m_writableDb.close();
-
- m_nmgr.cancel(NOTIFY_DOWNLOADING);
-
- // TODO send notification to activity?
-
- m_downloadInProgress = false;
- stopSelf();
- }
-
- private boolean isCacheServiceRunning() {
- ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
- for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
- if ("org.fox.ttrss.ImageCacheService".equals(service.service.getClassName())) {
- return true;
- }
- }
- return false;
- }
-
- public void downloadComplete() {
- m_downloadInProgress = false;
-
- // if cache service is running, it will send a finished intent on its own
- if (!isCacheServiceRunning()) {
- m_nmgr.cancel(NOTIFY_DOWNLOADING);
-
- Intent intent = new Intent();
- intent.setAction(INTENT_ACTION_SUCCESS);
- intent.addCategory(Intent.CATEGORY_DEFAULT);
- sendBroadcast(intent);
- } else {
- updateNotification(getString(R.string.notify_downloading_images, 0));
- }
-
- m_readableDb.close();
- m_writableDb.close();
-
- stopSelf();
- }
-
- private void initDatabase() {
- DatabaseHelper dh = new DatabaseHelper(getApplicationContext());
- m_writableDb = dh.getWritableDatabase();
- m_readableDb = dh.getReadableDatabase();
- }
-
- private synchronized SQLiteDatabase getReadableDb() {
- return m_readableDb;
- }
-
- private synchronized SQLiteDatabase getWritableDb() {
- return m_writableDb;
- }
-
- @SuppressWarnings("unchecked")
- private void downloadArticles() {
- Log.d(TAG, "offline: downloading articles... offset=" + m_articleOffset);
-
- updateNotification(getString(R.string.notify_downloading_articles, m_articleOffset));
-
- OfflineArticlesRequest req = new OfflineArticlesRequest(this);
-
- @SuppressWarnings("serial")
- HashMap<String,String> map = new HashMap<String,String>() {
- {
- put("op", "getHeadlines");
- put("sid", m_sessionId);
- put("feed_id", "-4");
- put("view_mode", "unread");
- put("show_content", "true");
- put("skip", String.valueOf(m_articleOffset));
- put("limit", String.valueOf(OFFLINE_SYNC_SEQ));
- }
- };
-
- req.execute(map);
- }
-
- private void downloadFeeds() {
-
- updateNotification(R.string.notify_downloading_feeds);
-
- getWritableDb().execSQL("DELETE FROM feeds;");
-
- ApiRequest req = new ApiRequest(getApplicationContext()) {
- @Override
- protected void onPostExecute(JsonElement content) {
- if (content != null) {
-
- try {
- Type listType = new TypeToken<List<Feed>>() {}.getType();
- List<Feed> feeds = new Gson().fromJson(content, listType);
-
- SQLiteStatement stmtInsert = getWritableDb().compileStatement("INSERT INTO feeds " +
- "("+BaseColumns._ID+", title, feed_url, has_icon, cat_id) " +
- "VALUES (?, ?, ?, ?, ?);");
-
- for (Feed feed : feeds) {
- stmtInsert.bindLong(1, feed.id);
- stmtInsert.bindString(2, feed.title);
- stmtInsert.bindString(3, feed.feed_url);
- stmtInsert.bindLong(4, feed.has_icon ? 1 : 0);
- stmtInsert.bindLong(5, feed.cat_id);
-
- stmtInsert.execute();
- }
-
- stmtInsert.close();
-
- Log.d(TAG, "offline: done downloading feeds");
-
- m_articleOffset = 0;
-
- getWritableDb().execSQL("DELETE FROM articles;");
-
- if (m_canProceed) {
- downloadArticles();
- } else {
- downloadFailed();
- }
- } catch (Exception e) {
- e.printStackTrace();
- updateNotification(R.string.offline_switch_error);
- downloadFailed();
- }
-
- } else {
- updateNotification(getErrorMessage());
- downloadFailed();
- }
- }
-
- };
-
- @SuppressWarnings("serial")
- HashMap<String,String> map = new HashMap<String,String>() {
- {
- put("op", "getFeeds");
- put("sid", m_sessionId);
- put("cat_id", "-3");
- put("unread_only", "true");
- }
- };
-
- req.execute(map);
- }
-
- private void downloadCategories() {
-
- updateNotification(R.string.notify_downloading_feeds);
-
- getWritableDb().execSQL("DELETE FROM categories;");
-
- ApiRequest req = new ApiRequest(getApplicationContext()) {
- @Override
- protected void onPostExecute(JsonElement content) {
- if (content != null) {
-
- try {
- Type listType = new TypeToken<List<FeedCategory>>() {}.getType();
- List<FeedCategory> cats = new Gson().fromJson(content, listType);
-
- SQLiteStatement stmtInsert = getWritableDb().compileStatement("INSERT INTO categories " +
- "("+BaseColumns._ID+", title) " +
- "VALUES (?, ?);");
-
- for (FeedCategory cat : cats) {
- stmtInsert.bindLong(1, cat.id);
- stmtInsert.bindString(2, cat.title);
-
- stmtInsert.execute();
- }
-
- stmtInsert.close();
-
- Log.d(TAG, "offline: done downloading categories");
-
- if (m_canProceed) {
- downloadFeeds();
- } else {
- downloadFailed();
- }
- } catch (Exception e) {
- e.printStackTrace();
- updateNotification(R.string.offline_switch_error);
- downloadFailed();
- }
-
- } else {
- updateNotification(getErrorMessage());
- downloadFailed();
- }
- }
-
- };
-
- @SuppressWarnings("serial")
- HashMap<String,String> map = new HashMap<String,String>() {
- {
- put("op", "getCategories");
- put("sid", m_sessionId);
- //put("cat_id", "-3");
- put("unread_only", "true");
- }
- };
-
- req.execute(map);
- }
-
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- m_nmgr.cancel(NOTIFY_DOWNLOADING);
-
- m_canProceed = false;
- Log.d(TAG, "onDestroy");
-
- //m_readableDb.close();
- //m_writableDb.close();
- }
-
- public class OfflineArticlesRequest extends ApiRequest {
- public OfflineArticlesRequest(Context context) {
- super(context);
- }
-
- @Override
- protected void onPostExecute(JsonElement content) {
- if (content != null) {
- try {
- Type listType = new TypeToken<List<Article>>() {}.getType();
- List<Article> articles = new Gson().fromJson(content, listType);
-
- SQLiteStatement stmtInsert = getWritableDb().compileStatement("INSERT INTO articles " +
- "("+BaseColumns._ID+", unread, marked, published, updated, is_updated, title, link, feed_id, tags, content) " +
- "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
-
- for (Article article : articles) {
-
- String tagsString = "";
-
- for (String t : article.tags) {
- tagsString += t + ", ";
- }
-
- tagsString = tagsString.replaceAll(", $", "");
-
- stmtInsert.bindLong(1, article.id);
- stmtInsert.bindLong(2, article.unread ? 1 : 0);
- stmtInsert.bindLong(3, article.marked ? 1 : 0);
- stmtInsert.bindLong(4, article.published ? 1 : 0);
- stmtInsert.bindLong(5, article.updated);
- stmtInsert.bindLong(6, article.is_updated ? 1 : 0);
- stmtInsert.bindString(7, article.title);
- stmtInsert.bindString(8, article.link);
- stmtInsert.bindLong(9, article.feed_id);
- stmtInsert.bindString(10, tagsString); // comma-separated tags
- stmtInsert.bindString(11, article.content);
-
- if (m_downloadImages) {
- Document doc = Jsoup.parse(article.content);
-
- if (doc != null) {
- Elements images = doc.select("img");
-
- for (Element img : images) {
- String url = img.attr("src");
-
- if (url.indexOf("://") != -1) {
- if (!ImageCacheService.isUrlCached(url)) {
- Intent intent = new Intent(OfflineDownloadService.this,
- ImageCacheService.class);
-
- intent.putExtra("url", url);
- startService(intent);
- }
- }
- }
- }
- }
-
- try {
- stmtInsert.execute();
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- }
-
- stmtInsert.close();
-
- //m_canGetMoreArticles = articles.size() == 30;
- m_articleOffset += articles.size();
-
- Log.d(TAG, "offline: received " + articles.size() + " articles; canProc=" + m_canProceed);
-
- if (m_canProceed) {
- if (articles.size() == OFFLINE_SYNC_SEQ && m_articleOffset < m_syncMax) {
- downloadArticles();
- } else {
- downloadComplete();
- }
- } else {
- downloadFailed();
- }
-
- return;
-
- } catch (Exception e) {
- updateNotification(R.string.offline_switch_error);
- Log.d(TAG, "offline: failed: exception when loading articles");
- e.printStackTrace();
- downloadFailed();
- }
-
- } else {
- Log.d(TAG, "offline: failed: " + getErrorMessage());
- updateNotification(getErrorMessage());
- downloadFailed();
- }
- }
- }
-
- @Override
- public void onStart(Intent intent, int startId) {
- m_sessionId = intent.getStringExtra("sessionId");
-
- if (!m_downloadInProgress) {
- if (m_downloadImages) ImageCacheService.cleanupCache(false);
-
- updateNotification(R.string.notify_downloading_init);
- m_downloadInProgress = true;
-
- downloadCategories();
- }
- }
-}
diff --git a/src/org/fox/ttrss/offline/OfflineFeedCategoriesFragment.java b/src/org/fox/ttrss/offline/OfflineFeedCategoriesFragment.java deleted file mode 100644 index f6ae2835..00000000 --- a/src/org/fox/ttrss/offline/OfflineFeedCategoriesFragment.java +++ /dev/null @@ -1,262 +0,0 @@ -package org.fox.ttrss.offline;
-
-import org.fox.ttrss.R;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.database.Cursor;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.provider.BaseColumns;
-import android.support.v4.app.Fragment;
-import android.support.v4.widget.SimpleCursorAdapter;
-import android.util.Log;
-import android.view.ContextMenu;
-import android.view.ContextMenu.ContextMenuInfo;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.AdapterContextMenuInfo;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.TextView;
-
-public class OfflineFeedCategoriesFragment extends Fragment implements OnItemClickListener, OnSharedPreferenceChangeListener {
- private final String TAG = this.getClass().getSimpleName();
- private SharedPreferences m_prefs;
- private FeedCategoryListAdapter m_adapter;
- private int m_selectedCatId;
- private Cursor m_cursor;
- private OfflineServices m_offlineServices;
-
- @Override
- public void onCreateContextMenu(ContextMenu menu, View v,
- ContextMenuInfo menuInfo) {
-
- getActivity().getMenuInflater().inflate(R.menu.category_menu, menu);
-
- AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
- Cursor cursor = (Cursor)m_adapter.getItem(info.position);
-
- if (cursor != null)
- menu.setHeaderTitle(cursor.getString(cursor.getColumnIndex("title")));
-
- super.onCreateContextMenu(menu, v, menuInfo);
-
- }
-
- public Cursor createCursor() {
- String unreadOnly = BaseColumns._ID + "> 0 AND " + (m_offlineServices.getUnreadOnly() ? "unread > 0" : "1");
-
- String order = m_prefs.getBoolean("sort_feeds_by_unread", false) ? "unread DESC, title" : "title";
-
- return m_offlineServices.getReadableDb().query("cats_unread",
- null, unreadOnly, null, null, null, order);
- }
-
- public void refresh() {
- if (m_cursor != null && !m_cursor.isClosed()) m_cursor.close();
-
- m_cursor = createCursor();
-
- if (m_cursor != null) {
- m_adapter.changeCursor(m_cursor);
- m_adapter.notifyDataSetChanged();
- }
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-
- if (savedInstanceState != null) {
- m_selectedCatId = savedInstanceState.getInt("selectedFeedId");
- }
-
- View view = inflater.inflate(R.layout.feeds_fragment, container, false);
-
- ListView list = (ListView)view.findViewById(R.id.feeds);
-
- m_cursor = createCursor();
-
- m_adapter = new FeedCategoryListAdapter(getActivity(), R.layout.feeds_row, m_cursor,
- new String[] { "title", "unread" }, new int[] { R.id.title, R.id.unread_counter }, 0);
-
- list.setAdapter(m_adapter);
- list.setOnItemClickListener(this);
- list.setEmptyView(view.findViewById(R.id.no_feeds));
- registerForContextMenu(list);
-
- view.findViewById(R.id.loading_container).setVisibility(View.GONE);
-
- return view;
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
-
- if (m_cursor != null && !m_cursor.isClosed()) m_cursor.close();
- }
-
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
-
- m_offlineServices = (OfflineServices)activity;
-
- m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
- m_prefs.registerOnSharedPreferenceChangeListener(this);
-
- }
-
- @Override
- public void onSaveInstanceState (Bundle out) {
- super.onSaveInstanceState(out);
-
- out.putInt("selectedFeedId", m_selectedCatId);
- }
-
- @Override
- public void onItemClick(AdapterView<?> av, View view, int position, long id) {
- ListView list = (ListView)getActivity().findViewById(R.id.feeds);
-
- if (list != null) {
- Cursor cursor = (Cursor) list.getItemAtPosition(position);
-
- if (cursor != null) {
- int feedId = (int) cursor.getLong(0);
- Log.d(TAG, "clicked on feed " + feedId);
-
- m_offlineServices.onCatSelected(feedId);
-
- if (!m_offlineServices.isSmallScreen())
- m_selectedCatId = feedId;
-
- m_adapter.notifyDataSetChanged();
- }
- }
- }
-
- /* 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);
- }
- }
-
- getActivity().setProgressBarIndeterminateVisibility(showProgress);
- } */
-
- private class FeedCategoryListAdapter extends SimpleCursorAdapter {
-
-
- public FeedCategoryListAdapter(Context context, int layout, Cursor c,
- String[] from, int[] to, int flags) {
- super(context, layout, c, from, to, flags);
- }
-
- public static final int VIEW_NORMAL = 0;
- public static final int VIEW_SELECTED = 1;
-
- public static final int VIEW_COUNT = VIEW_SELECTED+1;
-
- @Override
- public int getViewTypeCount() {
- return VIEW_COUNT;
- }
-
- @Override
- public int getItemViewType(int position) {
- Cursor cursor = (Cursor) this.getItem(position);
-
- if (!m_offlineServices.isSmallScreen() && cursor.getLong(0) == m_selectedCatId) {
- return VIEW_SELECTED;
- } else {
- return VIEW_NORMAL;
- }
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- View v = convertView;
-
- Cursor cursor = (Cursor)getItem(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(cursor.getString(cursor.getColumnIndex("title")));
- }
-
- TextView tu = (TextView) v.findViewById(R.id.unread_counter);
-
- if (tu != null) {
- tu.setText(String.valueOf(cursor.getInt(cursor.getColumnIndex("unread"))));
- tu.setVisibility((cursor.getInt(cursor.getColumnIndex("unread")) > 0) ? View.VISIBLE : View.INVISIBLE);
- }
-
- ImageView icon = (ImageView)v.findViewById(R.id.icon);
-
- if (icon != null) {
- icon.setImageResource(cursor.getInt(cursor.getColumnIndex("unread")) > 0 ? R.drawable.ic_rss : R.drawable.ic_rss_bw);
- }
-
- return v;
- }
- }
-
- public void sortCategories() {
- try {
- refresh();
- } catch (NullPointerException e) {
- // activity is gone?
- } catch (IllegalStateException e) {
- // we're probably closing and DB is gone already
- }
- }
-
- @Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
- String key) {
-
- sortCategories();
- }
-
- public int getCatIdAtPosition(int position) {
- Cursor c = (Cursor)m_adapter.getItem(position);
-
- if (c != null) {
- int catId = c.getInt(0);
- c.close();
- return catId;
- }
-
- return 0;
- }
-
- public void setSelectedFeedId(int feedId) {
- m_selectedCatId = feedId;
- refresh();
- }
-
-}
diff --git a/src/org/fox/ttrss/offline/OfflineFeedsFragment.java b/src/org/fox/ttrss/offline/OfflineFeedsFragment.java deleted file mode 100644 index 605f506c..00000000 --- a/src/org/fox/ttrss/offline/OfflineFeedsFragment.java +++ /dev/null @@ -1,306 +0,0 @@ -package org.fox.ttrss.offline;
-
-import java.io.File;
-
-import org.fox.ttrss.R;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.os.Bundle;
-import android.os.Environment;
-import android.preference.PreferenceManager;
-import android.provider.BaseColumns;
-import android.support.v4.app.Fragment;
-import android.support.v4.widget.SimpleCursorAdapter;
-import android.util.Log;
-import android.view.ContextMenu;
-import android.view.ContextMenu.ContextMenuInfo;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.AdapterContextMenuInfo;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.TextView;
-
-public class OfflineFeedsFragment extends Fragment implements OnItemClickListener, OnSharedPreferenceChangeListener {
- private final String TAG = this.getClass().getSimpleName();
- private SharedPreferences m_prefs;
- private FeedListAdapter m_adapter;
- private static final String ICON_PATH = "/data/org.fox.ttrss/icons/";
- private int m_selectedFeedId;
- private int m_catId = -1;
- private boolean m_enableFeedIcons;
- private Cursor m_cursor;
- private OfflineServices m_offlineServices;
-
- public OfflineFeedsFragment() {
- //
- }
-
- public OfflineFeedsFragment(int catId) {
- m_catId = catId;
- }
-
- @Override
- public void onCreateContextMenu(ContextMenu menu, View v,
- ContextMenuInfo menuInfo) {
-
- getActivity().getMenuInflater().inflate(R.menu.feed_menu, menu);
-
- AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
- Cursor cursor = (Cursor)m_adapter.getItem(info.position);
-
- if (cursor != null)
- menu.setHeaderTitle(cursor.getString(cursor.getColumnIndex("title")));
-
- super.onCreateContextMenu(menu, v, menuInfo);
-
- }
-
- public Cursor createCursor() {
- String unreadOnly = m_offlineServices.getUnreadOnly() ? "unread > 0" : "1";
- String order = m_prefs.getBoolean("sort_feeds_by_unread", false) ? "unread DESC, title" : "title";
-
- if (m_catId != -1) {
- return m_offlineServices.getReadableDb().query("feeds_unread",
- null, unreadOnly + " AND cat_id = ?", new String[] { String.valueOf(m_catId) }, null, null, order);
- } else {
- return m_offlineServices.getReadableDb().query("feeds_unread",
- null, unreadOnly, null, null, null, order);
- }
- }
-
- public void refresh() {
- if (m_cursor != null && !m_cursor.isClosed()) m_cursor.close();
-
- m_cursor = createCursor();
-
- if (m_cursor != null) {
- m_adapter.changeCursor(m_cursor);
- m_adapter.notifyDataSetChanged();
- }
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-
- if (savedInstanceState != null) {
- m_selectedFeedId = savedInstanceState.getInt("selectedFeedId");
- m_catId = savedInstanceState.getInt("catId");
- }
-
- View view = inflater.inflate(R.layout.feeds_fragment, container, false);
-
- ListView list = (ListView)view.findViewById(R.id.feeds);
-
- m_cursor = createCursor();
-
- m_adapter = new FeedListAdapter(getActivity(), R.layout.feeds_row, m_cursor,
- new String[] { "title", "unread" }, new int[] { R.id.title, R.id.unread_counter }, 0);
-
- list.setAdapter(m_adapter);
- list.setOnItemClickListener(this);
- list.setEmptyView(view.findViewById(R.id.no_feeds));
- registerForContextMenu(list);
-
- view.findViewById(R.id.loading_container).setVisibility(View.GONE);
-
- m_enableFeedIcons = m_prefs.getBoolean("download_feed_icons", false);
-
- return view;
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
-
- if (m_cursor != null && !m_cursor.isClosed()) m_cursor.close();
- }
-
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
-
- m_offlineServices = (OfflineServices)activity;
-
- m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
- m_prefs.registerOnSharedPreferenceChangeListener(this);
-
- }
-
- @Override
- public void onSaveInstanceState (Bundle out) {
- super.onSaveInstanceState(out);
-
- out.putInt("selectedFeedId", m_selectedFeedId);
- out.putInt("catId", m_catId);
- }
-
- @Override
- public void onItemClick(AdapterView<?> av, View view, int position, long id) {
- ListView list = (ListView)getActivity().findViewById(R.id.feeds);
-
- if (list != null) {
- Cursor cursor = (Cursor) list.getItemAtPosition(position);
-
- if (cursor != null) {
- int feedId = (int) cursor.getLong(0);
- Log.d(TAG, "clicked on feed " + feedId);
-
- m_offlineServices.onFeedSelected(feedId);
-
- if (!m_offlineServices.isSmallScreen())
- m_selectedFeedId = feedId;
-
- m_adapter.notifyDataSetChanged();
- }
- }
- }
-
- /* 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);
- }
- }
-
- getActivity().setProgressBarIndeterminateVisibility(showProgress);
- } */
-
- private class FeedListAdapter extends SimpleCursorAdapter {
-
-
- public FeedListAdapter(Context context, int layout, Cursor c,
- String[] from, int[] to, int flags) {
- super(context, layout, c, from, to, flags);
- }
-
- public static final int VIEW_NORMAL = 0;
- public static final int VIEW_SELECTED = 1;
-
- public static final int VIEW_COUNT = VIEW_SELECTED+1;
-
- @Override
- public int getViewTypeCount() {
- return VIEW_COUNT;
- }
-
- @Override
- public int getItemViewType(int position) {
- Cursor cursor = (Cursor) this.getItem(position);
-
- if (!m_offlineServices.isSmallScreen() && cursor.getLong(0) == m_selectedFeedId) {
- return VIEW_SELECTED;
- } else {
- return VIEW_NORMAL;
- }
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- View v = convertView;
-
- Cursor cursor = (Cursor)getItem(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(cursor.getString(cursor.getColumnIndex("title")));
- }
-
- TextView tu = (TextView) v.findViewById(R.id.unread_counter);
-
- if (tu != null) {
- tu.setText(String.valueOf(cursor.getInt(cursor.getColumnIndex("unread"))));
- tu.setVisibility((cursor.getInt(cursor.getColumnIndex("unread")) > 0) ? View.VISIBLE : View.INVISIBLE);
- }
-
- ImageView icon = (ImageView)v.findViewById(R.id.icon);
-
- if (icon != null) {
-
- if (m_enableFeedIcons) {
-
- File storage = Environment.getExternalStorageDirectory();
-
- File iconFile = new File(storage.getAbsolutePath() + ICON_PATH + cursor.getInt(cursor.getColumnIndex(BaseColumns._ID)) + ".ico");
- if (iconFile.exists()) {
- Bitmap bmpOrig = BitmapFactory.decodeFile(iconFile.getAbsolutePath());
- if (bmpOrig != null) {
- icon.setImageBitmap(bmpOrig);
- }
- } else {
- icon.setImageResource(cursor.getInt(cursor.getColumnIndex("unread")) > 0 ? R.drawable.ic_rss : R.drawable.ic_rss_bw);
- }
-
- } else {
- icon.setImageResource(cursor.getInt(cursor.getColumnIndex("unread")) > 0 ? R.drawable.ic_rss : R.drawable.ic_rss_bw);
- }
-
- }
-
- return v;
- }
- }
-
- public void sortFeeds() {
- try {
- refresh();
- } catch (NullPointerException e) {
- // activity is gone?
- } catch (IllegalStateException e) {
- // we're probably closing and DB is gone already
- }
- }
-
- @Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
- String key) {
-
- sortFeeds();
- m_enableFeedIcons = m_prefs.getBoolean("download_feed_icons", false);
-
- }
-
- public int getFeedIdAtPosition(int position) {
- Cursor c = (Cursor)m_adapter.getItem(position);
-
- if (c != null) {
- int feedId = c.getInt(0);
- c.close();
- return feedId;
- }
-
- return 0;
- }
-
- public void setSelectedFeedId(int feedId) {
- m_selectedFeedId = feedId;
- refresh();
- }
-
-}
diff --git a/src/org/fox/ttrss/offline/OfflineHeadlinesFragment.java b/src/org/fox/ttrss/offline/OfflineHeadlinesFragment.java deleted file mode 100644 index e5428f59..00000000 --- a/src/org/fox/ttrss/offline/OfflineHeadlinesFragment.java +++ /dev/null @@ -1,527 +0,0 @@ -package org.fox.ttrss.offline;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.TimeZone;
-
-import org.fox.ttrss.R;
-import org.jsoup.Jsoup;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteStatement;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.provider.BaseColumns;
-import android.support.v4.app.Fragment;
-import android.support.v4.widget.SimpleCursorAdapter;
-import android.text.Html;
-import android.text.Html.ImageGetter;
-import android.text.method.LinkMovementMethod;
-import android.util.Log;
-import android.view.ContextMenu;
-import android.view.ContextMenu.ContextMenuInfo;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.AdapterContextMenuInfo;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.CheckBox;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.TextView;
-
-public class OfflineHeadlinesFragment extends Fragment implements OnItemClickListener {
- public static enum ArticlesSelection { ALL, NONE, UNREAD };
-
- private final String TAG = this.getClass().getSimpleName();
-
- private int m_feedId;
- private boolean m_feedIsCat = false;
- private int m_activeArticleId;
- private boolean m_combinedMode = true;
- private String m_searchQuery = "";
-
- private SharedPreferences m_prefs;
-
- private Cursor m_cursor;
- private ArticleListAdapter m_adapter;
-
- private OfflineServices m_offlineServices;
-
- private ImageGetter m_dummyGetter = new ImageGetter() {
-
- @Override
- public Drawable getDrawable(String source) {
- return new BitmapDrawable();
- }
-
- };
-
- public OfflineHeadlinesFragment(int feedId, boolean isCat) {
- m_feedId = feedId;
- m_feedIsCat = isCat;
- }
-
- public OfflineHeadlinesFragment() {
- //
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
-
- if (m_cursor != null && !m_cursor.isClosed()) m_cursor.close();
- }
-
- public int getSelectedArticleCount() {
- Cursor c = m_offlineServices.getReadableDb().query("articles",
- new String[] { "COUNT(*)" }, "selected = 1", null, null, null, null);
- c.moveToFirst();
- int selected = c.getInt(0);
- c.close();
-
- return selected;
- }
-
- @Override
- public void onCreateContextMenu(ContextMenu menu, View v,
- ContextMenuInfo menuInfo) {
-
- getActivity().getMenuInflater().inflate(R.menu.headlines_menu, menu);
-
- if (getSelectedArticleCount() > 0) {
- menu.setHeaderTitle(R.string.headline_context_multiple);
- menu.setGroupVisible(R.id.menu_group_single_article, false);
- } else {
- AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo;
- Cursor c = getArticleAtPosition(info.position);
- menu.setHeaderTitle(c.getString(c.getColumnIndex("title")));
- //c.close();
- menu.setGroupVisible(R.id.menu_group_single_article, true);
- }
-
- super.onCreateContextMenu(menu, v, menuInfo);
-
- }
-
- public void refresh() {
- if (m_cursor != null && !m_cursor.isClosed()) m_cursor.close();
-
- m_cursor = createCursor();
-
- if (m_cursor != null) {
- m_adapter.changeCursor(m_cursor);
- setActiveArticleId(m_offlineServices.getSelectedArticleId());
- m_adapter.notifyDataSetChanged();
- }
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-
- if (savedInstanceState != null) {
- m_feedId = savedInstanceState.getInt("feedId");
- m_activeArticleId = savedInstanceState.getInt("activeArticleId");
- //m_selectedArticles = savedInstanceState.getParcelableArrayList("selectedArticles");
- m_combinedMode = savedInstanceState.getBoolean("combinedMode");
- m_searchQuery = (String) savedInstanceState.getCharSequence("searchQuery");
- m_feedIsCat = savedInstanceState.getBoolean("feedIsCat");
- }
-
- View view = inflater.inflate(R.layout.headlines_fragment, container, false);
-
- m_cursor = createCursor();
-
- ListView list = (ListView)view.findViewById(R.id.headlines);
- m_adapter = new ArticleListAdapter(getActivity(), R.layout.headlines_row, m_cursor,
- new String[] { "title" }, new int[] { R.id.title }, 0);
-
- list.setAdapter(m_adapter);
- list.setOnItemClickListener(this);
- list.setEmptyView(view.findViewById(R.id.no_headlines));
- registerForContextMenu(list);
-
- if (m_offlineServices.isSmallScreen() || m_offlineServices.isPortrait())
- view.findViewById(R.id.headlines_fragment).setPadding(0, 0, 0, 0);
-
- getActivity().setProgressBarIndeterminateVisibility(false);
-
- return view;
- }
-
- public Cursor createCursor() {
- String feedClause = null;
-
- if (m_feedIsCat) {
- feedClause = "feed_id IN (SELECT "+BaseColumns._ID+" FROM feeds WHERE cat_id = ?)";
- } else {
- feedClause = "feed_id = ?";
- }
-
- if (m_searchQuery.equals("")) {
- return m_offlineServices.getReadableDb().query("articles LEFT JOIN feeds ON (feed_id = feeds."+BaseColumns._ID+")",
- new String[] { "articles.*", "feeds.title AS feed_title" }, feedClause,
- new String[] { String.valueOf(m_feedId) }, null, null, "updated DESC");
- } else {
- return m_offlineServices.getReadableDb().query("articles LEFT JOIN feeds ON (feed_id = feeds."+BaseColumns._ID+")",
- new String[] { "articles.*", "feeds.title AS feed_title" },
- feedClause + " AND (articles.title LIKE '%' || ? || '%' OR content LIKE '%' || ? || '%')",
- new String[] { String.valueOf(m_feedId), m_searchQuery, m_searchQuery }, null, null, "updated DESC");
- }
- }
-
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
- m_offlineServices = (OfflineServices)activity;
-
- m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
- m_combinedMode = m_prefs.getBoolean("combined_mode", false);
- }
-
- @Override
- public void onItemClick(AdapterView<?> av, View view, int position, long id) {
- ListView list = (ListView)av;
-
- Log.d(TAG, "onItemClick=" + position);
-
- if (list != null) {
- Cursor cursor = (Cursor)list.getItemAtPosition(position);
-
- m_activeArticleId = cursor.getInt(0);
-
- SQLiteStatement stmtUpdate = m_offlineServices.getWritableDb().compileStatement("UPDATE articles SET unread = 0 " +
- "WHERE " + BaseColumns._ID + " = ?");
-
- stmtUpdate.bindLong(1, m_activeArticleId);
- stmtUpdate.execute();
- stmtUpdate.close();
-
- if (!m_combinedMode) {
- m_offlineServices.openArticle(m_activeArticleId, 0);
- }
-
- refresh();
- }
- }
-
- @Override
- public void onSaveInstanceState (Bundle out) {
- super.onSaveInstanceState(out);
-
- out.putInt("feedId", m_feedId);
- out.putInt("activeArticleId", m_activeArticleId);
- //out.putParcelableArrayList("selectedArticles", m_selectedArticles);
- out.putBoolean("combinedMode", m_combinedMode);
- out.putCharSequence("searchQuery", m_searchQuery);
- out.putBoolean("feedIsCat", m_feedIsCat);
- }
-
- /* 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);
- }
- }
-
- getActivity().setProgressBarIndeterminateVisibility(showProgress);
- } */
-
- private class ArticleListAdapter extends SimpleCursorAdapter {
- public ArticleListAdapter(Context context, int layout, Cursor c,
- String[] from, int[] to, int flags) {
- super(context, layout, c, from, to, flags);
- // TODO Auto-generated constructor stub
- }
-
- public static final int VIEW_NORMAL = 0;
- public static final int VIEW_UNREAD = 1;
- public static final int VIEW_SELECTED = 2;
- public static final int VIEW_LOADMORE = 3;
-
- public static final int VIEW_COUNT = VIEW_LOADMORE+1;
-
-
- public int getViewTypeCount() {
- return VIEW_COUNT;
- }
-
- @Override
- public int getItemViewType(int position) {
- Cursor c = (Cursor) getItem(position);
-
- //Log.d(TAG, "@gIVT " + position + " " + c.getInt(0) + " vs " + m_activeArticleId);
-
- if (c.getInt(0) == m_activeArticleId) {
- return VIEW_SELECTED;
- } else if (c.getInt(c.getColumnIndex("unread")) == 1) {
- return VIEW_UNREAD;
- } else {
- return VIEW_NORMAL;
- }
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
-
- View v = convertView;
-
- Cursor article = (Cursor)getItem(position);
- final int articleId = article.getInt(0);
-
- if (v == null) {
- int layoutId = R.layout.headlines_row;
-
- switch (getItemViewType(position)) {
- case VIEW_LOADMORE:
- layoutId = R.layout.headlines_row_loadmore;
- break;
- case VIEW_UNREAD:
- layoutId = R.layout.headlines_row_unread;
- break;
- case VIEW_SELECTED:
- layoutId = R.layout.headlines_row_selected;
- break;
- }
-
- LayoutInflater vi = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- v = vi.inflate(layoutId, null);
-
- // http://code.google.com/p/android/issues/detail?id=3414
- ((ViewGroup)v).setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
- }
-
- TextView tt = (TextView)v.findViewById(R.id.title);
-
- if (tt != null) {
- if (m_combinedMode) {
- tt.setMovementMethod(LinkMovementMethod.getInstance());
- tt.setText(Html.fromHtml("<a href=\""+article.getString(article.getColumnIndex("link")).trim().replace("\"", "\\\"")+"\">" +
- article.getString(article.getColumnIndex("title")) + "</a>"));
- } else {
- tt.setText(Html.fromHtml(article.getString(article.getColumnIndex("title"))));
- }
- }
-
- TextView ft = (TextView)v.findViewById(R.id.feed_title);
-
- int feedTitleIndex = article.getColumnIndex("feed_title");
-
- if (ft != null && feedTitleIndex != -1 && m_feedIsCat) {
- String feedTitle = article.getString(feedTitleIndex);
-
- if (feedTitle != null) {
- ft.setText(feedTitle);
- } else {
- ft.setVisibility(View.GONE);
- }
- } else if (ft != null) {
- ft.setVisibility(View.GONE);
- }
-
- ImageView marked = (ImageView)v.findViewById(R.id.marked);
-
- if (marked != null) {
- marked.setImageResource(article.getInt(article.getColumnIndex("marked")) == 1 ? android.R.drawable.star_on : android.R.drawable.star_off);
-
- marked.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- SQLiteStatement stmtUpdate = m_offlineServices.getWritableDb().compileStatement("UPDATE articles SET marked = NOT marked " +
- "WHERE " + BaseColumns._ID + " = ?");
-
- stmtUpdate.bindLong(1, articleId);
- stmtUpdate.execute();
- stmtUpdate.close();
-
- refresh();
- }
- });
- }
-
- ImageView published = (ImageView)v.findViewById(R.id.published);
-
- if (published != null) {
- published.setImageResource(article.getInt(article.getColumnIndex("published")) == 1 ? R.drawable.ic_rss : R.drawable.ic_rss_bw);
-
- published.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- SQLiteStatement stmtUpdate = m_offlineServices.getWritableDb().compileStatement("UPDATE articles SET published = NOT published " +
- "WHERE " + BaseColumns._ID + " = ?");
-
- stmtUpdate.bindLong(1, articleId);
- stmtUpdate.execute();
- stmtUpdate.close();
-
- refresh();
- }
- });
- }
-
- TextView te = (TextView)v.findViewById(R.id.excerpt);
-
- if (te != null) {
- if (!m_combinedMode) {
- String excerpt = Jsoup.parse(article.getString(article.getColumnIndex("content"))).text();
-
- if (excerpt.length() > 100)
- excerpt = excerpt.substring(0, 100) + "...";
-
- te.setText(excerpt);
- } else {
- te.setVisibility(View.GONE);
- }
- }
-
- /* ImageView separator = (ImageView)v.findViewById(R.id.headlines_separator);
-
- if (separator != null && m_offlineServices.isSmallScreen()) {
- separator.setVisibility(View.GONE);
- } */
-
- TextView content = (TextView)v.findViewById(R.id.content);
-
- if (content != null) {
- if (m_combinedMode) {
- content.setMovementMethod(LinkMovementMethod.getInstance());
-
- content.setText(Html.fromHtml(article.getString(article.getColumnIndex("content")), m_dummyGetter, null));
-
- switch (Integer.parseInt(m_prefs.getString("font_size", "0"))) {
- case 0:
- content.setTextSize(15F);
- break;
- case 1:
- content.setTextSize(18F);
- break;
- case 2:
- content.setTextSize(21F);
- break;
- }
- } else {
- content.setVisibility(View.GONE);
- }
- }
-
- v.findViewById(R.id.attachments_holder).setVisibility(View.GONE);
-
- TextView dv = (TextView) v.findViewById(R.id.date);
-
- if (dv != null) {
- Date d = new Date((long)article.getInt(article.getColumnIndex("updated")) * 1000);
- DateFormat df = new SimpleDateFormat("MMM dd, HH:mm");
- df.setTimeZone(TimeZone.getDefault());
- dv.setText(df.format(d));
- }
-
- CheckBox cb = (CheckBox) v.findViewById(R.id.selected);
-
- if (cb != null) {
- cb.setChecked(article.getInt(article.getColumnIndex("selected")) == 1);
- cb.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View view) {
- CheckBox cb = (CheckBox)view;
-
- SQLiteStatement stmtUpdate = m_offlineServices.getWritableDb().compileStatement("UPDATE articles SET selected = ? " +
- "WHERE " + BaseColumns._ID + " = ?");
-
- stmtUpdate.bindLong(1, cb.isChecked() ? 1 : 0);
- stmtUpdate.bindLong(2, articleId);
- stmtUpdate.execute();
- stmtUpdate.close();
-
- refresh();
-
- m_offlineServices.initMainMenu();
-
- }
- });
- }
-
- ImageButton ib = (ImageButton) v.findViewById(R.id.article_menu_button);
-
- if (ib != null) {
- ib.setVisibility(android.os.Build.VERSION.SDK_INT >= 10 ? View.VISIBLE : View.GONE);
- ib.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- getActivity().openContextMenu(v);
- }
- });
- }
-
- return v;
- }
- }
-
- public void notifyUpdated() {
- m_adapter.notifyDataSetChanged();
- }
-
- public void setActiveArticleId(int articleId) {
- m_activeArticleId = articleId;
- // m_adapter.notifyDataSetChanged();
-
- ListView list = (ListView)getView().findViewById(R.id.headlines);
-
- if (list != null) {
- list.setSelection(getArticleIdPosition(articleId));
- }
- }
-
- public Cursor getArticleAtPosition(int position) {
- return (Cursor) m_adapter.getItem(position);
- }
-
- public int getArticleIdAtPosition(int position) {
- /*Cursor c = getArticleAtPosition(position);
-
- if (c != null) {
- int id = c.getInt(0);
- return id;
- } */
-
- return (int) m_adapter.getItemId(position);
- }
-
- public int getActiveArticleId() {
- return m_activeArticleId;
- }
-
- public int getArticleIdPosition(int articleId) {
- for (int i = 0; i < m_adapter.getCount(); i++) {
- if (articleId == m_adapter.getItemId(i))
- return i;
- }
-
- return 0;
- }
-
- public int getArticleCount() {
- return m_adapter.getCount();
- }
-
- public void setSearchQuery(String query) {
- if (!m_searchQuery.equals(query)) {
- m_searchQuery = query;
- refresh();
- }
- }
-
-}
diff --git a/src/org/fox/ttrss/offline/OfflineServices.java b/src/org/fox/ttrss/offline/OfflineServices.java deleted file mode 100644 index 8483c97f..00000000 --- a/src/org/fox/ttrss/offline/OfflineServices.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.fox.ttrss.offline;
-
-import org.fox.ttrss.OnlineServices;
-
-import android.database.sqlite.SQLiteDatabase;
-
-public interface OfflineServices {
- public int getActiveFeedId();
- public SQLiteDatabase getReadableDb();
- public SQLiteDatabase getWritableDb();
- public int getRelativeArticleId(int baseId, int feedId, OnlineServices.RelativeArticle mode);
- public void onFeedSelected(int feedId);
- public void onCatSelected(int catId);
- public void openArticle(int articleId, int compatAnimation);
- public boolean getUnreadOnly();
- public int getSelectedArticleId();
- public void initMainMenu();
- public boolean isSmallScreen();
- public void setSelectedArticleId(int articleId);
- public boolean activeFeedIsCat();
- public boolean isPortrait();
-}
diff --git a/src/org/fox/ttrss/offline/OfflineUploadService.java b/src/org/fox/ttrss/offline/OfflineUploadService.java deleted file mode 100644 index 84a7fc92..00000000 --- a/src/org/fox/ttrss/offline/OfflineUploadService.java +++ /dev/null @@ -1,264 +0,0 @@ -package org.fox.ttrss.offline;
-
-import java.util.HashMap;
-
-import org.fox.ttrss.ApiRequest;
-import org.fox.ttrss.MainActivity;
-import org.fox.ttrss.R;
-import org.fox.ttrss.util.DatabaseHelper;
-
-import android.app.IntentService;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.Intent;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.util.Log;
-
-import com.google.gson.JsonElement;
-
-public class OfflineUploadService extends IntentService {
- private final String TAG = this.getClass().getSimpleName();
-
- public static final int NOTIFY_UPLOADING = 2;
- public static final String INTENT_ACTION_SUCCESS = "org.fox.ttrss.intent.action.UploadComplete";
-
- private SQLiteDatabase m_writableDb;
- private SQLiteDatabase m_readableDb;
- private String m_sessionId;
- private NotificationManager m_nmgr;
- private boolean m_uploadInProgress = false;
-
- public OfflineUploadService() {
- super("OfflineUploadService");
- }
-
- @Override
- public void onCreate() {
- super.onCreate();
- m_nmgr = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
- initDatabase();
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
-
- m_nmgr.cancel(NOTIFY_UPLOADING);
- }
-
- private void updateNotification(String msg) {
- Notification notification = new Notification(R.drawable.icon,
- getString(R.string.notify_uploading_title), System.currentTimeMillis());
-
- PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
- new Intent(this, MainActivity.class), 0);
-
- notification.flags |= Notification.FLAG_ONGOING_EVENT;
- notification.flags |= Notification.FLAG_ONLY_ALERT_ONCE;
-
- notification.setLatestEventInfo(this, getString(R.string.notify_uploading_title), msg, contentIntent);
-
- m_nmgr.notify(NOTIFY_UPLOADING, notification);
- }
-
- private void updateNotification(int msgResId) {
- updateNotification(getString(msgResId));
- }
-
- private void initDatabase() {
- DatabaseHelper dh = new DatabaseHelper(getApplicationContext());
- m_writableDb = dh.getWritableDatabase();
- m_readableDb = dh.getReadableDatabase();
- }
-
- private synchronized SQLiteDatabase getReadableDb() {
- return m_readableDb;
- }
-
- private synchronized SQLiteDatabase getWritableDb() {
- return m_writableDb;
- }
-
- private void uploadRead() {
- Log.d(TAG, "syncing modified offline data... (read)");
-
- final String ids = getModifiedIds(ModifiedCriteria.READ);
-
- if (ids.length() > 0) {
- ApiRequest req = new ApiRequest(getApplicationContext()) {
- @Override
- protected void onPostExecute(JsonElement result) {
- if (result != null) {
- uploadMarked();
- } else {
- updateNotification(getErrorMessage());
- uploadFailed();
- }
- }
- };
-
- @SuppressWarnings("serial")
- HashMap<String, String> map = new HashMap<String, String>() {
- {
- put("sid", m_sessionId);
- put("op", "updateArticle");
- put("article_ids", ids);
- put("mode", "0");
- put("field", "2");
- }
- };
-
- req.execute(map);
- } else {
- uploadMarked();
- }
- }
-
- private enum ModifiedCriteria {
- READ, MARKED, PUBLISHED
- };
-
- private String getModifiedIds(ModifiedCriteria criteria) {
-
- String criteriaStr = "";
-
- switch (criteria) {
- case READ:
- criteriaStr = "unread = 0";
- break;
- case MARKED:
- criteriaStr = "marked = 1";
- break;
- case PUBLISHED:
- criteriaStr = "published = 1";
- break;
- }
-
- Cursor c = getReadableDb().query("articles", null,
- "modified = 1 AND " + criteriaStr, null, null, null, null);
-
- String tmp = "";
-
- while (c.moveToNext()) {
- tmp += c.getInt(0) + ",";
- }
-
- tmp = tmp.replaceAll(",$", "");
-
- c.close();
-
- return tmp;
- }
-
- private void uploadMarked() {
- Log.d(TAG, "syncing modified offline data... (marked)");
-
- final String ids = getModifiedIds(ModifiedCriteria.MARKED);
-
- if (ids.length() > 0) {
- ApiRequest req = new ApiRequest(getApplicationContext()) {
- @Override
- protected void onPostExecute(JsonElement result) {
- if (result != null) {
- uploadPublished();
- } else {
- updateNotification(getErrorMessage());
- uploadFailed();
- }
- }
- };
-
- @SuppressWarnings("serial")
- HashMap<String, String> map = new HashMap<String, String>() {
- {
- put("sid", m_sessionId);
- put("op", "updateArticle");
- put("article_ids", ids);
- put("mode", "0");
- put("field", "0");
- }
- };
-
- req.execute(map);
- } else {
- uploadPublished();
- }
- }
-
- private void uploadFailed() {
- m_readableDb.close();
- m_writableDb.close();
-
- // TODO send notification to activity?
-
- m_uploadInProgress = false;
- }
-
- private void uploadSuccess() {
- getWritableDb().execSQL("UPDATE articles SET modified = 0");
-
- Intent intent = new Intent();
- intent.setAction(INTENT_ACTION_SUCCESS);
- intent.addCategory(Intent.CATEGORY_DEFAULT);
- sendBroadcast(intent);
-
- m_readableDb.close();
- m_writableDb.close();
-
- m_uploadInProgress = false;
-
- m_nmgr.cancel(NOTIFY_UPLOADING);
- }
-
- private void uploadPublished() {
- Log.d(TAG, "syncing modified offline data... (published)");
-
- final String ids = getModifiedIds(ModifiedCriteria.MARKED);
-
- if (ids.length() > 0) {
- ApiRequest req = new ApiRequest(getApplicationContext()) {
- @Override
- protected void onPostExecute(JsonElement result) {
- if (result != null) {
- uploadSuccess();
- } else {
- updateNotification(getErrorMessage());
- uploadFailed();
- }
- }
- };
-
- @SuppressWarnings("serial")
- HashMap<String, String> map = new HashMap<String, String>() {
- {
- put("sid", m_sessionId);
- put("op", "updateArticle");
- put("article_ids", ids);
- put("mode", "0");
- put("field", "1");
- }
- };
-
- req.execute(map);
- } else {
- uploadSuccess();
- }
- }
-
-
- @Override
- protected void onHandleIntent(Intent intent) {
- m_sessionId = intent.getStringExtra("sessionId");
-
- if (!m_uploadInProgress) {
- m_uploadInProgress = true;
-
- updateNotification(R.string.notify_uploading_sending_data);
-
- uploadRead();
- }
- }
-
-}
diff --git a/src/org/fox/ttrss/util/ApiRequest.java b/src/org/fox/ttrss/util/ApiRequest.java new file mode 100644 index 00000000..56901393 --- /dev/null +++ b/src/org/fox/ttrss/util/ApiRequest.java @@ -0,0 +1,257 @@ +package org.fox.ttrss.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+
+import org.apache.http.HttpHost;
+import org.apache.http.HttpResponse;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.protocol.ClientContext;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.HttpContext;
+import org.fox.ttrss.R;
+import org.fox.ttrss.R.string;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.net.http.AndroidHttpClient;
+import android.os.AsyncTask;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+
+public class ApiRequest extends AsyncTask<HashMap<String,String>, Integer, JsonElement> {
+ private final String TAG = this.getClass().getSimpleName();
+
+ public enum ApiError { NO_ERROR, HTTP_UNAUTHORIZED, HTTP_FORBIDDEN, HTTP_NOT_FOUND,
+ HTTP_SERVER_ERROR, HTTP_OTHER_ERROR, SSL_REJECTED, PARSE_ERROR, IO_ERROR, OTHER_ERROR, API_DISABLED, API_UNKNOWN, LOGIN_FAILED, INVALID_URL, INCORRECT_USAGE };
+
+ public static final int API_STATUS_OK = 0;
+ public static final int API_STATUS_ERR = 1;
+
+ private String m_api;
+ private boolean m_trustAny = false;
+ private boolean m_transportDebugging = false;
+ protected int m_httpStatusCode = 0;
+ protected int m_apiStatusCode = 0;
+ protected Context m_context;
+ private SharedPreferences m_prefs;
+
+ protected ApiError m_lastError;
+
+ public ApiRequest(Context context) {
+ m_context = context;
+
+ m_prefs = PreferenceManager.getDefaultSharedPreferences(m_context);
+
+ m_api = m_prefs.getString("ttrss_url", null).trim();
+ m_trustAny = m_prefs.getBoolean("ssl_trust_any", false);
+ m_transportDebugging = m_prefs.getBoolean("transport_debugging", false);
+ m_lastError = ApiError.NO_ERROR;
+
+ }
+
+ protected int getErrorMessage() {
+ switch (m_lastError) {
+ case NO_ERROR:
+ return R.string.error_unknown;
+ case HTTP_UNAUTHORIZED:
+ return R.string.error_http_unauthorized;
+ case HTTP_FORBIDDEN:
+ return R.string.error_http_forbidden;
+ case HTTP_NOT_FOUND:
+ return R.string.error_http_not_found;
+ case HTTP_SERVER_ERROR:
+ return R.string.error_http_server_error;
+ case HTTP_OTHER_ERROR:
+ return R.string.error_http_other_error;
+ case SSL_REJECTED:
+ return R.string.error_ssl_rejected;
+ case PARSE_ERROR:
+ return R.string.error_parse_error;
+ case IO_ERROR:
+ return R.string.error_io_error;
+ case OTHER_ERROR:
+ return R.string.error_other_error;
+ case API_DISABLED:
+ return R.string.error_api_disabled;
+ case API_UNKNOWN:
+ return R.string.error_api_unknown;
+ case LOGIN_FAILED:
+ return R.string.error_login_failed;
+ case INVALID_URL:
+ return R.string.error_invalid_api_url;
+ case INCORRECT_USAGE:
+ return R.string.error_api_incorrect_usage;
+ default:
+ Log.d(TAG, "getErrorMessage: unknown error code=" + m_lastError);
+ return R.string.error_unknown;
+ }
+ }
+
+ @Override
+ protected JsonElement doInBackground(HashMap<String, String>... params) {
+
+ Gson gson = new Gson();
+
+ String requestStr = gson.toJson(new HashMap<String,String>(params[0]));
+
+ if (m_transportDebugging) Log.d(TAG, ">>> (" + requestStr + ") " + m_api);
+
+ AndroidHttpClient client = AndroidHttpClient.newInstance("Tiny Tiny RSS"); +
+ if (m_trustAny) {
+ client.getConnectionManager().getSchemeRegistry().register(new Scheme("https", new EasySSLSocketFactory(), 443)); + }
+
+ try {
+
+ HttpPost httpPost;
+
+ try {
+ httpPost = new HttpPost(m_api + "/api/");
+ } catch (IllegalArgumentException e) {
+ m_lastError = ApiError.INVALID_URL;
+ e.printStackTrace();
+ client.close();
+ return null;
+ } catch (Exception e) {
+ m_lastError = ApiError.OTHER_ERROR;
+ e.printStackTrace();
+ client.close();
+ return null;
+ }
+
+ HttpContext context = null; + + String httpLogin = m_prefs.getString("http_login", "").trim();
+ String httpPassword = m_prefs.getString("http_password", "").trim();
+
+ if (httpLogin.length() > 0) {
+ if (m_transportDebugging) Log.d(TAG, "Using HTTP Basic authentication.");
+
+ URL targetUrl;
+ try {
+ targetUrl = new URL(m_api);
+ } catch (MalformedURLException e) {
+ m_lastError = ApiError.INVALID_URL;
+ e.printStackTrace();
+ client.close();
+ return null;
+ }
+
+ HttpHost targetHost = new HttpHost(targetUrl.getHost(), targetUrl.getPort(), targetUrl.getProtocol());
+ CredentialsProvider cp = new BasicCredentialsProvider(); + context = new BasicHttpContext(); +
+ cp.setCredentials( + new AuthScope(targetHost.getHostName(), targetHost.getPort()),
+ new UsernamePasswordCredentials(httpLogin, httpPassword));
+ + context.setAttribute(ClientContext.CREDS_PROVIDER, cp); + }
+
+ httpPost.setEntity(new StringEntity(requestStr, "utf-8"));
+ HttpResponse execute = client.execute(httpPost, context); +
+ m_httpStatusCode = execute.getStatusLine().getStatusCode();
+
+ switch (m_httpStatusCode) {
+ case 200:
+ InputStream content = execute.getEntity().getContent();
+
+ BufferedReader buffer = new BufferedReader(
+ new InputStreamReader(content), 8192);
+
+ String s = "";
+ String response = "";
+
+ while ((s = buffer.readLine()) != null) {
+ response += s;
+ }
+
+ if (m_transportDebugging) Log.d(TAG, "<<< " + response);
+
+ JsonParser parser = new JsonParser();
+
+ JsonElement result = parser.parse(response);
+ JsonObject resultObj = result.getAsJsonObject();
+
+ m_apiStatusCode = resultObj.get("status").getAsInt();
+
+ client.close();
+
+ switch (m_apiStatusCode) {
+ case API_STATUS_OK:
+ return result.getAsJsonObject().get("content");
+ case API_STATUS_ERR:
+ JsonObject contentObj = resultObj.get("content").getAsJsonObject();
+ String error = contentObj.get("error").getAsString();
+
+ if (error.equals("LOGIN_ERROR")) {
+ m_lastError = ApiError.LOGIN_FAILED;
+ } else if (error.equals("API_DISABLED")) {
+ m_lastError = ApiError.API_DISABLED;
+ } else if (error.equals("NOT_LOGGED_IN")) {
+ m_lastError = ApiError.LOGIN_FAILED;
+ } else if (error.equals("INCORRECT_USAGE")) {
+ m_lastError = ApiError.INCORRECT_USAGE;
+ } else {
+ Log.d(TAG, "Unknown API error: " + error);
+ m_lastError = ApiError.API_UNKNOWN;
+ }
+ }
+
+ return null;
+ case 401:
+ m_lastError = ApiError.HTTP_UNAUTHORIZED;
+ break;
+ case 403:
+ m_lastError = ApiError.HTTP_FORBIDDEN;
+ break;
+ case 404:
+ m_lastError = ApiError.HTTP_NOT_FOUND;
+ break;
+ case 500:
+ m_lastError = ApiError.HTTP_SERVER_ERROR;
+ break;
+ default:
+ m_lastError = ApiError.HTTP_OTHER_ERROR;
+ break;
+ }
+
+ client.close();
+ return null;
+ } catch (javax.net.ssl.SSLPeerUnverifiedException e) {
+ m_lastError = ApiError.SSL_REJECTED;
+ e.printStackTrace();
+ } catch (IOException e) {
+ m_lastError = ApiError.IO_ERROR;
+ e.printStackTrace();
+ } catch (com.google.gson.JsonSyntaxException e) {
+ m_lastError = ApiError.PARSE_ERROR;
+ e.printStackTrace();
+ } catch (Exception e) {
+ m_lastError = ApiError.OTHER_ERROR;
+ e.printStackTrace();
+ }
+
+ client.close();
+ return null;
+ }
+}
diff --git a/src/org/fox/ttrss/util/ImageCacheService.java b/src/org/fox/ttrss/util/ImageCacheService.java deleted file mode 100644 index 25c4aff0..00000000 --- a/src/org/fox/ttrss/util/ImageCacheService.java +++ /dev/null @@ -1,208 +0,0 @@ -package org.fox.ttrss.util;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.net.URLConnection;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Date;
-
-import org.fox.ttrss.MainActivity;
-import org.fox.ttrss.R;
-import org.fox.ttrss.offline.OfflineDownloadService;
-
-import android.app.ActivityManager;
-import android.app.ActivityManager.RunningServiceInfo;
-import android.app.IntentService;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.Intent;
-import android.os.Environment;
-
-public class ImageCacheService extends IntentService {
-
- private final String TAG = this.getClass().getSimpleName();
-
- public static final int NOTIFY_DOWNLOADING = 1;
-
- private static final String CACHE_PATH = "/data/org.fox.ttrss/image-cache/";
-
- private int m_imagesDownloaded = 0;
-
- private NotificationManager m_nmgr;
-
- public ImageCacheService() {
- super("ImageCacheService");
- }
-
- private boolean isDownloadServiceRunning() {
- ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
- for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
- if ("org.fox.ttrss.OfflineDownloadService".equals(service.service.getClassName())) {
- return true;
- }
- }
- return false;
- }
-
-
- @Override
- public void onCreate() {
- super.onCreate();
- m_nmgr = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
- }
-
- public static boolean isUrlCached(String url) {
- String hashedUrl = md5(url);
-
- File storage = Environment.getExternalStorageDirectory();
-
- File file = new File(storage.getAbsolutePath() + CACHE_PATH + "/" + hashedUrl + ".png");
-
- return file.exists();
- }
-
- public static String getCacheFileName(String url) {
- String hashedUrl = md5(url);
-
- File storage = Environment.getExternalStorageDirectory();
-
- File file = new File(storage.getAbsolutePath() + CACHE_PATH + "/" + hashedUrl + ".png");
-
- return file.getAbsolutePath();
- }
-
- public static void cleanupCache(boolean deleteAll) {
- if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
- File storage = Environment.getExternalStorageDirectory();
- File cachePath = new File(storage.getAbsolutePath() + CACHE_PATH);
-
- long now = new Date().getTime();
-
- if (cachePath.isDirectory()) {
- for (File file : cachePath.listFiles()) {
- if (deleteAll || now - file.lastModified() > 1000*60*60*24*7) {
- file.delete();
- }
- }
- }
- }
- }
-
- protected static String md5(String s) {
- try {
- MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
- digest.update(s.getBytes());
- byte messageDigest[] = digest.digest();
-
- StringBuffer hexString = new StringBuffer();
- for (int i=0; i<messageDigest.length; i++)
- hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
-
- return hexString.toString();
-
- } catch (NoSuchAlgorithmException e) {
- e.printStackTrace();
- }
-
- return null;
- }
-
- private InputStream getStream(String urlString) {
- try {
- URL url = new URL(urlString);
- URLConnection urlConnection = url.openConnection();
- urlConnection.setConnectTimeout(250);
- return urlConnection.getInputStream();
- } catch (Exception ex) {
- return null;
- }
- }
-
- private void updateNotification(String msg) {
- Notification notification = new Notification(R.drawable.icon,
- getString(R.string.notify_downloading_title), System.currentTimeMillis());
-
- PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
- new Intent(this, MainActivity.class), 0);
-
- notification.flags |= Notification.FLAG_ONGOING_EVENT;
- notification.flags |= Notification.FLAG_ONLY_ALERT_ONCE;
-
- notification.setLatestEventInfo(this, getString(R.string.notify_downloading_title), msg, contentIntent);
-
- m_nmgr.notify(NOTIFY_DOWNLOADING, notification);
- }
-
- /* private void updateNotification(int msgResId) {
- updateNotification(getString(msgResId));
- } */
-
- @Override
- protected void onHandleIntent(Intent intent) {
- String url = intent.getStringExtra("url");
-
- //Log.d(TAG, "got request to download URL=" + url);
-
- if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))
- return;
-
- String hashedUrl = md5(url);
-
- File storage = Environment.getExternalStorageDirectory();
- File cachePath = new File(storage.getAbsolutePath() + CACHE_PATH);
- if (!cachePath.exists()) cachePath.mkdirs();
-
- if (cachePath.isDirectory() && hashedUrl != null) {
- File outputFile = new File(cachePath.getAbsolutePath() + "/" + hashedUrl + ".png");
-
- if (!outputFile.exists()) {
-
- //Log.d(TAG, "downloading to " + outputFile.getAbsolutePath());
-
- InputStream is = getStream(url);
-
- if (is != null) {
- try {
- FileOutputStream fos = new FileOutputStream(outputFile);
-
- byte[] buffer = new byte[1024];
- int len = 0;
- while ((len = is.read(buffer)) != -1) {
- fos.write(buffer, 0, len);
- }
-
- fos.close();
- is.close();
-
- m_imagesDownloaded++;
-
- updateNotification(getString(R.string.notify_downloading_images, m_imagesDownloaded));
-
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
-
- if (!isDownloadServiceRunning()) {
- m_nmgr.cancel(NOTIFY_DOWNLOADING);
-
- Intent success = new Intent();
- success.setAction(OfflineDownloadService.INTENT_ACTION_SUCCESS);
- success.addCategory(Intent.CATEGORY_DEFAULT);
- sendBroadcast(success);
- }
- }
-
-}
|