diff --git a/media/android/NewsBlur/AndroidManifest.xml b/media/android/NewsBlur/AndroidManifest.xml index 1ab1ba669..88b3ccffb 100644 --- a/media/android/NewsBlur/AndroidManifest.xml +++ b/media/android/NewsBlur/AndroidManifest.xml @@ -1,8 +1,8 @@ + android:versionCode="30" + android:versionName="1.0.6" > + + + \ No newline at end of file diff --git a/media/android/NewsBlur/res/values/strings.xml b/media/android/NewsBlur/res/values/strings.xml index 1a049eb52..18ca9985a 100644 --- a/media/android/NewsBlur/res/values/strings.xml +++ b/media/android/NewsBlur/res/values/strings.xml @@ -141,5 +141,6 @@ Let's go! %d PUBLIC COMMENTS %d COMMENTS + All stories marked as read diff --git a/media/android/NewsBlur/src/com/newsblur/activity/AllStoriesItemsList.java b/media/android/NewsBlur/src/com/newsblur/activity/AllStoriesItemsList.java index 5ae896e78..e7f3f21fe 100644 --- a/media/android/NewsBlur/src/com/newsblur/activity/AllStoriesItemsList.java +++ b/media/android/NewsBlur/src/com/newsblur/activity/AllStoriesItemsList.java @@ -2,22 +2,31 @@ package com.newsblur.activity; import java.util.ArrayList; +import android.content.ContentResolver; +import android.content.ContentValues; import android.content.Intent; import android.database.Cursor; +import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.app.FragmentTransaction; +import android.widget.Toast; +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuInflater; import com.newsblur.R; import com.newsblur.database.DatabaseConstants; import com.newsblur.database.FeedProvider; import com.newsblur.fragment.AllStoriesItemListFragment; import com.newsblur.fragment.FeedItemListFragment; import com.newsblur.fragment.SyncUpdateFragment; +import com.newsblur.network.APIManager; import com.newsblur.service.SyncService; public class AllStoriesItemsList extends ItemsList { private ArrayList feedIds; + private APIManager apiManager; + private ContentResolver resolver; private boolean stopLoading = false; @Override @@ -27,8 +36,10 @@ public class AllStoriesItemsList extends ItemsList { setTitle(getResources().getString(R.string.all_stories)); feedIds = new ArrayList(); - - Cursor cursor = getContentResolver().query(FeedProvider.FEEDS_URI, null, FeedProvider.getStorySelectionFromState(currentState), null, null); + apiManager = new APIManager(this); + resolver = getContentResolver(); + + Cursor cursor = resolver.query(FeedProvider.FEEDS_URI, null, FeedProvider.getStorySelectionFromState(currentState), null, null); while (cursor.moveToNext()) { feedIds.add(cursor.getString(cursor.getColumnIndex(DatabaseConstants.FEED_ID))); @@ -76,8 +87,41 @@ public class AllStoriesItemsList extends ItemsList { @Override - public void markItemListAsRead() { } + public void markItemListAsRead() { + new AsyncTask() { + @Override + protected Boolean doInBackground(Void... arg) { + return apiManager.markAllAsRead(); + } + + @Override + protected void onPostExecute(Boolean result) { + if (result) { + // mark all feed IDs as read + ContentValues values = new ContentValues(); + values.put(DatabaseConstants.FEED_NEGATIVE_COUNT, 0); + values.put(DatabaseConstants.FEED_NEUTRAL_COUNT, 0); + values.put(DatabaseConstants.FEED_POSITIVE_COUNT, 0); + for (String feedId : feedIds) { + resolver.update(FeedProvider.FEEDS_URI.buildUpon().appendPath(feedId).build(), values, null, null); + } + setResult(RESULT_OK); + Toast.makeText(AllStoriesItemsList.this, R.string.toast_marked_all_stories_as_read, Toast.LENGTH_SHORT).show(); + finish(); + } else { + Toast.makeText(AllStoriesItemsList.this, R.string.toast_error_marking_feed_as_read, Toast.LENGTH_SHORT).show(); + } + }; + }.execute(); + } + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + MenuInflater inflater = getSupportMenuInflater(); + inflater.inflate(R.menu.allstories_itemslist, menu); + return true; + } @Override public void setNothingMoreToUpdate() { diff --git a/media/android/NewsBlur/src/com/newsblur/activity/Profile.java b/media/android/NewsBlur/src/com/newsblur/activity/Profile.java index dc7de8bdb..3c413ae60 100644 --- a/media/android/NewsBlur/src/com/newsblur/activity/Profile.java +++ b/media/android/NewsBlur/src/com/newsblur/activity/Profile.java @@ -78,7 +78,7 @@ public class Profile extends SherlockFragmentActivity { @Override protected void onPreExecute() { if (TextUtils.isEmpty(userId)) { - detailsFragment.setUser(PrefsUtils.getUserDetails(Profile.this), true); + detailsFragment.setUser(Profile.this, PrefsUtils.getUserDetails(Profile.this), true); } } @@ -102,8 +102,9 @@ public class Profile extends SherlockFragmentActivity { @Override protected void onPostExecute(Void result) { if (user != null && detailsFragment != null && activitiesFragment != null) { - detailsFragment.setUser(user, TextUtils.isEmpty(userId)); - activitiesFragment.setActivitiesAndUser(activities, user); + detailsFragment.setUser(Profile.this, user, TextUtils.isEmpty(userId)); + // TODO still sometimes causes a force close - is activities null ? + activitiesFragment.setActivitiesAndUser(Profile.this, activities, user); } } } diff --git a/media/android/NewsBlur/src/com/newsblur/domain/ValueMultimap.java b/media/android/NewsBlur/src/com/newsblur/domain/ValueMultimap.java index 3c8e694a4..9c94eabd0 100644 --- a/media/android/NewsBlur/src/com/newsblur/domain/ValueMultimap.java +++ b/media/android/NewsBlur/src/com/newsblur/domain/ValueMultimap.java @@ -74,4 +74,7 @@ public class ValueMultimap implements Serializable { return builder.toString(); } + public int size() { + return multimap.size(); + } } diff --git a/media/android/NewsBlur/src/com/newsblur/fragment/AddSitesListFragment.java b/media/android/NewsBlur/src/com/newsblur/fragment/AddSitesListFragment.java index 1012393b5..e3dda7fc8 100644 --- a/media/android/NewsBlur/src/com/newsblur/fragment/AddSitesListFragment.java +++ b/media/android/NewsBlur/src/com/newsblur/fragment/AddSitesListFragment.java @@ -193,8 +193,11 @@ public class AddSitesListFragment extends Fragment { feedImage.setAlpha(125); } - for (View feedBorder : feedBorderViews) { - feedBorder.setAlpha(125); + // View.setAlpha only support on API level >= 11 + if (Build.VERSION.SDK_INT > 10) { + for (View feedBorder : feedBorderViews) { + feedBorder.setAlpha(125); + } } } @@ -208,8 +211,11 @@ public class AddSitesListFragment extends Fragment { feedImage.setAlpha(255); } - for (View feedBorder : feedBorderViews) { - feedBorder.setAlpha(255); + // View.setAlpha only support on API level >= 11 + if (Build.VERSION.SDK_INT > 10) { + for (View feedBorder : feedBorderViews) { + feedBorder.setAlpha(255); + } } } diff --git a/media/android/NewsBlur/src/com/newsblur/fragment/FolderListFragment.java b/media/android/NewsBlur/src/com/newsblur/fragment/FolderListFragment.java index c7679557f..caf7a555c 100644 --- a/media/android/NewsBlur/src/com/newsblur/fragment/FolderListFragment.java +++ b/media/android/NewsBlur/src/com/newsblur/fragment/FolderListFragment.java @@ -1,11 +1,15 @@ package com.newsblur.fragment; +import java.util.ArrayList; +import java.util.List; + import android.app.Activity; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Intent; import android.content.SharedPreferences; import android.database.Cursor; +import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.ContextMenu; @@ -34,7 +38,6 @@ import com.newsblur.database.MixedExpandableListAdapter; import com.newsblur.network.APIManager; import com.newsblur.network.MarkFeedAsReadTask; import com.newsblur.network.MarkFolderAsReadTask; -import com.newsblur.network.MarkSocialFeedAsReadTask; import com.newsblur.util.AppConstants; import com.newsblur.util.PrefConstants; import com.newsblur.util.UIUtils; @@ -180,6 +183,8 @@ public class FolderListFragment extends Fragment implements OnGroupClickListener case R.id.menu_mark_folder_as_read: int groupPosition = ExpandableListView.getPackedPositionGroup(info.packedPosition); + // all shared stories and regular folders are expandable + // all stories is not expandable if (folderAdapter.isExpandable(groupPosition)) { final Cursor folderCursor = ((MixedExpandableListAdapter) list.getExpandableListAdapter()).getGroup(groupPosition); String folderId = folderCursor.getString(folderCursor.getColumnIndex(DatabaseConstants.FOLDER_NAME)); @@ -195,7 +200,8 @@ public class FolderListFragment extends Fragment implements OnGroupClickListener } }.execute(folderId); } else { - final Cursor socialFeedCursor = ((MixedExpandableListAdapter) list.getExpandableListAdapter()).getGroup(groupPosition); + // TODO is social feed actually all shared stories ? Should this be used for expandable and position == 0 ? + /*final Cursor socialFeedCursor = ((MixedExpandableListAdapter) list.getExpandableListAdapter()).getGroup(groupPosition); String socialFeedId = socialFeedCursor.getString(socialFeedCursor.getColumnIndex(DatabaseConstants.SOCIAL_FEED_ID)); new MarkSocialFeedAsReadTask(apiManager, resolver){ @Override @@ -207,7 +213,37 @@ public class FolderListFragment extends Fragment implements OnGroupClickListener Toast.makeText(getActivity(), R.string.toast_error_marking_feed_as_read, Toast.LENGTH_LONG).show(); } } - }.execute(socialFeedId); + }.execute(socialFeedId);*/ + + new AsyncTask() { + private List feedIds = new ArrayList(); + + @Override + protected Boolean doInBackground(Void... arg) { + Cursor cursor = resolver.query(FeedProvider.FEEDS_URI, null, FeedProvider.getStorySelectionFromState(currentState), null, null); + while (cursor.moveToNext()) { + feedIds.add(cursor.getString(cursor.getColumnIndex(DatabaseConstants.FEED_ID))); + } + return apiManager.markAllAsRead(); + } + + @Override + protected void onPostExecute(Boolean result) { + if (result) { + ContentValues values = new ContentValues(); + values.put(DatabaseConstants.FEED_NEGATIVE_COUNT, 0); + values.put(DatabaseConstants.FEED_NEUTRAL_COUNT, 0); + values.put(DatabaseConstants.FEED_POSITIVE_COUNT, 0); + for (String feedId : feedIds) { + resolver.update(FeedProvider.FEEDS_URI.buildUpon().appendPath(feedId).build(), values, null, null); + } + folderAdapter.requery(); + Toast.makeText(getActivity(), R.string.toast_marked_all_stories_as_read, Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(getActivity(), R.string.toast_error_marking_feed_as_read, Toast.LENGTH_SHORT).show(); + } + }; + }.execute(); } return true; } diff --git a/media/android/NewsBlur/src/com/newsblur/fragment/ProfileActivityFragment.java b/media/android/NewsBlur/src/com/newsblur/fragment/ProfileActivityFragment.java index 676edcebf..27c5fb7a4 100644 --- a/media/android/NewsBlur/src/com/newsblur/fragment/ProfileActivityFragment.java +++ b/media/android/NewsBlur/src/com/newsblur/fragment/ProfileActivityFragment.java @@ -1,5 +1,6 @@ package com.newsblur.fragment; +import android.content.Context; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; @@ -32,9 +33,9 @@ public class ProfileActivityFragment extends Fragment { return v; } - public void setActivitiesAndUser(final ActivitiesResponse[] activities, UserDetails user ) { + public void setActivitiesAndUser(Context context, final ActivitiesResponse[] activities, UserDetails user ) { // Set the activities, create the adapter - adapter = new ActivitiesAdapter(getActivity(), activities, user); + adapter = new ActivitiesAdapter(context, activities, user); displayActivities(); } diff --git a/media/android/NewsBlur/src/com/newsblur/fragment/ProfileDetailsFragment.java b/media/android/NewsBlur/src/com/newsblur/fragment/ProfileDetailsFragment.java index f908d1a2d..4309c7f6b 100644 --- a/media/android/NewsBlur/src/com/newsblur/fragment/ProfileDetailsFragment.java +++ b/media/android/NewsBlur/src/com/newsblur/fragment/ProfileDetailsFragment.java @@ -1,5 +1,6 @@ package com.newsblur.fragment; +import android.content.Context; import android.graphics.Bitmap; import android.os.AsyncTask; import android.os.Bundle; @@ -43,11 +44,11 @@ public class ProfileDetailsFragment extends Fragment implements OnClickListener apiManager = new APIManager(getActivity()); } - public void setUser(final UserDetails user, final boolean viewingSelf) { + public void setUser(Context context, final UserDetails user, final boolean viewingSelf) { this.user = user; this.viewingSelf = viewingSelf; if (username != null) { - setUserFields(); + setUserFields(context); } } @@ -69,13 +70,13 @@ public class ProfileDetailsFragment extends Fragment implements OnClickListener unfollowButton.setOnClickListener(this); if (user != null) { - setUserFields(); + setUserFields(getActivity()); } return v; } - private void setUserFields() { + private void setUserFields(Context context) { username.setText(user.username); if (!TextUtils.isEmpty(user.bio)) { @@ -114,9 +115,13 @@ public class ProfileDetailsFragment extends Fragment implements OnClickListener } } else { followButton.setVisibility(View.GONE); - Bitmap userPicture = PrefsUtils.getUserImage(getActivity()); - userPicture = UIUtils.roundCorners(userPicture, 5); - imageView.setImageBitmap(userPicture); + Bitmap userPicture = PrefsUtils.getUserImage(context); + // seems to sometimes be an error loading the picture so prevent + // force close if null returned + if (userPicture != null) { + userPicture = UIUtils.roundCorners(userPicture, 5); + imageView.setImageBitmap(userPicture); + } } } diff --git a/media/android/NewsBlur/src/com/newsblur/network/APIConstants.java b/media/android/NewsBlur/src/com/newsblur/network/APIConstants.java index e39d1d048..f83aa4543 100644 --- a/media/android/NewsBlur/src/com/newsblur/network/APIConstants.java +++ b/media/android/NewsBlur/src/com/newsblur/network/APIConstants.java @@ -22,6 +22,7 @@ public class APIConstants { public static final String URL_SIGNUP = "http://newsblur.com/api/signup"; public static final String URL_FEED_COUNTS = "http://newsblur.com/reader/refresh_feeds/"; public static final String URL_MARK_FEED_AS_READ = "http://newsblur.com/reader/mark_feed_as_read/"; + public static final String URL_MARK_ALL_AS_READ = "http://newsblur.com/reader/mark_all_as_read/"; public static final String URL_MARK_STORY_AS_READ = "http://newsblur.com/reader/mark_story_as_read/"; public static final String URL_MARK_FEED_STORIES_AS_READ = "http://newsblur.com/reader/mark_feed_stories_as_read/"; public static final String URL_MARK_SOCIALSTORY_AS_READ = "http://newsblur.com/reader/mark_social_stories_as_read/"; @@ -58,6 +59,7 @@ public class APIConstants { public static final String PARAMETER_SHARE_SOURCEID = "source_user_id"; public static final String PARAMETER_MARKSOCIAL_JSON = "users_feeds_stories"; public static final String PARAMETER_URL = "url"; + public static final String PARAMETER_DAYS = "days"; public static final String PARAMETER_PAGE_NUMBER = "page"; diff --git a/media/android/NewsBlur/src/com/newsblur/network/APIManager.java b/media/android/NewsBlur/src/com/newsblur/network/APIManager.java index e1942fd4a..4f04d1ec6 100644 --- a/media/android/NewsBlur/src/com/newsblur/network/APIManager.java +++ b/media/android/NewsBlur/src/com/newsblur/network/APIManager.java @@ -105,6 +105,18 @@ public class APIManager { return false; } } + + public boolean markAllAsRead() { + final APIClient client = new APIClient(context); + final ValueMultimap values = new ValueMultimap(); + values.put(APIConstants.PARAMETER_DAYS, "0"); + final APIResponse response = client.post(APIConstants.URL_MARK_ALL_AS_READ, values, false); + if (!response.isOffline && response.responseCode == HttpStatus.SC_OK && !response.hasRedirected) { + return true; + } else { + return false; + } + } public boolean markStoryAsRead(final String feedId, final ArrayList storyIds) { final APIClient client = new APIClient(context); @@ -661,6 +673,7 @@ public class APIManager { final APIResponse response = client.get(APIConstants.URL_FEED_AUTOCOMPLETE, values); if (response.responseCode == HttpStatus.SC_OK && !response.hasRedirected) { + // TODO doesn't handle auto complete not supporting premium users only causing force close ? return gson.fromJson(response.responseString, FeedResult[].class); } else { return null;