mirror of
https://github.com/viq/NewsBlur.git
synced 2025-09-18 21:43:31 +00:00
commit
7fd714a994
4 changed files with 156 additions and 56 deletions
|
@ -78,6 +78,8 @@ 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;
|
||||
|
@ -138,6 +140,7 @@ 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;
|
||||
}
|
||||
|
||||
currentState = (StateFilter) getIntent().getSerializableExtra(ItemsList.EXTRA_STATE);
|
||||
|
@ -224,10 +227,6 @@ public abstract class Reading extends NbActivity implements OnPageChangeListener
|
|||
readingAdapter.swapCursor(cursor);
|
||||
stories = cursor;
|
||||
|
||||
if (storyHash != null) {
|
||||
skipCursorToStoryHash();
|
||||
}
|
||||
|
||||
// if this is the first time we've found a cursor, we know the onCreate chain is done
|
||||
if (this.pager == null) {
|
||||
setupPager();
|
||||
|
@ -245,23 +244,16 @@ 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 skipCursorToStoryHash() {
|
||||
passedPosition = 0;
|
||||
while (stories.moveToNext()) {
|
||||
Story story = Story.fromCursor(stories);
|
||||
if (story.storyHash.equals(storyHash)) {
|
||||
return;
|
||||
}
|
||||
passedPosition++;
|
||||
}
|
||||
}
|
||||
|
||||
private void setupPager() {
|
||||
pager = (ViewPager) findViewById(R.id.reading_pager);
|
||||
pager.setPageMargin(UIUtils.dp2px(getApplicationContext(), 1));
|
||||
|
@ -646,45 +638,15 @@ 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 = 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;
|
||||
boolean unreadFound = searchForStory(new UnreadStorySearchMatcher());
|
||||
|
||||
if (this.stopLoading) {
|
||||
// this activity was ended before we finished. just stop.
|
||||
unreadSearchActive = false;
|
||||
return;
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -701,6 +663,87 @@ 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.
|
||||
*/
|
||||
|
@ -810,4 +853,29 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,27 @@
|
|||
package com.newsblur.activity;
|
||||
|
||||
import android.content.Loader;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.newsblur.database.MixedFeedsReadingAdapter;
|
||||
import com.newsblur.domain.SocialFeed;
|
||||
import com.newsblur.util.FeedUtils;
|
||||
import com.newsblur.util.UIUtils;
|
||||
|
||||
public class SocialFeedReading extends Reading {
|
||||
|
||||
public static final String EXTRA_NAVIGATE_FROM_PROFILE = "navigate_from_profile";
|
||||
private SocialFeed socialFeed;
|
||||
|
||||
private boolean openedFromProfile;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceBundle) {
|
||||
super.onCreate(savedInstanceBundle);
|
||||
|
||||
socialFeed = (SocialFeed) getIntent().getSerializableExtra(EXTRA_SOCIAL_FEED);
|
||||
openedFromProfile = getIntent().hasExtra(EXTRA_NAVIGATE_FROM_PROFILE);
|
||||
|
||||
UIUtils.setCustomActionBar(this, socialFeed.photoUrl, socialFeed.feedTitle);
|
||||
|
||||
|
@ -23,4 +30,14 @@ public class SocialFeedReading extends Reading {
|
|||
getLoaderManager().initLoader(0, null, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(int loaderId, Bundle bundle) {
|
||||
// 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);
|
||||
} else {
|
||||
return super.onCreateLoader(loaderId, bundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -856,13 +856,25 @@ public class BlurDatabaseHelper {
|
|||
|
||||
public Loader<Cursor> getStoriesLoader(final FeedSet fs, final StateFilter stateFilter) {
|
||||
return new QueryCursorLoader(context) {
|
||||
protected Cursor createCursor() {return getStoriesCursor(fs, stateFilter, cancellationSignal);}
|
||||
protected Cursor createCursor() {
|
||||
ReadFilter readFilter = PrefsUtils.getReadFilter(context, fs);
|
||||
return getStoriesCursor(fs, stateFilter, readFilter, cancellationSignal);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Cursor getStoriesCursor(FeedSet fs, StateFilter stateFilter, CancellationSignal cancellationSignal) {
|
||||
/**
|
||||
* 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) {
|
||||
return new QueryCursorLoader(context) {
|
||||
protected Cursor createCursor() {return getStoriesCursor(fs, StateFilter.ALL, ReadFilter.ALL, cancellationSignal);}
|
||||
};
|
||||
}
|
||||
|
||||
private Cursor getStoriesCursor(FeedSet fs, StateFilter stateFilter, ReadFilter readFilter, CancellationSignal cancellationSignal) {
|
||||
if (fs == null) return null;
|
||||
ReadFilter readFilter = PrefsUtils.getReadFilter(context, fs);
|
||||
StoryOrder order = PrefsUtils.getStoryOrder(context, fs);
|
||||
return getStoriesCursor(fs, stateFilter, readFilter, order, cancellationSignal);
|
||||
}
|
||||
|
|
|
@ -156,7 +156,9 @@ public abstract class ProfileActivityDetailsFragment extends Fragment implements
|
|||
i.putExtra(Reading.EXTRA_DEFAULT_FEED_VIEW, PrefsUtils.getDefaultFeedViewForFolder(context, PrefConstants.SAVED_STORIES_FOLDER_NAME));
|
||||
context.startActivity(i);
|
||||
} else if (isSocialFeedCategory(activity)) {
|
||||
SocialFeed feed = FeedUtils.getSocialFeed(activity.withUserId);
|
||||
// Strip the social: prefix from feedId
|
||||
String socialFeedId = activity.feedId.substring(7);
|
||||
SocialFeed feed = FeedUtils.getSocialFeed(socialFeedId);
|
||||
if (feed == null) {
|
||||
Toast.makeText(context, R.string.profile_do_not_follow, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
|
@ -165,7 +167,8 @@ public abstract class ProfileActivityDetailsFragment extends Fragment implements
|
|||
i.putExtra(Reading.EXTRA_SOCIAL_FEED, feed);
|
||||
i.putExtra(ItemsList.EXTRA_STATE, PrefsUtils.getStateFilter(context));
|
||||
i.putExtra(Reading.EXTRA_STORY_HASH, activity.storyHash);
|
||||
i.putExtra(Reading.EXTRA_DEFAULT_FEED_VIEW, PrefsUtils.getDefaultFeedViewForFeed(context, activity.withUserId));
|
||||
i.putExtra(Reading.EXTRA_DEFAULT_FEED_VIEW, PrefsUtils.getDefaultFeedViewForFeed(context, socialFeedId));
|
||||
i.putExtra(SocialFeedReading.EXTRA_NAVIGATE_FROM_PROFILE, true);
|
||||
context.startActivity(i);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue