Feeds and folders are now linked to an account

This commit is contained in:
Shinokuni 2019-05-23 17:14:36 +02:00
parent 00f331a18f
commit 52219995bb
14 changed files with 101 additions and 47 deletions

View File

@ -23,6 +23,7 @@ import com.google.android.material.textfield.TextInputEditText;
import com.mikepenz.fastadapter.FastAdapter;
import com.mikepenz.fastadapter.adapters.ItemAdapter;
import com.readrops.app.R;
import com.readrops.app.database.entities.Account;
import com.readrops.app.database.entities.Feed;
import com.readrops.app.utils.FeedInsertionResult;
import com.readrops.app.utils.ParsingResult;
@ -232,7 +233,8 @@ public class AddFeedActivity extends AppCompatActivity implements View.OnClickLi
feedsToInsert.add(result);
}
viewModel.addFeeds(feedsToInsert)
// TODO : choose the right account
viewModel.addFeeds(feedsToInsert, new Account())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new DisposableSingleObserver<List<FeedInsertionResult>>() {

View File

@ -103,14 +103,23 @@ public class MainActivity extends AppCompatActivity implements SwipeRefreshLayou
toolbar.setTitleTextColor(Color.WHITE);
emptyListLayout = findViewById(R.id.empty_list_layout);
refreshLayout = findViewById(R.id.swipe_refresh_layout);
refreshLayout.setOnRefreshListener(this);
syncProgressLayout = findViewById(R.id.sync_progress_layout);
syncProgress = findViewById(R.id.sync_progress_text_view);
syncProgressBar = findViewById(R.id.sync_progress_bar);
actionMenu = findViewById(R.id.fab_menu);
feedCount = 0;
initRecyclerView();
viewModel = ViewModelProviders.of(this).get(MainViewModel.class);
viewModel.setShowReadItems(SharedPreferencesManager.readBoolean(this,
SharedPreferencesManager.SharedPrefKey.SHOW_READ_ARTICLES));
viewModel.invalidate();
viewModel.getItemsWithFeed().observe(this, itemWithFeeds -> {
allItems = itemWithFeeds;
@ -123,16 +132,6 @@ public class MainActivity extends AppCompatActivity implements SwipeRefreshLayou
adapter.submitList(itemWithFeeds);
});
refreshLayout = findViewById(R.id.swipe_refresh_layout);
refreshLayout.setOnRefreshListener(this);
syncProgressLayout = findViewById(R.id.sync_progress_layout);
syncProgress = findViewById(R.id.sync_progress_text_view);
syncProgressBar = findViewById(R.id.sync_progress_bar);
feedCount = 0;
initRecyclerView();
drawerManager = new DrawerManager(this, toolbar, (view, position, drawerItem) -> {
handleDrawerClick(drawerItem);
@ -177,10 +176,12 @@ public class MainActivity extends AppCompatActivity implements SwipeRefreshLayou
} else { // last current account
viewModel.getAllAccounts().observe(this, accounts -> {
viewModel.setAccounts(accounts);
if (viewModel.getCurrentAccount() == null) {
viewModel.setAccounts(accounts);
drawer = drawerManager.buildDrawer(accounts);
updateDrawerFeeds();
drawer = drawerManager.buildDrawer(accounts);
updateDrawerFeeds();
}
});
}
}

View File

@ -47,7 +47,7 @@ public abstract class Database extends RoomDatabase {
super.onCreate(db);
Folder folder = new Folder("reserved");
new Thread(() -> database.folderDao().insert(folder)).start();
//new Thread(() -> database.folderDao().insert(folder)).start();
}
@Override

View File

@ -10,9 +10,10 @@ public class ItemsListQueryBuilder {
private String [] columns = {"Item.id", "title", "clean_description", "image_link", "pub_date", "read",
"read_changed", "read_it_later", "Feed.name", "text_color", "background_color", "icon_url", "read_time",
"Feed.id as feedId", "Folder.id as folder_id", "Folder.name as folder_name"};
"Feed.id as feedId", "Feed.account_id", "Folder.id as folder_id", "Folder.name as folder_name"};
private String SELECT_ALL_JOIN = "Item Inner Join Feed, Folder on Item.feed_id = Feed.id And Folder.id = Feed.folder_id";
private String SELECT_ALL_JOIN = "Item Inner Join Feed, Folder on Item.feed_id = " +
"Feed.id And Folder.id = Feed.folder_id";
private String ORDER_BY_ASC = "Item.id DESC";
@ -20,8 +21,10 @@ public class ItemsListQueryBuilder {
private SupportSQLiteQueryBuilder queryBuilder;
private boolean showReaditems;
private boolean showReadItems;
private int filterFeedId;
private int accountId;
private MainViewModel.FilterType filterType;
private MainActivity.ListSortType sortType;
@ -30,9 +33,11 @@ public class ItemsListQueryBuilder {
}
private String buildWhereClause() {
StringBuilder stringBuilder = new StringBuilder(50);
StringBuilder stringBuilder = new StringBuilder(80);
if (!showReaditems)
stringBuilder.append("Feed.account_id = " + accountId + " And ");
if (!showReadItems)
stringBuilder.append("read = 0 And ");
switch (filterType) {
@ -68,12 +73,12 @@ public class ItemsListQueryBuilder {
return queryBuilder.create();
}
public boolean showReaditems() {
return showReaditems;
public boolean showReadItems() {
return showReadItems;
}
public void setShowReaditems(boolean showReaditems) {
this.showReaditems = showReaditems;
public void setShowReadItems(boolean showReadItems) {
this.showReadItems = showReadItems;
}
public int getFilterFeedId() {
@ -99,4 +104,12 @@ public class ItemsListQueryBuilder {
public void setSortType(MainActivity.ListSortType sortType) {
this.sortType = sortType;
}
public int getAccountId() {
return accountId;
}
public void setAccountId(int accountId) {
this.accountId = accountId;
}
}

View File

@ -16,8 +16,8 @@ public interface FolderDao {
@Query("Select * from Folder Order By name ASC")
LiveData<List<Folder>> getAllFolders();
@Query("Select * from Folder Order By name ASC")
List<Folder> getFolders();
@Query("Select * from Folder Where account_id = :accountId Order By name ASC")
List<Folder> getFolders(int accountId);
@Insert
long insert(Folder folder);

View File

@ -18,7 +18,10 @@ import com.readrops.readropslibrary.localfeed.rss.RSSFeed;
import org.jsoup.Jsoup;
@Entity(foreignKeys = @ForeignKey(entity = Folder.class, parentColumns = "id", childColumns = "folder_id", onDelete = ForeignKey.SET_NULL))
@Entity(foreignKeys = {@ForeignKey(entity = Folder.class, parentColumns = "id",
childColumns = "folder_id", onDelete = ForeignKey.SET_NULL),
@ForeignKey(entity = Account.class, parentColumns = "id", childColumns = "account_id",
onDelete = ForeignKey.CASCADE)})
public class Feed implements Parcelable {
@PrimaryKey(autoGenerate = true)
@ -53,6 +56,9 @@ public class Feed implements Parcelable {
private int remoteId;
@ColumnInfo(name = "account_id", index = true)
private int accountId;
@Ignore
private int unreadCount;
@ -207,6 +213,14 @@ public class Feed implements Parcelable {
this.remoteId = remoteId;
}
public int getAccountId() {
return accountId;
}
public void setAccountId(int accountId) {
this.accountId = accountId;
}
public static Feed feedFromRSS(RSSFeed rssFeed) {
Feed feed = new Feed();
RSSChannel channel = rssFeed.getChannel();

View File

@ -3,11 +3,14 @@ package com.readrops.app.database.entities;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.ForeignKey;
import androidx.room.Ignore;
import androidx.room.PrimaryKey;
@Entity
@Entity(foreignKeys = @ForeignKey(entity = Account.class, parentColumns = "id",
childColumns = "account_id", onDelete = ForeignKey.CASCADE))
public class Folder implements Parcelable, Comparable<Folder> {
@PrimaryKey(autoGenerate = true)
@ -17,6 +20,9 @@ public class Folder implements Parcelable, Comparable<Folder> {
private int remoteId;
@ColumnInfo(name = "account_id", index = true)
private int accountId;
public Folder() {
}
@ -57,6 +63,14 @@ public class Folder implements Parcelable, Comparable<Folder> {
this.remoteId = remoteId;
}
public int getAccountId() {
return accountId;
}
public void setAccountId(int accountId) {
this.accountId = accountId;
}
public static final Creator<Folder> CREATOR = new Creator<Folder>() {
@Override
public Folder createFromParcel(Parcel in) {

View File

@ -40,7 +40,7 @@ public abstract class ARepository {
public abstract Observable<Feed> sync(List<Feed> feeds, Account account);
public abstract Single<List<FeedInsertionResult>> addFeeds(List<ParsingResult> results);
public abstract Single<List<FeedInsertionResult>> addFeeds(List<ParsingResult> results, Account account);
public abstract void updateFeedWithFolder(FeedWithFolder feedWithFolder);

View File

@ -108,7 +108,7 @@ public class LocalFeedRepository extends ARepository {
}
@Override
public Single<List<FeedInsertionResult>> addFeeds(List<ParsingResult> results) {
public Single<List<FeedInsertionResult>> addFeeds(List<ParsingResult> results, Account account) {
return Single.create(emitter -> {
List<FeedInsertionResult> insertionResults = new ArrayList<>();
@ -120,7 +120,7 @@ public class LocalFeedRepository extends ARepository {
RSSQueryResult queryResult = rssNet.queryUrl(parsingResult.getUrl(), new HashMap<>());
if (queryResult != null && queryResult.getException() == null) {
Feed feed = insertFeed(queryResult.getFeed(), queryResult.getRssType());
Feed feed = insertFeed(queryResult.getFeed(), queryResult.getRssType(), account);
if (feed != null) {
insertionResult.setFeed(feed);
insertionResults.add(insertionResult);
@ -197,7 +197,7 @@ public class LocalFeedRepository extends ARepository {
insertItems(items, dbFeed);
}
private Feed insertFeed(AFeed feed, RSSQuery.RSSType type) throws IOException {
private Feed insertFeed(AFeed feed, RSSQuery.RSSType type, Account account) throws IOException {
Feed dbFeed = null;
switch (type) {
case RSS_2:
@ -215,6 +215,7 @@ public class LocalFeedRepository extends ARepository {
return null; // feed already inserted
setFavIconUtils(dbFeed);
dbFeed.setAccountId(account.getId());
// we need empty headers to query the feed just after, without any 304 result
dbFeed.setEtag(null);

View File

@ -89,10 +89,10 @@ public class NextNewsRepository extends ARepository {
if (!syncResult.isError()) {
TimingLogger timings = new TimingLogger(TAG, "sync");
insertFolders(syncResult.getFolders());
insertFolders(syncResult.getFolders(), account);
timings.addSplit("insert folders");
insertFeeds(syncResult.getFeeds());
insertFeeds(syncResult.getFeeds(), account);
timings.addSplit("insert feeds");
insertItems(syncResult.getItems(), syncType == NextNewsAPI.SyncType.INITIAL_SYNC);
@ -115,7 +115,7 @@ public class NextNewsRepository extends ARepository {
}
@Override
public Single<List<FeedInsertionResult>> addFeeds(List<ParsingResult> results) {
public Single<List<FeedInsertionResult>> addFeeds(List<ParsingResult> results, Account account) {
return null;
}
@ -134,13 +134,14 @@ public class NextNewsRepository extends ARepository {
return null;
}
private void insertFeeds(List<NextNewsFeed> feeds) {
private void insertFeeds(List<NextNewsFeed> feeds, Account account) {
List<Feed> newFeeds = new ArrayList<>();
for (NextNewsFeed nextNewsFeed : feeds) {
if (!database.feedDao().remoteFeedExists(nextNewsFeed.getId())) {
Feed feed = FeedMatcher.nextNewsFeedToFeed(nextNewsFeed);
Feed feed = FeedMatcher.nextNewsFeedToFeed(nextNewsFeed, account);
// if the Nextcloud feed has a folder, it is already inserted, so we have to get its local id
if (nextNewsFeed.getFolderId() != 0) {
@ -169,7 +170,7 @@ public class NextNewsRepository extends ARepository {
.subscribe();
}
private void insertFolders(List<NextNewsFolder> folders) {
private void insertFolders(List<NextNewsFolder> folders, Account account) {
List<Folder> newFolders = new ArrayList<>();
for (NextNewsFolder nextNewsFolder : folders) {
@ -177,6 +178,7 @@ public class NextNewsRepository extends ARepository {
if (!database.folderDao().remoteFolderExists(nextNewsFolder.getId())) {
Folder folder = new Folder(nextNewsFolder.getName());
folder.setRemoteId(nextNewsFolder.getId());
folder.setAccountId(account.getId());
newFolders.add(folder);
}

View File

@ -29,8 +29,8 @@ import static com.readrops.app.utils.Utils.drawableWithColor;
public class DrawerManager {
public static final int ARTICLES_ITEM_ID = -1;
public static final int READ_LATER_ID = -2;
public static final int ARTICLES_ITEM_ID = -5;
public static final int READ_LATER_ID = -6;
public static final int ACCOUNT_SETTINGS_ID = -3;
public static final int ADD_ACCOUNT_ID = -4;

View File

@ -1,11 +1,12 @@
package com.readrops.app.utils;
import com.readrops.app.database.entities.Account;
import com.readrops.app.database.entities.Feed;
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFeed;
public final class FeedMatcher {
public static Feed nextNewsFeedToFeed(NextNewsFeed feed) {
public static Feed nextNewsFeedToFeed(NextNewsFeed feed, Account account) {
Feed newFeed = new Feed();
newFeed.setName(feed.getTitle());
@ -17,6 +18,7 @@ public final class FeedMatcher {
newFeed.setIconUrl(feed.getFaviconLink());
newFeed.setRemoteId(feed.getId());
newFeed.setAccountId(account.getId());
return newFeed;
}

View File

@ -4,6 +4,7 @@ import android.app.Application;
import androidx.lifecycle.AndroidViewModel;
import androidx.annotation.NonNull;
import com.readrops.app.database.entities.Account;
import com.readrops.app.repositories.LocalFeedRepository;
import com.readrops.app.utils.FeedInsertionResult;
import com.readrops.app.utils.HtmlParser;
@ -25,8 +26,8 @@ public class AddFeedsViewModel extends AndroidViewModel {
repository = new LocalFeedRepository(application);
}
public Single<List<FeedInsertionResult>> addFeeds(List<ParsingResult> results) {
return repository.addFeeds(results);
public Single<List<FeedInsertionResult>> addFeeds(List<ParsingResult> results, Account account) {
return repository.addFeeds(results, account);
}
public Single<List<ParsingResult>> parseUrl(String url) {

View File

@ -91,11 +91,11 @@ public class MainViewModel extends AndroidViewModel {
}
public void setShowReadItems(boolean showReadItems) {
queryBuilder.setShowReaditems(showReadItems);
queryBuilder.setShowReadItems(showReadItems);
}
public boolean showReadItems() {
return queryBuilder.showReaditems();
return queryBuilder.showReadItems();
}
public void setFilterType(FilterType filterType) {
@ -132,7 +132,7 @@ public class MainViewModel extends AndroidViewModel {
public Single<Map<Folder, List<Feed>>> getFoldersWithFeeds() {
return Single.create(emitter -> {
List<Folder> folders = db.folderDao().getFolders();
List<Folder> folders = db.folderDao().getFolders(currentAccount.getId());
Map<Folder, List<Feed>> foldersWithFeeds = new TreeMap<>(Folder::compareTo);
for (Folder folder : folders) {
@ -186,6 +186,8 @@ public class MainViewModel extends AndroidViewModel {
public void setCurrentAccount(Account currentAccount) {
this.currentAccount = currentAccount;
setRepository(currentAccount.getAccountType());
queryBuilder.setAccountId(currentAccount.getId());
buildPagedList();
// set the new account as the current one
Completable setCurrentAccount = Completable.create(emitter -> {
@ -211,6 +213,8 @@ public class MainViewModel extends AndroidViewModel {
if (account1.isCurrentAccount()) {
currentAccount = account1;
setRepository(currentAccount.getAccountType());
queryBuilder.setAccountId(currentAccount.getId());
buildPagedList();
break;
}
}