diff --git a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselNotificationBackend.kt b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselNotificationBackend.kt index 23bf961f9ead8394883c771c8b18acbb2c3884b6..9dadcec95a3ca096c6eb30e589f44526bcebd9ae 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselNotificationBackend.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselNotificationBackend.kt @@ -50,6 +50,7 @@ import de.kuschku.quasseldroid.util.helper.styledAttributes import de.kuschku.quasseldroid.util.irc.format.ContentFormatter import de.kuschku.quasseldroid.util.ui.TextDrawable import de.kuschku.quasseldroid.viewmodel.EditorViewModel +import org.threeten.bp.Instant import java.util.concurrent.Executors import java.util.concurrent.TimeUnit import javax.inject.Inject @@ -72,6 +73,8 @@ class QuasselNotificationBackend @Inject constructor( @ColorInt private var colorBackground: Int + private var initTime: Instant = Instant.EPOCH + init { notificationSettings = Settings.notification(context) appearanceSettings = Settings.appearance(context) @@ -95,6 +98,7 @@ class QuasselNotificationBackend @Inject constructor( } override fun init(session: Session) { + initTime = Instant.now() if (session.features.negotiated.hasFeature(ExtendedFeature.BacklogFilterType)) { val buffers = session.bufferSyncer.bufferInfos() for (buffer in buffers) { @@ -175,6 +179,7 @@ class QuasselNotificationBackend @Inject constructor( @Synchronized override fun processMessages(session: Session, vararg messages: Message) { + val now = Instant.now() val results = messages.filter { val level = it.bufferInfo.type.let { when { @@ -208,6 +213,7 @@ class QuasselNotificationBackend @Inject constructor( }.map { QuasselDatabase.NotificationData( messageId = it.messageId, + creationTime = now, time = it.time, type = it.type, flag = it.flag, @@ -237,6 +243,10 @@ class QuasselNotificationBackend @Inject constructor( private fun showNotification(buffer: BufferId) { val data = database.notifications().all(buffer) data.lastOrNull()?.let { + // Only send a loud notification if it has any new messages + val max = data.maxBy { it.creationTime } + val isLoud = max?.creationTime?.isAfter(initTime) == true + val bufferInfo = BufferInfo( bufferId = it.bufferId, bufferName = it.bufferName, @@ -300,7 +310,7 @@ class QuasselNotificationBackend @Inject constructor( ) } val notification = notificationHandler.notificationMessage( - notificationSettings, bufferInfo, notificationData + notificationSettings, bufferInfo, notificationData, isLoud ) notificationHandler.notify(notification) } ?: notificationHandler.remove(buffer) diff --git a/app/src/main/java/de/kuschku/quasseldroid/service/QuasseldroidNotificationManager.kt b/app/src/main/java/de/kuschku/quasseldroid/service/QuasseldroidNotificationManager.kt index f9576ca89c93658681aacbc1360dc38c244c6c14..c87b1ab034f0a573d174b4031efe12770ec0284b 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/service/QuasseldroidNotificationManager.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/service/QuasseldroidNotificationManager.kt @@ -42,6 +42,7 @@ import de.kuschku.quasseldroid.settings.NotificationSettings import de.kuschku.quasseldroid.ui.chat.ChatActivity import de.kuschku.quasseldroid.util.NotificationMessage import de.kuschku.quasseldroid.util.helper.getColorCompat +import de.kuschku.quasseldroid.util.helper.letIf import de.kuschku.quasseldroid.util.ui.LocaleHelper import javax.inject.Inject @@ -77,6 +78,17 @@ class QuasseldroidNotificationManager @Inject constructor(private val context: C enableVibration(true) lightColor = context.getColorCompat(R.color.colorPrimary) lockscreenVisibility = Notification.VISIBILITY_PRIVATE + }, + NotificationChannel( + translatedLocale.getString(R.string.notification_channel_old_highlight), + translatedLocale.getString(R.string.notification_channel_old_highlight_title), + NotificationManager.IMPORTANCE_DEFAULT + ).apply { + setSound(null, null) + enableLights(false) + enableVibration(false) + lightColor = context.getColorCompat(R.color.colorPrimary) + lockscreenVisibility = Notification.VISIBILITY_PRIVATE } ) ) @@ -96,7 +108,7 @@ class QuasseldroidNotificationManager @Inject constructor(private val context: C } fun notificationMessage(notificationSettings: NotificationSettings, bufferInfo: BufferInfo, - notifications: List<NotificationMessage>): Handle { + notifications: List<NotificationMessage>, isLoud: Boolean): Handle { val pendingIntentOpen = PendingIntent.getActivity( context.applicationContext, System.currentTimeMillis().toInt(), @@ -145,7 +157,10 @@ class QuasseldroidNotificationManager @Inject constructor(private val context: C val notification = NotificationCompat.Builder( context.applicationContext, - translatedLocale.getString(R.string.notification_channel_highlight) + translatedLocale.getString( + if (isLoud) R.string.notification_channel_highlight + else R.string.notification_channel_old_highlight + ) ) .setContentIntent(pendingIntentOpen) .setDeleteIntent(deletePendingIntent) @@ -153,7 +168,7 @@ class QuasseldroidNotificationManager @Inject constructor(private val context: C .setColor(context.getColorCompat(R.color.colorPrimary)) .setLights(context.getColorCompat(R.color.colorPrimary), 200, 200) .apply { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O && isLoud) { var defaults = 0 if (!notificationSettings.sound.isEmpty()) { setSound(Uri.parse(notificationSettings.sound)) @@ -179,13 +194,15 @@ class QuasseldroidNotificationManager @Inject constructor(private val context: C } ) .addAction(0, translatedLocale.getString(R.string.label_mark_read), markReadPendingIntent) - .addAction( - NotificationCompat.Action.Builder( - 0, - translatedLocale.getString(R.string.label_reply), - replyPendingIntent - ).addRemoteInput(remoteInput).build() - ) + .letIf(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + it.addAction( + NotificationCompat.Action.Builder( + 0, + translatedLocale.getString(R.string.label_reply), + replyPendingIntent + ).addRemoteInput(remoteInput).build() + ) + } .setWhen(notifications.last().time.toEpochMilli()) .apply { if (bufferInfo.type.hasFlag(Buffer_Type.QueryBuffer)) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9e0cbfc0c3e431fc6333f21877d935b569c8a188..6ab72eed00a02e01e816110bc77cbd56259cb632 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -133,7 +133,9 @@ <string name="notification_channel_background" translatable="false">background</string> <string name="notification_channel_connection_title">Connection</string> <string name="notification_channel_highlight" translatable="false">highlight</string> - <string name="notification_channel_highlight_title">Highlight</string> + <string name="notification_channel_highlight_title">Highlights</string> + <string name="notification_channel_old_highlight" translatable="false">old_highlight</string> + <string name="notification_channel_old_highlight_title">Old Highlights</string> <string name="label_missing_features">Missing Features</string> <string name="info_missing_features">Your core is missing features that are required for Quasseldroid to work correctly.</string> diff --git a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/QuasselDatabase.kt b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/QuasselDatabase.kt index 94c20f52a712d5300f8f7c56cb7d22b12c77f71b..aff4e8abaa37b2374cd93a7f219a70ddb57c9534 100644 --- a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/QuasselDatabase.kt +++ b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/QuasselDatabase.kt @@ -32,7 +32,7 @@ import io.reactivex.Flowable import org.threeten.bp.Instant @Database(entities = [MessageData::class, Filtered::class, SslValidityWhitelistEntry::class, SslHostnameWhitelistEntry::class, NotificationData::class], - version = 15) + version = 16) @TypeConverters(MessageTypeConverter::class) abstract class QuasselDatabase : RoomDatabase() { abstract fun message(): MessageDao @@ -196,6 +196,7 @@ abstract class QuasselDatabase : RoomDatabase() { @Entity(tableName = "notification", indices = [Index("bufferId")]) data class NotificationData( @PrimaryKey var messageId: MsgId, + var creationTime: Instant, var time: Instant, var type: Message_Types, var flag: Message_Flags, @@ -212,7 +213,7 @@ abstract class QuasselDatabase : RoomDatabase() { @Dao interface NotificationDao { - @Insert(onConflict = OnConflictStrategy.REPLACE) + @Insert(onConflict = OnConflictStrategy.IGNORE) fun save(vararg entities: NotificationData) @Query("SELECT * FROM notification ORDER BY time ASC") @@ -325,6 +326,11 @@ abstract class QuasselDatabase : RoomDatabase() { override fun migrate(database: SupportSQLiteDatabase) { database.execSQL("ALTER TABLE message ADD networkId INT DEFAULT 0 NOT NULL;") } + }, + object : Migration(15, 16) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE `notification` ADD `creationTime` INT DEFAULT 0 NOT NULL;") + } } ).build() }