Add star/unstar api calls for Nextcloud News

This commit is contained in:
Shinokuni 2020-10-25 19:14:01 +01:00
parent 363ccad5af
commit 9ceb5e6dd7
7 changed files with 91 additions and 35 deletions

View File

@ -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<String, List<String>> 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<String, List<String>> 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<Folder> createFolder(Folder folder) throws IOException, UnknownFormatException, ConflictException {
@ -236,10 +222,42 @@ public class NextNewsDataSource {
return false;
}
private void setReadState(List<String> items, SyncResult syncResult, StateType stateType) throws IOException {
if (!items.isEmpty()) {
Map<String, List<String>> 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<StarItem> items, SyncResult syncResult, StateType stateType) throws IOException {
if (!items.isEmpty()) {
List<Map<String, String>> body = new ArrayList<>();
for (StarItem item : items) {
Map<String, String> 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
}
}

View File

@ -38,7 +38,10 @@ public interface NextNewsService {
Call<List<Item>> getNewItems(@Query("lastModified") long lastModified, @Query("type") int type);
@PUT("items/{stateType}/multiple")
Call<ResponseBody> setArticlesState(@Path("stateType") String stateType, @Body Map<String, List<String>> itemIdsMap);
Call<ResponseBody> setReadState(@Path("stateType") String stateType, @Body Map<String, List<String>> itemIdsMap);
@PUT("items/{starType}/multiple")
Call<ResponseBody> setStarState(@Path("starType") String starType, @Body Map<String, List<Map<String, String>>> body);
@POST("feeds")
Call<List<Feed>> createFeed(@Query("url") String url, @Query("folderId") int folderId);

View File

@ -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<String> readItems;
private List<Integer> starredItems;
private List<StarItem> starredItems;
private List<Integer> unstarredItems;
private List<StarItem> unstarredItems;
private long lastModified;
@ -38,19 +40,19 @@ public class NextNewsSyncData {
this.readItems = readItems;
}
public List<Integer> getStarredItems() {
public List<StarItem> getStarredItems() {
return starredItems;
}
public void setStarredItems(List<Integer> starredItems) {
public void setStarredItems(List<StarItem> starredItems) {
this.starredItems = starredItems;
}
public List<Integer> getUnstarredItems() {
public List<StarItem> getUnstarredItems() {
return unstarredItems;
}
public void setUnstarredItems(List<Integer> unstarredItems) {
public void setUnstarredItems(List<StarItem> unstarredItems) {
this.unstarredItems = unstarredItems;
}

View File

@ -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<List<Item>>() {
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<List<Item>>() {
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")
}
}

View File

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

View File

@ -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<Item> {
* 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<Item> {
@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<String> 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<StarItem> 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<StarItem> 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);
}

View File

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