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.Feed;
import com.readrops.db.entities.Folder; import com.readrops.db.entities.Folder;
import com.readrops.db.entities.Item; import com.readrops.db.entities.Item;
import com.readrops.db.pojo.StarItem;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -125,27 +127,11 @@ public class NextNewsDataSource {
} }
private void putModifiedItems(NextNewsSyncData data, SyncResult syncResult) throws IOException { private void putModifiedItems(NextNewsSyncData data, SyncResult syncResult) throws IOException {
if (!data.getReadItems().isEmpty()) { setReadState(data.getReadItems(), syncResult, StateType.READ);
Map<String, List<String>> itemIdsMap = new HashMap<>(); setReadState(data.getUnreadItems(), syncResult, StateType.UNREAD);
itemIdsMap.put("items", data.getReadItems());
Response readItemsResponse = api.setArticlesState(StateType.READ.name().toLowerCase(), setStarState(data.getStarredItems(), syncResult, StateType.STAR);
itemIdsMap).execute(); setStarState(data.getUnstarredItems(), syncResult, StateType.UNSTAR);
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);
}
} }
public List<Folder> createFolder(Folder folder) throws IOException, UnknownFormatException, ConflictException { public List<Folder> createFolder(Folder folder) throws IOException, UnknownFormatException, ConflictException {
@ -236,10 +222,42 @@ public class NextNewsDataSource {
return false; 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 { public enum StateType {
READ, READ,
UNREAD, UNREAD,
STARRED, STAR,
UNSTARRED UNSTAR
} }
} }

View File

@ -38,7 +38,10 @@ public interface NextNewsService {
Call<List<Item>> getNewItems(@Query("lastModified") long lastModified, @Query("type") int type); Call<List<Item>> getNewItems(@Query("lastModified") long lastModified, @Query("type") int type);
@PUT("items/{stateType}/multiple") @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") @POST("feeds")
Call<List<Feed>> createFeed(@Query("url") String url, @Query("folderId") int folderId); Call<List<Feed>> createFeed(@Query("url") String url, @Query("folderId") int folderId);

View File

@ -1,5 +1,7 @@
package com.readrops.api.services.nextcloudnews; package com.readrops.api.services.nextcloudnews;
import com.readrops.db.pojo.StarItem;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -9,9 +11,9 @@ public class NextNewsSyncData {
private List<String> readItems; private List<String> readItems;
private List<Integer> starredItems; private List<StarItem> starredItems;
private List<Integer> unstarredItems; private List<StarItem> unstarredItems;
private long lastModified; private long lastModified;
@ -38,19 +40,19 @@ public class NextNewsSyncData {
this.readItems = readItems; this.readItems = readItems;
} }
public List<Integer> getStarredItems() { public List<StarItem> getStarredItems() {
return starredItems; return starredItems;
} }
public void setStarredItems(List<Integer> starredItems) { public void setStarredItems(List<StarItem> starredItems) {
this.starredItems = starredItems; this.starredItems = starredItems;
} }
public List<Integer> getUnstarredItems() { public List<StarItem> getUnstarredItems() {
return unstarredItems; return unstarredItems;
} }
public void setUnstarredItems(List<Integer> unstarredItems) { public void setUnstarredItems(List<StarItem> unstarredItems) {
this.unstarredItems = unstarredItems; this.unstarredItems = unstarredItems;
} }

View File

@ -4,6 +4,7 @@ import android.annotation.SuppressLint
import com.readrops.db.entities.Item import com.readrops.db.entities.Item
import com.readrops.api.utils.ApiUtils import com.readrops.api.utils.ApiUtils
import com.readrops.api.utils.exceptions.ParseException import com.readrops.api.utils.exceptions.ParseException
import com.readrops.api.utils.extensions.nextNonEmptyString
import com.readrops.api.utils.extensions.nextNullableString import com.readrops.api.utils.extensions.nextNullableString
import com.squareup.moshi.JsonAdapter import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonReader import com.squareup.moshi.JsonReader
@ -46,7 +47,9 @@ class NextNewsItemsAdapter : JsonAdapter<List<Item>>() {
6 -> enclosureMime = reader.nextNullableString() 6 -> enclosureMime = reader.nextNullableString()
7 -> enclosureLink = reader.nextNullableString() 7 -> enclosureLink = reader.nextNullableString()
8 -> feedRemoteId = reader.nextInt().toString() 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() else -> reader.skipValue()
} }
} }
@ -70,6 +73,6 @@ class NextNewsItemsAdapter : JsonAdapter<List<Item>>() {
companion object { companion object {
val NAMES: JsonReader.Options = JsonReader.Options.of("id", "url", "title", "author", 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.content.Context;
import android.database.sqlite.SQLiteConstraintException; import android.database.sqlite.SQLiteConstraintException;
import android.util.Log;
import android.util.TimingLogger; import android.util.TimingLogger;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -88,8 +89,12 @@ public class NextNewsRepository extends ARepository {
if (syncType == SyncType.CLASSIC_SYNC) { if (syncType == SyncType.CLASSIC_SYNC) {
syncData.setLastModified(account.getLastModified() / 1000L); syncData.setLastModified(account.getLastModified() / 1000L);
syncData.setReadItems(database.itemDao().getReadChanges(account.getId())); syncData.setReadItems(database.itemDao().getReadChanges(account.getId()));
syncData.setUnreadItems(database.itemDao().getUnreadChanges(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()); TimingLogger timings = new TimingLogger(TAG, "nextcloud news " + syncType.name().toLowerCase());
@ -111,14 +116,22 @@ public class NextNewsRepository extends ARepository {
account.setLastModified(lastModified); account.setLastModified(lastModified);
database.accountDao().updateLastModified(account.getId(), lastModified); database.accountDao().updateLastModified(account.getId(), lastModified);
if (!syncData.getReadItems().isEmpty() || !syncData.getUnreadItems().isEmpty()) {
database.itemDao().resetReadChanges(account.getId()); database.itemDao().resetReadChanges(account.getId());
}
if (!syncData.getStarredItems().isEmpty() || !syncData.getUnstarredItems().isEmpty()) {
database.itemDao().resetStarChanges(account.getId());
}
emitter.onComplete(); emitter.onComplete();
} else } else {
emitter.onError(new Throwable()); emitter.onError(new Throwable());
}
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Log.d(TAG, "sync: " + e.getMessage());
emitter.onError(e); 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.Folder;
import com.readrops.db.entities.Item; import com.readrops.db.entities.Item;
import com.readrops.db.pojo.ItemWithFeed; import com.readrops.db.pojo.ItemWithFeed;
import com.readrops.db.pojo.StarItem;
import java.util.List; import java.util.List;
@ -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") @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); 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)") @Query("Update Item set read_changed = 0 Where feed_id in (Select id From Feed Where account_id = :accountId)")
void resetReadChanges(int 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") @Query("Update Item set read = :read Where remoteId = :remoteId")
void setReadState(String remoteId, boolean read); 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)