-
-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Display notifications per-article instead of feed
Groups notifications by article by feed with individual notifications for each.
- Loading branch information
Showing
18 changed files
with
265 additions
and
182 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
129 changes: 129 additions & 0 deletions
129
app/src/main/java/com/capyreader/app/refresher/ArticleNotifications.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package com.capyreader.app.refresher | ||
|
||
import android.app.NotificationChannel | ||
import android.app.NotificationManager | ||
import android.app.PendingIntent | ||
import android.content.Context | ||
import android.content.Intent | ||
import android.os.Bundle | ||
import android.util.Log | ||
import androidx.core.app.NotificationCompat | ||
import androidx.core.app.NotificationCompat.Style | ||
import com.capyreader.app.MainActivity | ||
import com.capyreader.app.Notifications.FEED_UPDATE | ||
import com.capyreader.app.R | ||
import com.capyreader.app.common.AppPreferences | ||
import com.capyreader.app.common.notificationManager | ||
import com.capyreader.app.refresher.ArticleNotifications.Companion.ARTICLE_ID_KEY | ||
import com.capyreader.app.refresher.ArticleNotifications.Companion.FEED_ID_KEY | ||
import com.jocmp.capy.Account | ||
import com.jocmp.capy.ArticleFilter | ||
import com.jocmp.capy.ArticleStatus | ||
import com.jocmp.capy.notifications.ArticleNotification | ||
import java.lang.reflect.Field | ||
import java.time.ZonedDateTime | ||
|
||
class ArticleNotifications( | ||
private val account: Account, | ||
private val applicationContext: Context, | ||
) { | ||
private val notificationManager = applicationContext.notificationManager | ||
|
||
suspend fun notify(since: ZonedDateTime) { | ||
createChannel() | ||
|
||
account.findNotifications(since = since) | ||
.grouped() | ||
.forEach { | ||
notify(it) | ||
} | ||
} | ||
|
||
private fun notify(group: FeedNotification) { | ||
val builder = NotificationCompat.Builder(applicationContext, FEED_UPDATE.channelID) | ||
.setContentTitle(group.title) | ||
.setSmallIcon(R.drawable.newsmode) | ||
.setGroup(group.id) | ||
.setGroupSummary(true) | ||
.setStyle(group.inboxStyle()) | ||
|
||
group.notifications.forEach { notifyArticle(it) } | ||
|
||
notificationManager.notify(group.notificationID, builder.build()) | ||
} | ||
|
||
private fun notifyArticle(notification: ArticleNotification) { | ||
val builder = NotificationCompat.Builder(applicationContext, FEED_UPDATE.channelID) | ||
.setContentTitle(notification.title) | ||
.setSmallIcon(R.drawable.newsmode) | ||
.setGroup(notification.feedID) | ||
.setSubText(notification.feedTitle) | ||
.setAutoCancel(true) | ||
.setContentIntent(notification.intent(applicationContext)) | ||
|
||
notificationManager.notify(notification.notificationID, builder.build()) | ||
} | ||
|
||
private fun createChannel() { | ||
val name = applicationContext.getString(R.string.notifications_channel_title_feed_update) | ||
val channel = NotificationChannel( | ||
FEED_UPDATE.channelID, | ||
name, | ||
NotificationManager.IMPORTANCE_DEFAULT | ||
) | ||
|
||
notificationManager.createNotificationChannel(channel) | ||
} | ||
|
||
companion object { | ||
const val ARTICLE_ID_KEY = "article_id" | ||
const val FEED_ID_KEY = "feed_id" | ||
|
||
fun handleResult(intent: Intent, appPreferences: AppPreferences) { | ||
val articleID = intent.getStringExtra(ARTICLE_ID_KEY) ?: return | ||
val feedID = intent.getStringExtra(FEED_ID_KEY) ?: return | ||
intent.replaceExtras(Bundle()) | ||
|
||
appPreferences.filter.set( | ||
ArticleFilter.Feeds( | ||
feedID, | ||
feedStatus = ArticleStatus.ALL | ||
) | ||
) | ||
appPreferences.articleID.set(articleID) | ||
} | ||
} | ||
} | ||
|
||
private fun FeedNotification.inboxStyle(): Style { | ||
val style = NotificationCompat.InboxStyle() | ||
|
||
notifications.take(3).forEach { | ||
style.addLine(it.title) | ||
} | ||
|
||
style.setSummaryText(title) | ||
|
||
return style | ||
} | ||
|
||
|
||
private fun ArticleNotification.intent(context: Context): PendingIntent { | ||
val notifyIntent = Intent(context, MainActivity::class.java).apply { | ||
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK | ||
putExtra(ARTICLE_ID_KEY, id) | ||
putExtra(FEED_ID_KEY, feedID) | ||
} | ||
|
||
return PendingIntent.getActivity( | ||
context, | ||
notificationID, | ||
notifyIntent, | ||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE | ||
) | ||
} | ||
|
||
private fun List<ArticleNotification>.grouped() = | ||
groupBy { it.feedID }.map { (feedID, notifications) -> | ||
FeedNotification.from(feedID, notifications) | ||
} |
30 changes: 30 additions & 0 deletions
30
app/src/main/java/com/capyreader/app/refresher/FeedNotification.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package com.capyreader.app.refresher | ||
|
||
import com.jocmp.capy.notifications.ArticleNotification | ||
|
||
internal data class FeedNotification( | ||
val id: String, | ||
val title: String, | ||
val faviconURL: String? = null, | ||
val notifications: List<ArticleNotification> | ||
) { | ||
val articleCount: Int | ||
get() = notifications.size | ||
|
||
val notificationID | ||
get() = id.hashCode() | ||
|
||
companion object { | ||
fun from(feedID: String, notifications: List<ArticleNotification>): FeedNotification { | ||
val title = notifications.firstOrNull()?.feedTitle.orEmpty() | ||
val faviconURL = notifications.firstOrNull()?.feedFaviconURL | ||
|
||
return FeedNotification( | ||
id = feedID, | ||
title = title, | ||
faviconURL = faviconURL, | ||
notifications = notifications | ||
) | ||
} | ||
} | ||
} |
91 changes: 0 additions & 91 deletions
91
app/src/main/java/com/capyreader/app/refresher/FeedNotifications.kt
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
app/src/main/java/com/capyreader/app/ui/articles/ArticleHandler.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package com.capyreader.app.ui.articles | ||
|
||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.LaunchedEffect | ||
import com.capyreader.app.common.AppPreferences | ||
import org.koin.compose.koinInject | ||
|
||
@Composable | ||
fun ArticleHandler( | ||
appPreferences: AppPreferences = koinInject(), | ||
onRequestArticle: (articleID: String) -> Unit, | ||
) { | ||
LaunchedEffect(Unit) { | ||
val articleID = appPreferences.articleID.get() | ||
|
||
if (articleID.isNotBlank()) { | ||
appPreferences.articleID.delete() | ||
onRequestArticle(articleID) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.