Sync result notification now respects account and feed notification permissions

This commit is contained in:
Shinokuni 2020-03-15 18:47:04 +01:00
parent 65aca8eb5d
commit c949ed58f5
5 changed files with 121 additions and 60 deletions

View File

@ -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<Account, SyncResult>().apply {
put(account1, syncResult)

View File

@ -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<Account, SyncResult>, 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<Boolean>()
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<Int> {
val feedsIds = mutableListOf<Int>()
private fun getFeedsIdsForNewItems(syncResult: SyncResult): List<Long> {
val feedsIds = mutableListOf<Long>()
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<Account, SyncResult>): List<Long> {
val feedsIds = mutableListOf<Long>()
syncResults.values.forEach { feedsIds += getFeedsIdsForNewItems(it) }
return feedsIds
}
private fun isFeedNotificationEnabledForItem(feeds: List<Feed>, item: Item): Boolean =
feeds.find { it.id == item.feedId }?.isNotificationEnabled!!
}

View File

@ -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<Account, SyncResult> {
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<Account, SyncResult>().apply {
put(account1, SyncResult().apply { items = mutableListOf(item) })
}
}
@TestOnly
fun oneAccountOneFeedMultipleItems(context: Context): Map<Account, SyncResult> {
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<Account, SyncResult>().apply {
put(account1, SyncResult().apply { items = listOf(item, item2) })
}
}
@TestOnly
fun oneAccountMultipleFeeds(): Map<Account, SyncResult> {
val account1 = Account().apply {
accountName = "Test account"
id = 1
accountType = AccountType.FRESHRSS
isNotificationsEnabled = true
}
val item1 = Item().apply {

View File

@ -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?)
class SyncResultNotifContent {
var title: String? = null
var content: String? = null
var largeIcon: Bitmap? = null
var item: Item? = null
}

View File

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