diff --git a/app/src/androidTest/java/com/readrops/app/SyncResultAnalyserTest.kt b/app/src/androidTest/java/com/readrops/app/SyncResultAnalyserTest.kt index 16b76b44..3feb3528 100644 --- a/app/src/androidTest/java/com/readrops/app/SyncResultAnalyserTest.kt +++ b/app/src/androidTest/java/com/readrops/app/SyncResultAnalyserTest.kt @@ -11,6 +11,7 @@ import com.readrops.readropsdb.entities.Item import com.readrops.readropsdb.entities.account.Account import com.readrops.readropsdb.entities.account.AccountType import com.readrops.readropslibrary.services.SyncResult +import org.joda.time.LocalDateTime import org.junit.After import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue @@ -27,11 +28,13 @@ class SyncResultAnalyserTest { private val account1 = Account().apply { accountName = "test account 1" accountType = AccountType.FRESHRSS + isNotificationsEnabled = true } private val account2 = Account().apply { accountName = "test account 2" accountType = AccountType.NEXTCLOUD_NEWS + isNotificationsEnabled = true } @Before @@ -50,6 +53,7 @@ class SyncResultAnalyserTest { name = "feed ${i + 1}" iconUrl = "https://i0.wp.com/mrmondialisation.org/wp-content/uploads/2017/05/ico_final.gif" this.accountId = if (i % 2 == 0) account1Id else account2Id + isNotificationEnabled = true } database.feedDao().insert(feed).subscribe() @@ -62,28 +66,38 @@ class SyncResultAnalyserTest { } @Test - fun caseOneElementEveryWhere() { + fun testOneElementEveryWhere() { val item = Item().apply { title = "caseOneElementEveryWhere" feedId = 1 + remoteId = "item 1" + pubDate = LocalDateTime.now() } + database.itemDao() + .insert(item) + .subscribe() + val syncResult = SyncResult().apply { items = mutableListOf(item) } val notifContent = SyncResultAnalyser(context, mapOf(Pair(account1, syncResult)), database).getSyncNotifContent() assertEquals("caseOneElementEveryWhere", notifContent.content) assertEquals("feed 1", notifContent.title) assertTrue(notifContent.largeIcon != null) + + database.itemDao() + .delete(item) + .subscribe() } @Test - fun caseTwoItemsOneFeed() { + fun testTwoItemsOneFeed() { val item = Item().apply { title = "caseTwoItemsOneFeed" feedId = 1 } - val syncResult = SyncResult().apply { items = mutableListOf(item, item, item) } + val syncResult = SyncResult().apply { items = listOf(item, item, item) } val notifContent = SyncResultAnalyser(context, mapOf(Pair(account1, syncResult)), database).getSyncNotifContent() assertEquals(context.getString(R.string.new_items, 3), notifContent.content) @@ -92,11 +106,11 @@ class SyncResultAnalyserTest { } @Test - fun caseMultipleFeeds() { + fun testMultipleFeeds() { val item = Item().apply { feedId = 1 } val item2 = Item().apply { feedId = 2 } - val syncResult = SyncResult().apply { items = mutableListOf(item, item2) } + val syncResult = SyncResult().apply { items = listOf(item, item2) } val notifContent = SyncResultAnalyser(context, mapOf(Pair(account1, syncResult)), database).getSyncNotifContent() assertEquals(context.getString(R.string.new_items, 2), notifContent.content) @@ -105,12 +119,12 @@ class SyncResultAnalyserTest { } @Test - fun multipleAccounts() { + fun testMultipleAccounts() { val item = Item().apply { feedId = 1 } val item2 = Item().apply { feedId = 2 } - val syncResult = SyncResult().apply { items = mutableListOf(item, item2) } - val syncResult2 = SyncResult().apply { items = mutableListOf(item, item2) } + val syncResult = SyncResult().apply { items = listOf(item, item2) } + val syncResult2 = SyncResult().apply { items = listOf(item, item2) } val syncResults = mutableMapOf().apply { put(account1, syncResult) diff --git a/app/src/main/java/com/readrops/app/utils/SyncResultAnalyser.kt b/app/src/main/java/com/readrops/app/utils/SyncResultAnalyser.kt index 2d2dcef8..dcd14edf 100644 --- a/app/src/main/java/com/readrops/app/utils/SyncResultAnalyser.kt +++ b/app/src/main/java/com/readrops/app/utils/SyncResultAnalyser.kt @@ -1,11 +1,11 @@ package com.readrops.app.utils import android.content.Context -import android.graphics.Bitmap import androidx.core.content.ContextCompat import com.bumptech.glide.load.engine.DiskCacheStrategy import com.readrops.app.R import com.readrops.readropsdb.Database +import com.readrops.readropsdb.entities.Feed import com.readrops.readropsdb.entities.Item import com.readrops.readropsdb.entities.account.Account import com.readrops.readropslibrary.services.SyncResult @@ -15,81 +15,100 @@ import com.readrops.readropslibrary.services.SyncResult */ class SyncResultAnalyser(val context: Context, private val syncResults: Map, val database: Database) { + private val notifContent = SyncResultNotifContent() + fun getSyncNotifContent(): SyncResultNotifContent { - var title: String? = null - var contentText: String? = null - var largeIcon: Bitmap? = null - var item: Item? = null + if (newItemsInMultipleAccounts()) { // new items from several accounts + var itemCount = 0 + val feeds = database.feedDao().selectFromIdList(getFeedsIdsForNewItems(syncResults)) - if (newItemsInMultipleAccounts()) { - var itemsNb = 0 - syncResults.values.forEach { itemsNb += it.items.size } + syncResults.values.forEach { syncResult -> + itemCount += syncResult.items.filter { isFeedNotificationEnabledForItem(feeds, it) }.size + } - title = "Notifications" - contentText = context.getString(R.string.new_items, itemsNb.toString()) + notifContent.title = "Notifications" + notifContent.content = context.getString(R.string.new_items, itemCount.toString()) } else { // new items from only one account val syncResultMap = syncResults.filterValues { it.items.isNotEmpty() } if (syncResultMap.values.isNotEmpty()) { val syncResult = syncResultMap.values.first() + val account = syncResultMap.keys.first() val feedsIdsForNewItems = getFeedsIdsForNewItems(syncResult) - // new items from several feeds from one account - if (feedsIdsForNewItems.size > 1) { - val account = syncResultMap.keys.first() + if (account.isNotificationsEnabled) { + // new items from several feeds from one account + if (feedsIdsForNewItems.size > 1) { + val feeds = database.feedDao().selectFromIdList(feedsIdsForNewItems) - title = account.accountName - contentText = context.getString(R.string.new_items, syncResult.items.size.toString()) - largeIcon = Utils.getBitmapFromDrawable(ContextCompat.getDrawable(context, account.accountType.iconRes)) - } else if (feedsIdsForNewItems.size == 1) { // new items from only one feed from one account - val feed = database.feedDao().getFeedById(feedsIdsForNewItems.first()) - title = feed?.name + val itemCount = syncResult.items.filter { isFeedNotificationEnabledForItem(feeds, it) }.size - feed?.iconUrl?.let { - val target = GlideApp.with(context) - .asBitmap() - .load(it) - .diskCacheStrategy(DiskCacheStrategy.ALL) - .submit() - - largeIcon = target.get() - } - - if (syncResult.items.size == 1) { - item = database.itemDao().selectByRemoteId(syncResult.items.first().remoteId, - syncResult.items.first().feedId) - contentText = item.title - } else contentText = context.getString(R.string.new_items, syncResult.items.size.toString()) + notifContent.title = account.accountName + notifContent.content = context.getString(R.string.new_items, itemCount.toString()) + notifContent.largeIcon = Utils.getBitmapFromDrawable(ContextCompat.getDrawable(context, account.accountType.iconRes)) + } else if (feedsIdsForNewItems.size == 1) // new items from only one feed from one account + oneFeedCase(feedsIdsForNewItems.first(), syncResult) } } - } - return SyncResultNotifContent(title, - contentText, - largeIcon, - item) + return notifContent + } + + private fun oneFeedCase(feedId: Long, syncResult: SyncResult) { + val feed = database.feedDao().getFeedById(feedId.toInt()) + + if (feed.isNotificationEnabled) { + notifContent.title = feed?.name + + feed?.iconUrl?.let { + val target = GlideApp.with(context) + .asBitmap() + .load(it) + .diskCacheStrategy(DiskCacheStrategy.ALL) + .submit() + + notifContent.largeIcon = target.get() + } + + if (syncResult.items.size == 1) { + val item = database.itemDao().selectByRemoteId(syncResult.items.first().remoteId, + syncResult.items.first().feedId) + notifContent.content = item.title + notifContent.item = item + } else notifContent.content = context.getString(R.string.new_items, syncResult.items.size.toString()) + } } private fun newItemsInMultipleAccounts(): Boolean { val itemsNotEmptyByAccount = mutableListOf() - for ((_, syncResult) in syncResults) { - itemsNotEmptyByAccount += syncResult.items.isNotEmpty() + for ((account, syncResult) in syncResults) { + if (account.isNotificationsEnabled) itemsNotEmptyByAccount += syncResult.items.isNotEmpty() } // return true it there is at least two true booleans in the list return itemsNotEmptyByAccount.groupingBy { it }.eachCount()[true] ?: 0 > 1 } - private fun getFeedsIdsForNewItems(syncResult: SyncResult): List { - val feedsIds = mutableListOf() + private fun getFeedsIdsForNewItems(syncResult: SyncResult): List { + val feedsIds = mutableListOf() syncResult.items.forEach { - if (it.feedId !in feedsIds) - feedsIds += it.feedId + if (it.feedId.toLong() !in feedsIds) + feedsIds += it.feedId.toLong() } return feedsIds } + + private fun getFeedsIdsForNewItems(syncResults: Map): List { + val feedsIds = mutableListOf() + + syncResults.values.forEach { feedsIds += getFeedsIdsForNewItems(it) } + return feedsIds + } + + private fun isFeedNotificationEnabledForItem(feeds: List, item: Item): Boolean = + feeds.find { it.id == item.feedId }?.isNotificationEnabled!! } \ No newline at end of file diff --git a/app/src/main/java/com/readrops/app/utils/SyncResultDebugData.kt b/app/src/main/java/com/readrops/app/utils/SyncResultDebugData.kt index 0a8f623e..e3bbeb07 100644 --- a/app/src/main/java/com/readrops/app/utils/SyncResultDebugData.kt +++ b/app/src/main/java/com/readrops/app/utils/SyncResultDebugData.kt @@ -6,29 +6,55 @@ import com.readrops.readropsdb.entities.Item import com.readrops.readropsdb.entities.account.Account import com.readrops.readropsdb.entities.account.AccountType import com.readrops.readropslibrary.services.SyncResult +import org.jetbrains.annotations.TestOnly class SyncResultDebugData { companion object { + @TestOnly fun oneAccountOneFeedOneItem(context: Context): Map { val account1 = Account().apply { id = 1 accountType = AccountType.FRESHRSS + isNotificationsEnabled = true } - val item = Database.getInstance(context).itemDao().select(5362) + val database = Database.getInstance(context) + val item = database.itemDao().select(5056) + // database.feedDao().updateNotificationState(item.feedId, false).subscribe() return mutableMapOf().apply { put(account1, SyncResult().apply { items = mutableListOf(item) }) } } + @TestOnly + fun oneAccountOneFeedMultipleItems(context: Context): Map { + val account1 = Account().apply { + id = 1 + accountType = AccountType.FRESHRSS + isNotificationsEnabled = true + } + + val database = Database.getInstance(context) + val item = database.itemDao().select(5055) + database.feedDao().updateNotificationState(item.feedId, false).subscribe() + + val item2 = database.itemDao().select(5056) + + return mutableMapOf().apply { + put(account1, SyncResult().apply { items = listOf(item, item2) }) + } + } + + @TestOnly fun oneAccountMultipleFeeds(): Map { val account1 = Account().apply { accountName = "Test account" id = 1 accountType = AccountType.FRESHRSS + isNotificationsEnabled = true } val item1 = Item().apply { diff --git a/app/src/main/java/com/readrops/app/utils/SyncResultNotifContent.kt b/app/src/main/java/com/readrops/app/utils/SyncResultNotifContent.kt index dcfcdb36..86e799e4 100644 --- a/app/src/main/java/com/readrops/app/utils/SyncResultNotifContent.kt +++ b/app/src/main/java/com/readrops/app/utils/SyncResultNotifContent.kt @@ -3,7 +3,9 @@ package com.readrops.app.utils import android.graphics.Bitmap import com.readrops.readropsdb.entities.Item -data class SyncResultNotifContent(val title: String?, - val content: String?, - val largeIcon: Bitmap?, - val item: Item?) \ No newline at end of file +class SyncResultNotifContent { + var title: String? = null + var content: String? = null + var largeIcon: Bitmap? = null + var item: Item? = null +} \ No newline at end of file diff --git a/app/src/main/java/com/readrops/app/utils/SyncWorker.kt b/app/src/main/java/com/readrops/app/utils/SyncWorker.kt index 77f31405..8f7c2bd7 100644 --- a/app/src/main/java/com/readrops/app/utils/SyncWorker.kt +++ b/app/src/main/java/com/readrops/app/utils/SyncWorker.kt @@ -73,8 +73,8 @@ class SyncWorker(context: Context, parameters: WorkerParameters) : Worker(contex if (notifContent.title != null && notifContent.content != null) { val intent = Intent(applicationContext, MainActivity::class.java).apply { if (notifContent.item != null) { - putExtra(ReadropsKeys.ITEM_ID, notifContent.item.id) - putExtra(ReadropsKeys.IMAGE_URL, notifContent.item.imageLink) + putExtra(ReadropsKeys.ITEM_ID, notifContent.item?.id) + putExtra(ReadropsKeys.IMAGE_URL, notifContent.item?.imageLink) } }