mirror of https://github.com/readrops/Readrops.git
Add star/unstar api calls for Nextcloud News
This commit is contained in:
parent
363ccad5af
commit
9ceb5e6dd7
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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")
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
Loading…
Reference in New Issue