Synchronize local read/star changes

This commit is contained in:
Shinokuni 2021-05-06 22:10:27 +02:00
parent ede2b77ef8
commit d15315b53f
7 changed files with 102 additions and 34 deletions

View File

@ -38,6 +38,7 @@ import com.readrops.app.utils.PermissionManager;
import com.readrops.app.utils.SharedPreferencesManager;
import com.readrops.app.utils.Utils;
import com.readrops.db.entities.Item;
import com.readrops.db.entities.account.Account;
import com.readrops.db.pojo.ItemWithFeed;
import org.koin.androidx.viewmodel.compat.ViewModelCompat;
@ -49,10 +50,10 @@ import java.util.regex.Pattern;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import static com.readrops.app.utils.ReadropsKeys.ACCOUNT;
import static com.readrops.app.utils.ReadropsKeys.ACTION_BAR_COLOR;
import static com.readrops.app.utils.ReadropsKeys.IMAGE_URL;
import static com.readrops.app.utils.ReadropsKeys.ITEM_ID;
import static com.readrops.app.utils.ReadropsKeys.STARRED_ITEM;
import static com.readrops.app.utils.ReadropsKeys.WEB_URL;
public class ItemActivity extends AppCompatActivity {
@ -82,7 +83,7 @@ public class ItemActivity extends AppCompatActivity {
Intent intent = getIntent();
int itemId = intent.getIntExtra(ITEM_ID, 0);
String imageUrl = intent.getStringExtra(IMAGE_URL);
boolean starredItem = intent.getBooleanExtra(STARRED_ITEM, false);
Account account = intent.getParcelableExtra(ACCOUNT);
setSupportActionBar(binding.collapsingLayoutToolbar);
@ -119,6 +120,7 @@ public class ItemActivity extends AppCompatActivity {
}));
viewModel = ViewModelCompat.getViewModel(this, ItemViewModel.class);
viewModel.setAccount(account);
viewModel.getItemById(itemId).observe(this, itemWithFeed1 -> {
if (!uiBinded) {
bindUI(itemWithFeed1);

View File

@ -12,8 +12,10 @@ import androidx.lifecycle.ViewModel;
import com.readrops.app.repositories.ARepository;
import com.readrops.db.Database;
import com.readrops.db.entities.Item;
import com.readrops.db.entities.account.Account;
import com.readrops.db.pojo.ItemWithFeed;
import org.koin.core.parameter.DefinitionParametersKt;
import org.koin.java.KoinJavaComponent;
import java.io.File;
@ -26,17 +28,23 @@ import io.reactivex.Completable;
public class ItemViewModel extends ViewModel {
private final Database database;
private Account account;
public ItemViewModel(@NonNull Database database) {
this.database = database;
}
public void setAccount(Account account) {
this.account = account;
}
public LiveData<ItemWithFeed> getItemById(int id) {
return database.itemDao().getItemById(id);
}
public Completable setStarState(Item item) {
return KoinJavaComponent.get(ARepository.class).setItemStarState(item);
return KoinJavaComponent.get(ARepository.class, null, () -> DefinitionParametersKt.parametersOf(account))
.setItemStarState(item);
}
public Uri saveImageInCache(Bitmap bitmap, Context context) throws IOException {

View File

@ -73,7 +73,6 @@ import static com.readrops.app.utils.ReadropsKeys.FROM_MAIN_ACTIVITY;
import static com.readrops.app.utils.ReadropsKeys.IMAGE_URL;
import static com.readrops.app.utils.ReadropsKeys.ITEM_ID;
import static com.readrops.app.utils.ReadropsKeys.SETTINGS;
import static com.readrops.app.utils.ReadropsKeys.STARRED_ITEM;
import static com.readrops.app.utils.ReadropsKeys.SYNCING;
public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener,
@ -229,6 +228,7 @@ public class MainActivity extends AppCompatActivity implements SwipeRefreshLayou
if (intent.hasExtra(ITEM_ID) && intent.hasExtra(IMAGE_URL)) {
Intent itemIntent = new Intent(this, ItemActivity.class);
itemIntent.putExtras(intent);
itemIntent.putExtra(ACCOUNT, viewModel.getCurrentAccount());
startActivity(itemIntent);
@ -318,8 +318,8 @@ public class MainActivity extends AppCompatActivity implements SwipeRefreshLayou
intent.putExtra(ITEM_ID, itemWithFeed.getItem().getId());
intent.putExtra(IMAGE_URL, itemWithFeed.getItem().getImageLink());
intent.putExtra(STARRED_ITEM, drawerManager.getCurrentSelection() == DrawerManager.STARS_ID &&
viewModel.getCurrentAccount().getConfig().useStarredItems());
intent.putExtra(ACCOUNT, viewModel.getCurrentAccount());
startActivityForResult(intent, ITEM_REQUEST);
itemWithFeed.getItem().setRead(true);

View File

@ -18,7 +18,6 @@ import com.readrops.db.entities.Feed;
import com.readrops.db.entities.Folder;
import com.readrops.db.entities.Item;
import com.readrops.db.entities.ItemState;
import com.readrops.db.entities.ItemStateChange;
import com.readrops.db.entities.account.Account;
import org.koin.java.KoinJavaComponent;
@ -116,9 +115,9 @@ public abstract class ARepository {
}
public Completable setItemReadState(Item item) {
return database.itemStateDao().upsertItemReadState(new ItemState(0, item.isRead(), item.isStarred(), item.getRemoteId(), account.getId()))
.andThen(database.itemStateChangesDao().upsertItemStateChange(new ItemStateChange(item.getId(),
true, false, account.getId())));
return database.itemStateChangesDao().upsertItemReadStateChange(item, account.getId())
.andThen(database.itemStateDao().upsertItemReadState(new ItemState(0, item.isRead(),
item.isStarred(), item.getRemoteId(), account.getId())));
}
public Completable setAllItemsReadState(boolean read) {
@ -130,9 +129,10 @@ public abstract class ARepository {
}
public Completable setItemStarState(Item item) {
return database.itemDao().setStarState(item.getId(), item.isStarred())
.andThen(database.itemStateChangesDao().upsertItemStateChange(new ItemStateChange(item.getId(),
false, true, account.getId())));
return database.itemStateChangesDao().upsertItemStarStateChange(item, account.getId())
.andThen(database.itemStateDao().upsertItemStarState(new ItemState(0, item.isRead(),
item.isStarred(), item.getRemoteId(), account.getId())));
}
public Single<Integer> getFeedCount(int accountId) {

View File

@ -38,12 +38,6 @@ public interface ItemDao extends BaseDao<Item> {
@Query("Select * From Item Where remoteId = :remoteId And feed_id = :feedId")
Item selectByRemoteId(String remoteId, int feedId);
/**
* Set an item read or unread
*
* @param itemId id of the item to update
* @param read 1 for read, 0 for unread
*/
@Query("Update Item Set read = :read Where id = :itemId")
Completable setReadState(int itemId, boolean read);
@ -60,7 +54,7 @@ public interface ItemDao extends BaseDao<Item> {
int getUnreadCount(int feedId);
@SuppressWarnings(RoomWarnings.CURSOR_MISMATCH)
@Query("Select Item.id, title, Item.description, content, link, pub_date, image_link, author, read, text_color, " +
@Query("Select Item.id, Item.remoteId, title, Item.description, content, link, pub_date, image_link, author, read, text_color, " +
"background_color, read_time, starred, Feed.name, Feed.id as feedId, siteUrl, Folder.id as folder_id, " +
"Folder.name as folder_name from Item Inner Join Feed On Item.feed_id = Feed.id Left Join Folder on Folder.id = Feed.folder_id Where Item.id = :id")
LiveData<ItemWithFeed> getItemById(int id);
@ -79,7 +73,4 @@ public interface ItemDao extends BaseDao<Item> {
@Query("Update Item set read = :read, starred = :starred Where remoteId = :remoteId")
void setReadAndStarState(String remoteId, boolean read, boolean starred);
@Query("Update Item set starred = :starred Where id = :itemId")
Completable setStarState(int itemId, boolean starred);
}

View File

@ -4,6 +4,7 @@ import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import com.readrops.db.entities.Item
import com.readrops.db.entities.ItemStateChange
import com.readrops.db.pojo.ItemReadStarState
import io.reactivex.Completable
@ -27,20 +28,73 @@ interface ItemStateChangeDao : BaseDao<ItemStateChange> {
"Left Join ItemState On ItemState.remote_id = Item.remoteId Where ItemStateChange.account_id = :accountId")
fun getItemStateChanges(accountId: Int): List<ItemReadStarState>
fun upsertItemStateChange(itemStateChange: ItemStateChange) = Completable.create {
if (itemStateChange.readChange && readStateChangeExists(itemStateChange.id) ||
itemStateChange.starChange && starStateChangeExists(itemStateChange.id)) {
deleteItemStateChange(itemStateChange)
} else {
insertItemStateChange(itemStateChange)
}
it.onComplete()
}
@Query("Select Case When :itemId In (Select id From ItemStateChange Where read_change = 1) Then 1 Else 0 End")
fun readStateChangeExists(itemId: Int): Boolean
@Query("Select Case When :itemId In (Select id From ItemStateChange Where star_change = 1) Then 1 Else 0 End")
fun starStateChangeExists(itemId: Int): Boolean
fun upsertItemReadStateChange(item: Item, accountId: Int) = Completable.create {
if (itemStateChangeExists(item.id, accountId)) {
val oldItemReadState = getItemReadState(item.remoteId, accountId)
val readChange = item.isRead != oldItemReadState
if (readChange) {
val oldItemStateChange = selectItemStateChange(item.id)
val newReadChange = !oldItemStateChange.readChange
if (!newReadChange && !oldItemStateChange.starChange) {
deleteItemStateChange(oldItemStateChange)
} else {
updateItemReadStateChange(newReadChange, oldItemStateChange.id)
}
}
} else {
insertItemStateChange(ItemStateChange(id = item.id, readChange = true, accountId = accountId))
}
it.onComplete()
}
fun upsertItemStarStateChange(item: Item, accountId: Int) = Completable.create {
if (itemStateChangeExists(item.id, accountId)) {
val oldItemStarState = getItemStarState(item.remoteId, accountId)
val starChange = item.isStarred != oldItemStarState
if (starChange) {
val oldItemStateChange = selectItemStateChange(item.id)
val newStarChange = !oldItemStateChange.starChange
if (!newStarChange && !oldItemStateChange.readChange) {
deleteItemStateChange(oldItemStateChange)
} else {
updateItemStarStateChange(newStarChange, oldItemStateChange.id)
}
}
} else {
insertItemStateChange(ItemStateChange(id = item.id, starChange = true, accountId = accountId))
}
it.onComplete()
}
@Query("Select * From ItemStateChange Where id = :id")
fun selectItemStateChange(id: Int): ItemStateChange
@Query("Select case When Exists (Select id, account_id From ItemStateChange Where id = :id And account_id = :accountId) Then 1 else 0 End")
fun itemStateChangeExists(id: Int, accountId: Int): Boolean
@Query("Select read From ItemState Where remote_id = :remoteId And account_id = :accountId")
fun getItemReadState(remoteId: String, accountId: Int): Boolean
@Query("Select starred From ItemState Where remote_id = :remoteId And account_id = :accountId")
fun getItemStarState(remoteId: String, accountId: Int): Boolean
@Query("Update ItemStateChange set read_change = :readChange Where id = :id")
fun updateItemReadStateChange(readChange: Boolean, id: Int)
@Query("Update ItemStateChange set star_change = :starChange Where id = :id")
fun updateItemStarStateChange(starChange: Boolean, id: Int)
}

View File

@ -24,6 +24,9 @@ interface ItemStateDao : BaseDao<ItemState> {
@Query("Update ItemState set read = :read Where remote_id = :remoteId And account_id = :accountId")
fun updateItemReadState(read: Boolean, remoteId: String, accountId: Int)
@Query("Update ItemState set starred = :star Where remote_id = :remoteId And account_id = :accountId")
fun updateItemStarState(star: Boolean, remoteId: String, accountId: Int)
@Query("Select case When Exists (Select remote_id, account_id From ItemState Where remote_id = :remoteId And account_id = :accountId) Then 1 else 0 End")
fun itemStateExists(remoteId: String, accountId: Int): Boolean
@ -36,4 +39,14 @@ interface ItemStateDao : BaseDao<ItemState> {
it.onComplete()
}
fun upsertItemStarState(itemState: ItemState) = Completable.create {
if (itemStateExists(itemState.remoteId, itemState.accountId)) {
updateItemStarState(itemState.starred, itemState.remoteId, itemState.accountId)
} else {
insertItemState(itemState)
}
it.onComplete()
}
}