diff --git a/api/src/main/java/com/readrops/api/services/nextcloudnews/NextNewsDataSource.java b/api/src/main/java/com/readrops/api/services/nextcloudnews/NextNewsDataSource.java index eaa6d30c..4bb96f1d 100644 --- a/api/src/main/java/com/readrops/api/services/nextcloudnews/NextNewsDataSource.java +++ b/api/src/main/java/com/readrops/api/services/nextcloudnews/NextNewsDataSource.java @@ -14,9 +14,11 @@ import com.readrops.api.utils.exceptions.UnknownFormatException; import com.readrops.db.entities.Feed; import com.readrops.db.entities.Folder; import com.readrops.db.entities.Item; +import com.readrops.db.pojo.StarItem; import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -125,27 +127,11 @@ public class NextNewsDataSource { } private void putModifiedItems(NextNewsSyncData data, SyncResult syncResult) throws IOException { - if (!data.getReadItems().isEmpty()) { - Map> itemIdsMap = new HashMap<>(); - itemIdsMap.put("items", data.getReadItems()); + setReadState(data.getReadItems(), syncResult, StateType.READ); + setReadState(data.getUnreadItems(), syncResult, StateType.UNREAD); - Response readItemsResponse = api.setArticlesState(StateType.READ.name().toLowerCase(), - itemIdsMap).execute(); - - if (!readItemsResponse.isSuccessful()) - syncResult.setError(true); - } - - if (!data.getUnreadItems().isEmpty()) { - Map> itemIdsMap = new HashMap<>(); - itemIdsMap.put("items", data.getUnreadItems()); - - Response unreadItemsResponse = api.setArticlesState(StateType.UNREAD.toString().toLowerCase(), - itemIdsMap).execute(); - - if (!unreadItemsResponse.isSuccessful()) - syncResult.setError(true); - } + setStarState(data.getStarredItems(), syncResult, StateType.STAR); + setStarState(data.getUnstarredItems(), syncResult, StateType.UNSTAR); } public List createFolder(Folder folder) throws IOException, UnknownFormatException, ConflictException { @@ -236,10 +222,42 @@ public class NextNewsDataSource { return false; } + private void setReadState(List items, SyncResult syncResult, StateType stateType) throws IOException { + if (!items.isEmpty()) { + Map> itemIdsMap = new HashMap<>(); + itemIdsMap.put("items", items); + + Response readItemsResponse = api.setReadState(stateType.name().toLowerCase(), + itemIdsMap).execute(); + + if (!readItemsResponse.isSuccessful()) + syncResult.setError(true); + } + } + + private void setStarState(List items, SyncResult syncResult, StateType stateType) throws IOException { + if (!items.isEmpty()) { + List> body = new ArrayList<>(); + for (StarItem item : items) { + Map itemBody = new HashMap<>(); + itemBody.put("feedId", item.getFeedRemoteId()); + itemBody.put("guidHash", item.getGuidHash()); + + body.add(itemBody); + } + + Response response = api.setStarState(stateType.name().toLowerCase(), + Collections.singletonMap("items", body)).execute(); + if (!response.isSuccessful()) { + syncResult.setError(true); + } + } + } + public enum StateType { READ, UNREAD, - STARRED, - UNSTARRED + STAR, + UNSTAR } } diff --git a/api/src/main/java/com/readrops/api/services/nextcloudnews/NextNewsService.java b/api/src/main/java/com/readrops/api/services/nextcloudnews/NextNewsService.java index ad37b4fa..a4d4d11c 100644 --- a/api/src/main/java/com/readrops/api/services/nextcloudnews/NextNewsService.java +++ b/api/src/main/java/com/readrops/api/services/nextcloudnews/NextNewsService.java @@ -38,7 +38,10 @@ public interface NextNewsService { Call> getNewItems(@Query("lastModified") long lastModified, @Query("type") int type); @PUT("items/{stateType}/multiple") - Call setArticlesState(@Path("stateType") String stateType, @Body Map> itemIdsMap); + Call setReadState(@Path("stateType") String stateType, @Body Map> itemIdsMap); + + @PUT("items/{starType}/multiple") + Call setStarState(@Path("starType") String starType, @Body Map>> body); @POST("feeds") Call> createFeed(@Query("url") String url, @Query("folderId") int folderId); diff --git a/api/src/main/java/com/readrops/api/services/nextcloudnews/NextNewsSyncData.java b/api/src/main/java/com/readrops/api/services/nextcloudnews/NextNewsSyncData.java index cc1fc8ba..0e59a982 100644 --- a/api/src/main/java/com/readrops/api/services/nextcloudnews/NextNewsSyncData.java +++ b/api/src/main/java/com/readrops/api/services/nextcloudnews/NextNewsSyncData.java @@ -1,5 +1,7 @@ package com.readrops.api.services.nextcloudnews; +import com.readrops.db.pojo.StarItem; + import java.util.ArrayList; import java.util.List; @@ -9,9 +11,9 @@ public class NextNewsSyncData { private List readItems; - private List starredItems; + private List starredItems; - private List unstarredItems; + private List unstarredItems; private long lastModified; @@ -38,19 +40,19 @@ public class NextNewsSyncData { this.readItems = readItems; } - public List getStarredItems() { + public List getStarredItems() { return starredItems; } - public void setStarredItems(List starredItems) { + public void setStarredItems(List starredItems) { this.starredItems = starredItems; } - public List getUnstarredItems() { + public List getUnstarredItems() { return unstarredItems; } - public void setUnstarredItems(List unstarredItems) { + public void setUnstarredItems(List unstarredItems) { this.unstarredItems = unstarredItems; } diff --git a/api/src/main/java/com/readrops/api/services/nextcloudnews/adapters/NextNewsItemsAdapter.kt b/api/src/main/java/com/readrops/api/services/nextcloudnews/adapters/NextNewsItemsAdapter.kt index 25fdf91e..2667b46f 100644 --- a/api/src/main/java/com/readrops/api/services/nextcloudnews/adapters/NextNewsItemsAdapter.kt +++ b/api/src/main/java/com/readrops/api/services/nextcloudnews/adapters/NextNewsItemsAdapter.kt @@ -4,6 +4,7 @@ import android.annotation.SuppressLint import com.readrops.db.entities.Item import com.readrops.api.utils.ApiUtils import com.readrops.api.utils.exceptions.ParseException +import com.readrops.api.utils.extensions.nextNonEmptyString import com.readrops.api.utils.extensions.nextNullableString import com.squareup.moshi.JsonAdapter import com.squareup.moshi.JsonReader @@ -46,7 +47,9 @@ class NextNewsItemsAdapter : JsonAdapter>() { 6 -> enclosureMime = reader.nextNullableString() 7 -> enclosureLink = reader.nextNullableString() 8 -> feedRemoteId = reader.nextInt().toString() - 9 -> isRead = !reader.nextBoolean() + 9 -> isRead = !reader.nextBoolean() // the negation is important here + 10 -> isStarred = reader.nextBoolean() + 11 -> guid = reader.nextNullableString() else -> reader.skipValue() } } @@ -70,6 +73,6 @@ class NextNewsItemsAdapter : JsonAdapter>() { companion object { val NAMES: JsonReader.Options = JsonReader.Options.of("id", "url", "title", "author", - "pubDate", "body", "enclosureMime", "enclosureLink", "feedId", "unread") + "pubDate", "body", "enclosureMime", "enclosureLink", "feedId", "unread", "starred", "guidHash") } } \ No newline at end of file diff --git a/app/src/main/java/com/readrops/app/repositories/NextNewsRepository.java b/app/src/main/java/com/readrops/app/repositories/NextNewsRepository.java index 3cdb7dd8..96789171 100644 --- a/app/src/main/java/com/readrops/app/repositories/NextNewsRepository.java +++ b/app/src/main/java/com/readrops/app/repositories/NextNewsRepository.java @@ -2,6 +2,7 @@ package com.readrops.app.repositories; import android.content.Context; import android.database.sqlite.SQLiteConstraintException; +import android.util.Log; import android.util.TimingLogger; import androidx.annotation.NonNull; @@ -88,8 +89,12 @@ public class NextNewsRepository extends ARepository { if (syncType == SyncType.CLASSIC_SYNC) { syncData.setLastModified(account.getLastModified() / 1000L); + syncData.setReadItems(database.itemDao().getReadChanges(account.getId())); syncData.setUnreadItems(database.itemDao().getUnreadChanges(account.getId())); + + syncData.setStarredItems(database.itemDao().getStarChanges(account.getId())); + syncData.setUnstarredItems(database.itemDao().getUnstarChanges(account.getId())); } TimingLogger timings = new TimingLogger(TAG, "nextcloud news " + syncType.name().toLowerCase()); @@ -111,14 +116,22 @@ public class NextNewsRepository extends ARepository { account.setLastModified(lastModified); database.accountDao().updateLastModified(account.getId(), lastModified); - database.itemDao().resetReadChanges(account.getId()); + + if (!syncData.getReadItems().isEmpty() || !syncData.getUnreadItems().isEmpty()) { + database.itemDao().resetReadChanges(account.getId()); + } + + if (!syncData.getStarredItems().isEmpty() || !syncData.getUnstarredItems().isEmpty()) { + database.itemDao().resetStarChanges(account.getId()); + } emitter.onComplete(); - } else + } else { emitter.onError(new Throwable()); + } } catch (Exception e) { - e.printStackTrace(); + Log.d(TAG, "sync: " + e.getMessage()); emitter.onError(e); } }); diff --git a/db/src/main/java/com/readrops/db/dao/ItemDao.java b/db/src/main/java/com/readrops/db/dao/ItemDao.java index b0eb1f45..439b4e85 100644 --- a/db/src/main/java/com/readrops/db/dao/ItemDao.java +++ b/db/src/main/java/com/readrops/db/dao/ItemDao.java @@ -13,6 +13,7 @@ import com.readrops.db.entities.Feed; import com.readrops.db.entities.Folder; import com.readrops.db.entities.Item; import com.readrops.db.pojo.ItemWithFeed; +import com.readrops.db.pojo.StarItem; import java.util.List; @@ -40,7 +41,7 @@ public interface ItemDao extends BaseDao { * Set an item read or unread * * @param itemId id of the item to update - * @param read 1 for read, 0 for unread + * @param read 1 for read, 0 for unread * @param readChanged */ @Query("Update Item Set read_changed = :readChanged, read = :read Where id = :itemId") @@ -70,9 +71,18 @@ public interface ItemDao extends BaseDao { @Query("Select Item.remoteId From Item Inner Join Feed On Item.feed_id = Feed.id Where read_changed = 1 And read = 0 And account_id = :accountId") List getUnreadChanges(int accountId); + @Query("Select Item.guid, Feed.remoteId as feedRemoteId From Item Inner Join Feed On Item.feed_id = Feed.id Where starred_changed = 1 And starred = 1 And account_id = :accountId") + List getStarChanges(int accountId); + + @Query("Select Item.guid, Feed.remoteId as feedRemoteId From Item Inner Join Feed On Item.feed_id = Feed.id Where starred_changed = 1 And starred = 0 And account_id = :accountId") + List getUnstarChanges(int accountId); + @Query("Update Item set read_changed = 0 Where feed_id in (Select id From Feed Where account_id = :accountId)") void resetReadChanges(int accountId); + @Query("Update Item set starred_changed = 0 Where feed_id in (Select id From Feed Where account_id = :accountId)") + void resetStarChanges(int accountId); + @Query("Update Item set read = :read Where remoteId = :remoteId") void setReadState(String remoteId, boolean read); } diff --git a/db/src/main/java/com/readrops/db/pojo/StarItem.kt b/db/src/main/java/com/readrops/db/pojo/StarItem.kt new file mode 100644 index 00000000..a58ba616 --- /dev/null +++ b/db/src/main/java/com/readrops/db/pojo/StarItem.kt @@ -0,0 +1,7 @@ +package com.readrops.db.pojo + +import androidx.room.ColumnInfo + + +data class StarItem(@ColumnInfo val feedRemoteId: String, + @ColumnInfo(name = "guid") val guidHash: String) \ No newline at end of file