Merge pull request #117 from manderson23/master

Android App Updates
This commit is contained in:
Samuel Clay 2013-03-26 11:18:18 -07:00
commit 23e919abca
12 changed files with 142 additions and 24 deletions

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.newsblur"
android:versionCode="29"
android:versionName="1.0.55" >
android:versionCode="30"
android:versionName="1.0.6" >
<uses-sdk
android:minSdkVersion="8"

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/menu_mark_all_as_read"
android:title="@string/menu_mark_all_as_read"
android:showAsAction="never" />
</menu>

View file

@ -141,5 +141,6 @@
<string name="let_s_go_">Let&amp;apos;s go!</string>
<string name="public_comment_count">%d PUBLIC COMMENTS</string>
<string name="friends_comments_count">%d COMMENTS</string>
<string name="toast_marked_all_stories_as_read">All stories marked as read</string>
</resources>

View file

@ -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<String> 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<String>();
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<Void, Void, Boolean>() {
@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() {

View file

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

View file

@ -74,4 +74,7 @@ public class ValueMultimap implements Serializable {
return builder.toString();
}
public int size() {
return multimap.size();
}
}

View file

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

View file

@ -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<Void, Void, Boolean>() {
private List<String> feedIds = new ArrayList<String>();
@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;
}

View file

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

View file

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

View file

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

View file

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