mirror of
https://github.com/samuelclay/NewsBlur.git
synced 2025-09-18 21:50:56 +00:00
commit
3eba1408f2
26 changed files with 209 additions and 231 deletions
|
@ -131,7 +131,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:layout_marginBottom="25dp"
|
||||
android:gravity="center_horizontal"
|
||||
style="?explainerText"
|
||||
android:visibility="invisible"
|
||||
|
|
|
@ -70,6 +70,7 @@ public abstract class ItemsList extends NbActivity implements StateChangedListen
|
|||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
if (NBSyncService.isHousekeepingRunning()) finish();
|
||||
updateStatusIndicators();
|
||||
// Reading activities almost certainly changed the read/unread state of some stories. Ensure
|
||||
// we reflect those changes promptly.
|
||||
|
@ -124,6 +125,9 @@ public abstract class ItemsList extends NbActivity implements StateChangedListen
|
|||
|
||||
@Override
|
||||
public void handleUpdate(int updateType) {
|
||||
if ((updateType & UPDATE_REBUILD) != 0) {
|
||||
finish();
|
||||
}
|
||||
if ((updateType & UPDATE_STATUS) != 0) {
|
||||
updateStatusIndicators();
|
||||
}
|
||||
|
|
|
@ -70,6 +70,11 @@ public class Main extends NbActivity implements StateChangedListener, SwipeRefre
|
|||
|
||||
getActionBar().hide();
|
||||
|
||||
// set the status bar to an generic loading message when the activity is first created so
|
||||
// that something is displayed while the service warms up
|
||||
overlayStatusText.setText(R.string.loading);
|
||||
overlayStatusText.setVisibility(View.VISIBLE);
|
||||
|
||||
swipeLayout = (SwipeRefreshLayout)findViewById(R.id.swipe_container);
|
||||
swipeLayout.setColorScheme(R.color.refresh_1, R.color.refresh_2, R.color.refresh_3, R.color.refresh_4);
|
||||
swipeLayout.setOnRefreshListener(this);
|
||||
|
@ -102,6 +107,7 @@ public class Main extends NbActivity implements StateChangedListener, SwipeRefre
|
|||
|
||||
updateStatusIndicators();
|
||||
folderFeedList.pushUnreadCounts();
|
||||
folderFeedList.checkOpenFolderPreferences();
|
||||
triggerSync();
|
||||
|
||||
if (PrefsUtils.isLightThemeSelected(this) != isLightTheme) {
|
||||
|
@ -116,6 +122,9 @@ public class Main extends NbActivity implements StateChangedListener, SwipeRefre
|
|||
|
||||
@Override
|
||||
public void handleUpdate(int updateType) {
|
||||
if ((updateType & UPDATE_REBUILD) != 0) {
|
||||
folderFeedList.reset();
|
||||
}
|
||||
if ((updateType & UPDATE_DB_READY) != 0) {
|
||||
try {
|
||||
folderFeedList.startLoaders();
|
||||
|
@ -138,8 +147,7 @@ public class Main extends NbActivity implements StateChangedListener, SwipeRefre
|
|||
if ((neutCount+posiCount) <= 0) {
|
||||
if (NBSyncService.isFeedCountSyncRunning() || (!folderFeedList.firstCursorSeenYet)) {
|
||||
emptyViewImage.setVisibility(View.INVISIBLE);
|
||||
emptyViewText.setText(R.string.loading);
|
||||
emptyViewText.setVisibility(View.VISIBLE);
|
||||
emptyViewText.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
emptyViewImage.setVisibility(View.VISIBLE);
|
||||
if (folderFeedList.currentState == StateFilter.BEST) {
|
||||
|
|
|
@ -25,6 +25,7 @@ public class NbActivity extends Activity {
|
|||
public static final int UPDATE_SOCIAL = (1<<3);
|
||||
public static final int UPDATE_STATUS = (1<<5);
|
||||
public static final int UPDATE_TEXT = (1<<6);
|
||||
public static final int UPDATE_REBUILD = (1<<7);
|
||||
|
||||
private final static String UNIQUE_LOGIN_KEY = "uniqueLoginKey";
|
||||
private String uniqueLoginKey;
|
||||
|
|
|
@ -70,7 +70,6 @@ public abstract class Reading extends NbActivity implements OnPageChangeListener
|
|||
/** The minimum screen width (in DP) needed to show all the overlay controls. */
|
||||
private static final int OVERLAY_MIN_WIDTH_DP = 355;
|
||||
|
||||
protected int passedPosition;
|
||||
protected StateFilter currentState;
|
||||
protected StoryOrder storyOrder;
|
||||
protected ReadFilter readFilter;
|
||||
|
@ -78,8 +77,6 @@ public abstract class Reading extends NbActivity implements OnPageChangeListener
|
|||
// Activities navigate to a particular story by hash.
|
||||
// We can find it once we have the cursor.
|
||||
private String storyHash;
|
||||
private boolean storyHashSearchActive = false;
|
||||
private boolean storyHashSearchStarted = false;
|
||||
|
||||
protected final Object STORIES_MUTEX = new Object();
|
||||
protected Cursor stories;
|
||||
|
@ -127,11 +124,6 @@ public abstract class Reading extends NbActivity implements OnPageChangeListener
|
|||
|
||||
fs = (FeedSet)getIntent().getSerializableExtra(EXTRA_FEEDSET);
|
||||
|
||||
if ((savedInstanceBundle != null) && savedInstanceBundle.containsKey(BUNDLE_POSITION)) {
|
||||
passedPosition = savedInstanceBundle.getInt(BUNDLE_POSITION);
|
||||
} else {
|
||||
passedPosition = getIntent().getIntExtra(EXTRA_POSITION, 0);
|
||||
}
|
||||
if ((savedInstanceBundle != null) && savedInstanceBundle.containsKey(BUNDLE_STARTING_UNREAD)) {
|
||||
startingUnreadCount = savedInstanceBundle.getInt(BUNDLE_STARTING_UNREAD);
|
||||
}
|
||||
|
@ -140,7 +132,8 @@ public abstract class Reading extends NbActivity implements OnPageChangeListener
|
|||
// recreated due to rotation etc.
|
||||
if (savedInstanceBundle == null) {
|
||||
storyHash = getIntent().getStringExtra(EXTRA_STORY_HASH);
|
||||
storyHashSearchActive = storyHash != null;
|
||||
} else {
|
||||
storyHash = savedInstanceBundle.getString(EXTRA_STORY_HASH);
|
||||
}
|
||||
|
||||
currentState = (StateFilter) getIntent().getSerializableExtra(ItemsList.EXTRA_STATE);
|
||||
|
@ -176,7 +169,9 @@ public abstract class Reading extends NbActivity implements OnPageChangeListener
|
|||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
if (pager != null) {
|
||||
outState.putInt(BUNDLE_POSITION, pager.getCurrentItem());
|
||||
int currentItem = pager.getCurrentItem();
|
||||
Story story = readingAdapter.getStory(currentItem);
|
||||
outState.putString(EXTRA_STORY_HASH, story.storyHash);
|
||||
}
|
||||
|
||||
if (startingUnreadCount != 0) {
|
||||
|
@ -196,6 +191,7 @@ public abstract class Reading extends NbActivity implements OnPageChangeListener
|
|||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
if (NBSyncService.isHousekeepingRunning()) finish();
|
||||
// this view shows stories, it is not safe to perform cleanup
|
||||
this.stopLoading = false;
|
||||
// onCreate() in our subclass should have called createLoader(), but sometimes the callback never makes it.
|
||||
|
@ -232,6 +228,9 @@ public abstract class Reading extends NbActivity implements OnPageChangeListener
|
|||
setupPager();
|
||||
}
|
||||
|
||||
// see if we are just starting and need to jump to a target story
|
||||
skipPagerToStoryHash();
|
||||
|
||||
try {
|
||||
readingAdapter.notifyDataSetChanged();
|
||||
} catch (IllegalStateException ise) {
|
||||
|
@ -244,18 +243,37 @@ public abstract class Reading extends NbActivity implements OnPageChangeListener
|
|||
// now that we have more stories, look again.
|
||||
nextUnread();
|
||||
}
|
||||
|
||||
if (storyHashSearchActive) {
|
||||
findStoryByHash();
|
||||
}
|
||||
checkStoryCount(pager.getCurrentItem());
|
||||
updateOverlayNav();
|
||||
updateOverlayText();
|
||||
}
|
||||
}
|
||||
|
||||
private void skipPagerToStoryHash() {
|
||||
// if we already started and found our target story, this will be unset
|
||||
if (storyHash == null) return;
|
||||
stories.moveToPosition(-1);
|
||||
while (stories.moveToNext()) {
|
||||
if (stopLoading) return;
|
||||
Story story = Story.fromCursor(stories);
|
||||
if (story.storyHash.equals(storyHash)) {
|
||||
// now that the pager is getting the right story, make it visible
|
||||
pager.setVisibility(View.VISIBLE);
|
||||
pager.setCurrentItem(stories.getPosition(), false);
|
||||
this.onPageSelected(stories.getPosition());
|
||||
storyHash = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// if the story wasn't found, try to get more stories into the cursor
|
||||
FeedUtils.activateAllStories();
|
||||
this.checkStoryCount(readingAdapter.getCount()+1);
|
||||
}
|
||||
|
||||
private void setupPager() {
|
||||
pager = (ViewPager) findViewById(R.id.reading_pager);
|
||||
// since it might start on the wrong story, create the pager as invisible
|
||||
pager.setVisibility(View.INVISIBLE);
|
||||
pager.setPageMargin(UIUtils.dp2px(getApplicationContext(), 1));
|
||||
if (PrefsUtils.isLightThemeSelected(this)) {
|
||||
pager.setPageMarginDrawable(R.drawable.divider_light);
|
||||
|
@ -266,10 +284,11 @@ public abstract class Reading extends NbActivity implements OnPageChangeListener
|
|||
pager.setOnPageChangeListener(this);
|
||||
pager.setAdapter(readingAdapter);
|
||||
|
||||
pager.setCurrentItem(passedPosition, false);
|
||||
// setCurrentItem sometimes fails to pass the first page to the callback, so call it manually
|
||||
// for the first one.
|
||||
this.onPageSelected(passedPosition);
|
||||
// if the first story in the list was "viewed" before the page change listener was set,
|
||||
// the calback was probably missed
|
||||
if (storyHash == null) {
|
||||
this.onPageSelected(pager.getCurrentItem());
|
||||
}
|
||||
|
||||
updateOverlayNav();
|
||||
enableOverlays();
|
||||
|
@ -349,6 +368,9 @@ public abstract class Reading extends NbActivity implements OnPageChangeListener
|
|||
|
||||
@Override
|
||||
protected void handleUpdate(int updateType) {
|
||||
if ((updateType & UPDATE_REBUILD) != 0) {
|
||||
finish();
|
||||
}
|
||||
if ((updateType & UPDATE_STATUS) != 0) {
|
||||
enableMainProgress(NBSyncService.isFeedSetSyncing(this.fs, this));
|
||||
}
|
||||
|
@ -638,15 +660,45 @@ public abstract class Reading extends NbActivity implements OnPageChangeListener
|
|||
// let either finish. search will happen when the cursor is pushed.
|
||||
if ((pager == null) || (readingAdapter == null)) return;
|
||||
|
||||
boolean unreadFound = searchForStory(new UnreadStorySearchMatcher());
|
||||
|
||||
if (this.stopLoading) {
|
||||
// this activity was ended before we finished. just stop.
|
||||
unreadSearchActive = false;
|
||||
return;
|
||||
boolean unreadFound = false;
|
||||
// start searching just after the current story
|
||||
int candidate = pager.getCurrentItem() + 1;
|
||||
unreadSearch:while (!unreadFound) {
|
||||
// if we've reached the end of the list, loop back to the beginning
|
||||
if (candidate >= readingAdapter.getCount()) {
|
||||
candidate = 0;
|
||||
}
|
||||
// if we have looped all the way around to the story we are on, there aren't any left
|
||||
if (candidate == pager.getCurrentItem()) {
|
||||
break unreadSearch;
|
||||
}
|
||||
Story story = readingAdapter.getStory(candidate);
|
||||
if (this.stopLoading) {
|
||||
// this activity was ended before we finished. just stop.
|
||||
unreadSearchActive = false;
|
||||
return;
|
||||
}
|
||||
// iterate through the stories in our cursor until we find an unread one
|
||||
if (story != null) {
|
||||
if (story.read) {
|
||||
candidate++;
|
||||
continue unreadSearch;
|
||||
} else {
|
||||
unreadFound = true;
|
||||
}
|
||||
}
|
||||
// if we didn't continue or break, the cursor probably changed out from under us, so stop.
|
||||
break unreadSearch;
|
||||
}
|
||||
|
||||
if (unreadFound) {
|
||||
// jump to the story we found
|
||||
final int page = candidate;
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
pager.setCurrentItem(page, true);
|
||||
}
|
||||
});
|
||||
// disable the search flag, as we are done
|
||||
unreadSearchActive = false;
|
||||
} else {
|
||||
|
@ -663,87 +715,6 @@ public abstract class Reading extends NbActivity implements OnPageChangeListener
|
|||
}
|
||||
}
|
||||
|
||||
private boolean searchForStory(StorySearchMatcher matcher) {
|
||||
boolean storyFound = false;
|
||||
// start searching just after the current story
|
||||
int candidate = pager.getCurrentItem() + 1;
|
||||
storySearch:while (!storyFound) {
|
||||
// if we've reached the end of the list, loop back to the beginning
|
||||
if (candidate >= readingAdapter.getCount()) {
|
||||
candidate = 0;
|
||||
}
|
||||
// if we have looped all the way around to the story we are on, there aren't any left
|
||||
if (candidate == pager.getCurrentItem()) {
|
||||
break storySearch;
|
||||
}
|
||||
Story story = readingAdapter.getStory(candidate);
|
||||
if (this.stopLoading) {
|
||||
// this activity was ended before we finished. just stop.
|
||||
return false;
|
||||
}
|
||||
// iterate through the stories in our cursor until we find one that matches
|
||||
if (story != null) {
|
||||
if (matcher.matches(story)) {
|
||||
storyFound = true;
|
||||
} else {
|
||||
candidate++;
|
||||
continue storySearch;
|
||||
}
|
||||
}
|
||||
// if we didn't continue or break, the cursor probably changed out from under us, so stop.
|
||||
break storySearch;
|
||||
}
|
||||
|
||||
if (storyFound) {
|
||||
// jump to the story we found
|
||||
final int page = candidate;
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
pager.setCurrentItem(page, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return storyFound;
|
||||
}
|
||||
|
||||
private void findStoryByHash() {
|
||||
// the first time an story hash search is triggered, also trigger an activation of unreads, so
|
||||
// we don't search for a story that doesn't exist in the cursor
|
||||
if (!storyHashSearchStarted) {
|
||||
FeedUtils.activateAllStories();
|
||||
storyHashSearchStarted = true;
|
||||
}
|
||||
|
||||
// if we somehow got tapped before construction or are running during destruction, stop and
|
||||
// let either finish. search will happen when the cursor is pushed.
|
||||
if ((pager == null) || (readingAdapter == null)) return;
|
||||
|
||||
boolean storyFound = searchForStory(new StoryHashSearchMatcher(storyHash));
|
||||
|
||||
if (this.stopLoading) {
|
||||
// this activity was ended before we finished. just stop.
|
||||
storyHashSearchActive = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (storyFound) {
|
||||
// disable the search flag, as we are done
|
||||
storyHashSearchActive = false;
|
||||
} else {
|
||||
// We didn't find a story, so we should trigger a check to see if the API can load any more.
|
||||
// First, though, double check that there are even any left, as there may have been a delay
|
||||
// between marking an earlier one and double-checking counts.
|
||||
if (getUnreadCount() <= 0) {
|
||||
storyHashSearchActive = false;
|
||||
} else {
|
||||
// trigger a check to see if there are any more to search before proceeding. By leaving the
|
||||
// unreadSearchActive flag high, this method will be called again when a new cursor is loaded
|
||||
this.checkStoryCount(readingAdapter.getCount()+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Click handler for the lefthand overlay nav button.
|
||||
*/
|
||||
|
@ -853,29 +824,4 @@ public abstract class Reading extends NbActivity implements OnPageChangeListener
|
|||
return super.onKeyUp(keyCode, event);
|
||||
}
|
||||
}
|
||||
|
||||
private interface StorySearchMatcher {
|
||||
boolean matches(Story story);
|
||||
}
|
||||
|
||||
private class UnreadStorySearchMatcher implements StorySearchMatcher {
|
||||
|
||||
@Override
|
||||
public boolean matches(Story story) {
|
||||
return !story.read;
|
||||
}
|
||||
}
|
||||
|
||||
private class StoryHashSearchMatcher implements StorySearchMatcher {
|
||||
private String hash;
|
||||
|
||||
public StoryHashSearchMatcher(String hash) {
|
||||
this.hash = hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Story story) {
|
||||
return this.hash.equals(story.storyHash);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,6 +59,9 @@ public abstract class ReadingAdapter extends FragmentStatePagerAdapter {
|
|||
|
||||
public synchronized void swapCursor(Cursor cursor) {
|
||||
this.stories = cursor;
|
||||
if (cursor != null) {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract ReadingItemFragment getReadingItemFragment(Story story);
|
||||
|
|
|
@ -35,7 +35,7 @@ public class SocialFeedReading extends Reading {
|
|||
// If we have navigated from the profile we want to ignore the StateFilter and ReadFilter settings
|
||||
// for the feed to ensure we can find the story.
|
||||
if (openedFromProfile) {
|
||||
return FeedUtils.dbHelper.getAllStoriesLoader(fs);
|
||||
return FeedUtils.dbHelper.getStoriesLoaderIgnoreFilters(fs);
|
||||
} else {
|
||||
return super.onCreateLoader(loaderId, bundle);
|
||||
}
|
||||
|
|
|
@ -867,7 +867,7 @@ public class BlurDatabaseHelper {
|
|||
* When navigating to a social story from an interaction/activity we want to ignore
|
||||
* the any state so we can be sure we find the selected story.
|
||||
*/
|
||||
public Loader<Cursor> getAllStoriesLoader(final FeedSet fs) {
|
||||
public Loader<Cursor> getStoriesLoaderIgnoreFilters(final FeedSet fs) {
|
||||
return new QueryCursorLoader(context) {
|
||||
protected Cursor createCursor() {return getStoriesCursor(fs, StateFilter.ALL, ReadFilter.ALL, cancellationSignal);}
|
||||
};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.newsblur.database;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
|
@ -258,7 +259,8 @@ public class FolderListAdapter extends BaseExpandableListAdapter {
|
|||
// in addition to the real folders returned by the /reader/feeds API, there are virtual folders
|
||||
// for global shared stories, social feeds and saved stories
|
||||
if (activeFolderNames == null) return 0;
|
||||
return (activeFolderNames.size() + 4);
|
||||
// two types of group (folder and All Stories are represented as folders, and don't count, so -2)
|
||||
return (activeFolderNames.size() + (GroupType.values().length - 2));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -505,6 +507,30 @@ public class FolderListAdapter extends BaseExpandableListAdapter {
|
|||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public synchronized void reset() {
|
||||
socialFeeds = Collections.emptyMap();
|
||||
socialFeedsOrdered = Collections.emptyList();
|
||||
totalSocialNeutCount = 0;
|
||||
totalSocialPosiCount = 0;
|
||||
|
||||
folders = Collections.emptyMap();
|
||||
flatFolders = Collections.emptyMap();
|
||||
safeClear(activeFolderNames);
|
||||
safeClear(activeFolderChildren);
|
||||
safeClear(folderNeutCounts);
|
||||
safeClear(folderPosCounts);
|
||||
|
||||
feeds = Collections.emptyMap();
|
||||
safeClear(feedNeutCounts);
|
||||
safeClear(feedPosCounts);
|
||||
totalNeutCount = 0;
|
||||
totalPosCount = 0;
|
||||
|
||||
safeClear(closedFolders);
|
||||
|
||||
savedStoriesCount = 0;
|
||||
}
|
||||
|
||||
public Feed getFeed(String feedId) {
|
||||
return feeds.get(feedId);
|
||||
}
|
||||
|
@ -649,4 +675,12 @@ public class FolderListAdapter extends BaseExpandableListAdapter {
|
|||
}
|
||||
};
|
||||
|
||||
public void safeClear(Collection c) {
|
||||
if (c != null) c.clear();
|
||||
}
|
||||
|
||||
public void safeClear(Map m) {
|
||||
if (m != null) m.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.database.Cursor;
|
|||
import android.text.TextUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import com.newsblur.database.DatabaseConstants;
|
||||
|
@ -64,6 +65,10 @@ public class Folder {
|
|||
builder.append(name);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public void removeOrphanFeedIds(Collection<String> orphanFeedIds) {
|
||||
feedIds.removeAll(orphanFeedIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object otherFolder) {
|
||||
|
|
|
@ -8,8 +8,6 @@ import java.util.Map;
|
|||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.squareup.okhttp.FormEncodingBuilder;
|
||||
import com.squareup.okhttp.RequestBody;
|
||||
|
||||
|
@ -49,23 +47,6 @@ public class ValueMultimap implements Serializable {
|
|||
return TextUtils.join("&", parameters);
|
||||
}
|
||||
|
||||
public String getJsonString() {
|
||||
ArrayList<String> parameters = new ArrayList<String>();
|
||||
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
|
||||
for (String key : multimap.keySet()) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("\"" + key + "\"");
|
||||
builder.append(": ");
|
||||
builder.append(gson.toJson(multimap.get(key)));
|
||||
parameters.add(builder.toString());
|
||||
}
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append("{");
|
||||
builder.append(TextUtils.join(",", parameters));
|
||||
builder.append("}");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public RequestBody asFormEncodedRequestBody() {
|
||||
FormEncodingBuilder formEncodingBuilder = new FormEncodingBuilder();
|
||||
for (String key : multimap.keySet()) {
|
||||
|
|
|
@ -5,7 +5,6 @@ import android.content.Loader;
|
|||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
|
||||
import com.newsblur.R;
|
||||
import com.newsblur.activity.AllSharedStoriesReading;
|
||||
|
@ -44,11 +43,10 @@ public class AllSharedStoriesItemListFragment extends ItemListFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick_(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (getActivity().isFinishing()) return;
|
||||
public void onItemClick_(String storyHash) {
|
||||
Intent i = new Intent(getActivity(), AllSharedStoriesReading.class);
|
||||
i.putExtra(Reading.EXTRA_STORY_HASH, storyHash);
|
||||
i.putExtra(Reading.EXTRA_FEEDSET, getFeedSet());
|
||||
i.putExtra(FeedReading.EXTRA_POSITION, position);
|
||||
i.putExtra(ItemsList.EXTRA_STATE, currentState);
|
||||
i.putExtra(Reading.EXTRA_DEFAULT_FEED_VIEW, defaultFeedView);
|
||||
startActivity(i);
|
||||
|
|
|
@ -5,7 +5,6 @@ import android.database.Cursor;
|
|||
import android.os.Bundle;
|
||||
import android.content.Loader;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
|
||||
import com.newsblur.R;
|
||||
import com.newsblur.activity.AllStoriesReading;
|
||||
|
@ -44,11 +43,10 @@ public class AllStoriesItemListFragment extends ItemListFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick_(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (getActivity().isFinishing()) return;
|
||||
public void onItemClick_(String storyHash) {
|
||||
Intent i = new Intent(getActivity(), AllStoriesReading.class);
|
||||
i.putExtra(Reading.EXTRA_STORY_HASH, storyHash);
|
||||
i.putExtra(Reading.EXTRA_FEEDSET, getFeedSet());
|
||||
i.putExtra(FeedReading.EXTRA_POSITION, position);
|
||||
i.putExtra(ItemsList.EXTRA_STATE, currentState);
|
||||
i.putExtra(Reading.EXTRA_DEFAULT_FEED_VIEW, defaultFeedView);
|
||||
startActivity(i);
|
||||
|
|
|
@ -5,7 +5,6 @@ import android.database.Cursor;
|
|||
import android.os.Bundle;
|
||||
import android.content.Loader;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
|
||||
import com.newsblur.R;
|
||||
import com.newsblur.activity.FeedReading;
|
||||
|
@ -55,12 +54,11 @@ public class FeedItemListFragment extends ItemListFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick_(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (getActivity().isFinishing()) return;
|
||||
public void onItemClick_(String storyHash) {
|
||||
Intent i = new Intent(getActivity(), FeedReading.class);
|
||||
i.putExtra(Reading.EXTRA_STORY_HASH, storyHash);
|
||||
i.putExtra(Reading.EXTRA_FEEDSET, getFeedSet());
|
||||
i.putExtra(Reading.EXTRA_FEED, feed);
|
||||
i.putExtra(FeedReading.EXTRA_POSITION, position);
|
||||
i.putExtra(ItemsList.EXTRA_STATE, currentState);
|
||||
i.putExtra(Reading.EXTRA_DEFAULT_FEED_VIEW, defaultFeedView);
|
||||
startActivity(i);
|
||||
|
|
|
@ -5,7 +5,6 @@ import android.database.Cursor;
|
|||
import android.os.Bundle;
|
||||
import android.content.Loader;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
|
||||
import com.newsblur.R;
|
||||
import com.newsblur.activity.FeedReading;
|
||||
|
@ -54,11 +53,10 @@ public class FolderItemListFragment extends ItemListFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick_(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (getActivity().isFinishing()) return;
|
||||
public void onItemClick_(String storyHash) {
|
||||
Intent i = new Intent(getActivity(), FolderReading.class);
|
||||
i.putExtra(Reading.EXTRA_STORY_HASH, storyHash);
|
||||
i.putExtra(Reading.EXTRA_FEEDSET, getFeedSet());
|
||||
i.putExtra(FeedReading.EXTRA_POSITION, position);
|
||||
i.putExtra(FeedReading.EXTRA_FOLDERNAME, folderName);
|
||||
i.putExtra(ItemsList.EXTRA_STATE, currentState);
|
||||
i.putExtra(Reading.EXTRA_DEFAULT_FEED_VIEW, defaultFeedView);
|
||||
|
|
|
@ -57,7 +57,6 @@ public class FolderListFragment extends NbFragment implements OnCreateContextMen
|
|||
public StateFilter currentState = StateFilter.SOME;
|
||||
private SharedPreferences sharedPreferences;
|
||||
@FindView(R.id.folderfeed_list) ExpandableListView list;
|
||||
private Main activity;
|
||||
public boolean firstCursorSeenYet = false;
|
||||
|
||||
@Override
|
||||
|
@ -73,7 +72,6 @@ public class FolderListFragment extends NbFragment implements OnCreateContextMen
|
|||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
sharedPreferences = getActivity().getSharedPreferences(PrefConstants.PREFERENCES, 0);
|
||||
activity = (Main) getActivity();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -154,6 +152,10 @@ public class FolderListFragment extends NbFragment implements OnCreateContextMen
|
|||
}
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
if (adapter != null) adapter.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.fragment_folderfeedlist, container);
|
||||
|
@ -181,7 +183,7 @@ public class FolderListFragment extends NbFragment implements OnCreateContextMen
|
|||
* database. The list widget likes to default all folders to closed, so open them up
|
||||
* unless expressly collapsed at some point.
|
||||
*/
|
||||
private void checkOpenFolderPreferences() {
|
||||
public void checkOpenFolderPreferences() {
|
||||
// make sure we didn't beat construction
|
||||
if ((this.list == null) || (this.sharedPreferences == null)) return;
|
||||
|
||||
|
@ -275,7 +277,7 @@ public class FolderListFragment extends NbFragment implements OnCreateContextMen
|
|||
* DB model, so having Main also load it would cause some lag.
|
||||
*/
|
||||
public void pushUnreadCounts() {
|
||||
activity.updateUnreadCounts((adapter.totalNeutCount+adapter.totalSocialNeutCount), (adapter.totalPosCount+adapter.totalSocialPosiCount));
|
||||
((Main) getActivity()).updateUnreadCounts((adapter.totalNeutCount+adapter.totalSocialNeutCount), (adapter.totalPosCount+adapter.totalSocialPosiCount));
|
||||
}
|
||||
|
||||
@OnGroupClick(R.id.folderfeed_list) boolean onGroupClick(ExpandableListView list, View group, int groupPosition, long id) {
|
||||
|
|
|
@ -7,7 +7,6 @@ import android.os.Bundle;
|
|||
import android.view.ContextMenu;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
|
||||
import com.newsblur.R;
|
||||
import com.newsblur.activity.FeedReading;
|
||||
|
@ -44,11 +43,10 @@ public class GlobalSharedStoriesItemListFragment extends ItemListFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick_(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (getActivity().isFinishing()) return;
|
||||
public void onItemClick_(String storyHash) {
|
||||
Intent i = new Intent(getActivity(), GlobalSharedStoriesReading.class);
|
||||
i.putExtra(Reading.EXTRA_STORY_HASH, storyHash);
|
||||
i.putExtra(Reading.EXTRA_FEEDSET, getFeedSet());
|
||||
i.putExtra(FeedReading.EXTRA_POSITION, position);
|
||||
i.putExtra(Reading.EXTRA_DEFAULT_FEED_VIEW, defaultFeedView);
|
||||
i.putExtra(ItemsList.EXTRA_STATE, currentState);
|
||||
startActivity(i);
|
||||
|
|
|
@ -316,12 +316,14 @@ public abstract class ItemListFragment extends NbFragment implements OnScrollLis
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
public synchronized void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
int truePosition = position - 1;
|
||||
onItemClick_(parent, view, truePosition, id);
|
||||
Story story = adapter.getStory(truePosition);
|
||||
if (getActivity().isFinishing()) return;
|
||||
onItemClick_(story.storyHash);
|
||||
}
|
||||
|
||||
public abstract void onItemClick_(AdapterView<?> parent, View view, int position, long id);
|
||||
public abstract void onItemClick_(String storyHash);
|
||||
|
||||
protected void setupBezelSwipeDetector(View v) {
|
||||
final GestureDetector gestureDetector = new GestureDetector(getActivity(), new BezelSwipeDetector());
|
||||
|
|
|
@ -8,7 +8,6 @@ import android.os.Bundle;
|
|||
import android.view.ContextMenu;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
|
||||
import com.newsblur.R;
|
||||
import com.newsblur.activity.Reading;
|
||||
|
@ -48,11 +47,10 @@ public class ReadStoriesItemListFragment extends ItemListFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick_(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (getActivity().isFinishing()) return;
|
||||
public void onItemClick_(String storyHash) {
|
||||
Intent i = new Intent(getActivity(), ReadStoriesReading.class);
|
||||
i.putExtra(Reading.EXTRA_STORY_HASH, storyHash);
|
||||
i.putExtra(Reading.EXTRA_FEEDSET, getFeedSet());
|
||||
i.putExtra(FeedReading.EXTRA_POSITION, position);
|
||||
i.putExtra(Reading.EXTRA_DEFAULT_FEED_VIEW, defaultFeedView);
|
||||
startActivity(i);
|
||||
}
|
||||
|
|
|
@ -532,9 +532,7 @@ public class ReadingItemFragment extends NbFragment implements ClassifierDialogF
|
|||
|
||||
sniffAltTexts(storyText);
|
||||
|
||||
if (PrefsUtils.isImagePrefetchEnabled(getActivity())) {
|
||||
storyText = swapInOfflineImages(storyText);
|
||||
}
|
||||
storyText = swapInOfflineImages(storyText);
|
||||
|
||||
float currentSize = PrefsUtils.getTextSize(getActivity());
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ import android.os.Bundle;
|
|||
import android.view.ContextMenu;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
|
||||
import com.newsblur.R;
|
||||
import com.newsblur.activity.Reading;
|
||||
|
@ -48,11 +47,10 @@ public class SavedStoriesItemListFragment extends ItemListFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick_(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (getActivity().isFinishing()) return;
|
||||
public void onItemClick_(String storyHash) {
|
||||
Intent i = new Intent(getActivity(), SavedStoriesReading.class);
|
||||
i.putExtra(Reading.EXTRA_STORY_HASH, storyHash);
|
||||
i.putExtra(Reading.EXTRA_FEEDSET, getFeedSet());
|
||||
i.putExtra(FeedReading.EXTRA_POSITION, position);
|
||||
i.putExtra(Reading.EXTRA_DEFAULT_FEED_VIEW, defaultFeedView);
|
||||
startActivity(i);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import android.content.Loader;
|
|||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
|
||||
import com.newsblur.R;
|
||||
import com.newsblur.activity.ItemsList;
|
||||
|
@ -53,12 +52,11 @@ public class SocialFeedItemListFragment extends ItemListFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick_(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (getActivity().isFinishing()) return;
|
||||
public void onItemClick_(String storyHash) {
|
||||
Intent i = new Intent(getActivity(), SocialFeedReading.class);
|
||||
i.putExtra(Reading.EXTRA_STORY_HASH, storyHash);
|
||||
i.putExtra(Reading.EXTRA_FEEDSET, getFeedSet());
|
||||
i.putExtra(Reading.EXTRA_SOCIAL_FEED, socialFeed);
|
||||
i.putExtra(Reading.EXTRA_POSITION, position);
|
||||
i.putExtra(ItemsList.EXTRA_STATE, currentState);
|
||||
i.putExtra(Reading.EXTRA_DEFAULT_FEED_VIEW, defaultFeedView);
|
||||
startActivity(i);
|
||||
|
|
|
@ -615,9 +615,17 @@ public class APIManager {
|
|||
return new APIResponse(context);
|
||||
}
|
||||
|
||||
if (AppConstants.VERBOSE_LOG) {
|
||||
if (AppConstants.VERBOSE_LOG_NET) {
|
||||
Log.d(this.getClass().getName(), "API POST " + urlString);
|
||||
Log.d(this.getClass().getName(), "post body: " + formBody.toString());
|
||||
String body = "";
|
||||
try {
|
||||
okio.Buffer buffer = new okio.Buffer();
|
||||
formBody.writeTo(buffer);
|
||||
body = buffer.readUtf8();
|
||||
} catch (Exception e) {
|
||||
; // this is debug code, do not raise
|
||||
}
|
||||
Log.d(this.getClass().getName(), "post body: " + body);
|
||||
}
|
||||
|
||||
Request.Builder requestBuilder = new Request.Builder().url(urlString);
|
||||
|
|
|
@ -20,8 +20,6 @@ public class NewsBlurResponse {
|
|||
public String[] errors;
|
||||
public long readTime;
|
||||
|
||||
public static final Pattern KnownUserErrors = Pattern.compile("cannot mark as unread");
|
||||
|
||||
public boolean isError() {
|
||||
if (isProtocolError) return true;
|
||||
if ((message != null) && (!message.equals(""))) {
|
||||
|
@ -35,18 +33,6 @@ public class NewsBlurResponse {
|
|||
return false;
|
||||
}
|
||||
|
||||
// TODO: can we add a canonical flag of some sort to 100% of API responses that differentiates
|
||||
// between user and server errors? Until then, we have to sniff known bad ones, since all
|
||||
// user errors have a 200 response rather than a 4xx.
|
||||
public boolean isUserError() {
|
||||
String err = getErrorMessage(null);
|
||||
if (err != null) {
|
||||
Matcher m = KnownUserErrors.matcher(err);
|
||||
if (m.find()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the error message returned by the API, or defaultMessage if none was found.
|
||||
*/
|
||||
|
|
|
@ -270,7 +270,7 @@ public class NBSyncService extends Service {
|
|||
boolean upgraded = PrefsUtils.checkForUpgrade(this);
|
||||
if (upgraded) {
|
||||
HousekeepingRunning = true;
|
||||
NbActivity.updateAllActivities(NbActivity.UPDATE_STATUS);
|
||||
NbActivity.updateAllActivities(NbActivity.UPDATE_STATUS | NbActivity.UPDATE_REBUILD);
|
||||
// wipe the local DB
|
||||
dbHelper.dropAndRecreateTables();
|
||||
NbActivity.updateAllActivities(NbActivity.UPDATE_METADATA);
|
||||
|
@ -350,10 +350,8 @@ public class NBSyncService extends Service {
|
|||
}
|
||||
} finally {
|
||||
closeQuietly(c);
|
||||
if (ActionsRunning) {
|
||||
ActionsRunning = false;
|
||||
NbActivity.updateAllActivities(NbActivity.UPDATE_STATUS);
|
||||
}
|
||||
ActionsRunning = false;
|
||||
NbActivity.updateAllActivities(NbActivity.UPDATE_STATUS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -371,7 +369,6 @@ public class NBSyncService extends Service {
|
|||
if (PendingFeed == null) {
|
||||
FollowupActions.clear();
|
||||
}
|
||||
NbActivity.updateAllActivities(NbActivity.UPDATE_STATUS);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -393,8 +390,9 @@ public class NBSyncService extends Service {
|
|||
FFSyncRunning = true;
|
||||
NbActivity.updateAllActivities(NbActivity.UPDATE_STATUS);
|
||||
|
||||
// there is a rare issue with feeds that have no folder. capture them for workarounds.
|
||||
Set<String> debugFeedIds = new HashSet<String>();
|
||||
// there is an issue with feeds that have no folder or folders that list feeds that do not exist. capture them for workarounds.
|
||||
Set<String> debugFeedIdsFromFolders = new HashSet<String>();
|
||||
Set<String> debugFeedIdsFromFeeds = new HashSet<String>();
|
||||
orphanFeedIds = new HashSet<String>();
|
||||
|
||||
try {
|
||||
|
@ -430,21 +428,20 @@ public class NBSyncService extends Service {
|
|||
// clean out the feed / folder tables
|
||||
dbHelper.cleanupFeedsFolders();
|
||||
|
||||
// data for the folder and folder-feed-mapping tables
|
||||
List<ContentValues> folderValues = new ArrayList<ContentValues>();
|
||||
// note all feeds that belong to some folder so we can find orphans
|
||||
for (Folder folder : feedResponse.folders) {
|
||||
folderValues.add(folder.getValues());
|
||||
// note all feeds that belong to some folder
|
||||
debugFeedIds.addAll(folder.feedIds);
|
||||
debugFeedIdsFromFolders.addAll(folder.feedIds);
|
||||
}
|
||||
|
||||
// data for the feeds table
|
||||
List<ContentValues> feedValues = new ArrayList<ContentValues>();
|
||||
feedaddloop: for (Feed feed : feedResponse.feeds) {
|
||||
// note all feeds for which the API returned data
|
||||
debugFeedIdsFromFeeds.add(feed.feedId);
|
||||
// sanity-check that the returned feeds actually exist in a folder or at the root
|
||||
// if they do not, they should neither display nor count towards unread numbers
|
||||
if (! debugFeedIds.contains(feed.feedId)) {
|
||||
Log.w(this.getClass().getName(), "Found and ignoring un-foldered feed: " + feed.feedId );
|
||||
if (! debugFeedIdsFromFolders.contains(feed.feedId)) {
|
||||
Log.w(this.getClass().getName(), "Found and ignoring orphan feed (in feeds but not folders): " + feed.feedId );
|
||||
orphanFeedIds.add(feed.feedId);
|
||||
continue feedaddloop;
|
||||
}
|
||||
|
@ -454,7 +451,23 @@ public class NBSyncService extends Service {
|
|||
}
|
||||
feedValues.add(feed.getValues());
|
||||
}
|
||||
|
||||
// prune out missiong feed IDs from folders
|
||||
for (String id : debugFeedIdsFromFolders) {
|
||||
if (! debugFeedIdsFromFeeds.contains(id)) {
|
||||
Log.w(this.getClass().getName(), "Found and ignoring orphan feed (in folders but not feeds): " + id );
|
||||
orphanFeedIds.add(id);
|
||||
}
|
||||
}
|
||||
|
||||
// data for the folder table
|
||||
List<ContentValues> folderValues = new ArrayList<ContentValues>();
|
||||
for (Folder folder : feedResponse.folders) {
|
||||
// prune out orphans before pushing to the DB
|
||||
folder.removeOrphanFeedIds(orphanFeedIds);
|
||||
folderValues.add(folder.getValues());
|
||||
}
|
||||
|
||||
// data for the the social feeds table
|
||||
List<ContentValues> socialFeedValues = new ArrayList<ContentValues>();
|
||||
for (SocialFeed feed : feedResponse.socialFeeds) {
|
||||
|
@ -542,7 +555,7 @@ public class NBSyncService extends Service {
|
|||
} finally {
|
||||
if (RecountsRunning) {
|
||||
RecountsRunning = false;
|
||||
NbActivity.updateAllActivities(NbActivity.UPDATE_METADATA);
|
||||
NbActivity.updateAllActivities(NbActivity.UPDATE_METADATA | NbActivity.UPDATE_STATUS);
|
||||
}
|
||||
FlushRecounts = false;
|
||||
}
|
||||
|
@ -744,6 +757,10 @@ public class NBSyncService extends Service {
|
|||
return (HousekeepingRunning || RecountsRunning || FFSyncRunning);
|
||||
}
|
||||
|
||||
public static boolean isHousekeepingRunning() {
|
||||
return HousekeepingRunning;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is there a sync for a given FeedSet running?
|
||||
*/
|
||||
|
|
|
@ -40,8 +40,7 @@ public class NewsblurWebview extends WebView {
|
|||
getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
|
||||
getSettings().setDomStorageEnabled(true);
|
||||
getSettings().setSupportZoom(true);
|
||||
getSettings().setAppCacheMaxSize(1024*1024*8);
|
||||
getSettings().setAppCachePath("/data/data/com.newsblur/cache");
|
||||
getSettings().setAppCachePath(context.getCacheDir().getAbsolutePath());
|
||||
getSettings().setAllowFileAccess(true);
|
||||
getSettings().setAppCacheEnabled(true);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue