Sync result notification now respects account and feed notification permissions
This commit is contained in:
parent
65aca8eb5d
commit
c949ed58f5
@ -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)
|
||||
|
@ -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!!
|
||||
}
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user