Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 16f6f0be authored by Guillaume Jacquart's avatar Guillaume Jacquart
Browse files

Merge branch '3192-full_notification_display' into 'main'

feat:3192,3194,3195,3197: display eOS notifications, block others

See merge request !20
parents 06824cd7 37a90e9e
Loading
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ plugins {
    id 'com.google.devtools.ksp'
    alias(libs.plugins.hilt.android)
    alias(libs.plugins.detekt)
    alias(libs.plugins.kotlin.compose)
}

repositories {
@@ -98,6 +99,10 @@ android {
            '-Xjvm-default=all-compatibility' // https://stackoverflow.com/a/71234042/1440785
        ]
    }

    buildFeatures {
        compose true
    }
}

// Disables GoogleServices tasks for F-Droid variant
@@ -130,6 +135,7 @@ dependencies {
    implementation(libs.dagger.hilt.android)
    ksp(libs.dagger.hilt.compiler)
    implementation(libs.eos.telemetry)
    implementation(libs.androidx.lifecycle.runtime.compose)

    // AndroidX, The Basics
    implementation "androidx.appcompat:appcompat:1.6.1"
@@ -198,9 +204,7 @@ detekt {

tasks.withType(io.gitlab.arturbosch.detekt.Detekt).configureEach {
    jvmTarget = "17"
  //  exclude("**/io/heckel/ntfy/**")
}
tasks.withType(io.gitlab.arturbosch.detekt.DetektCreateBaselineTask).configureEach {
    jvmTarget = "17"
    //exclude("**/io/heckel/ntfy/**")
}
+57 −0
Original line number Diff line number Diff line
package foundation.e.notificationsreceiver.repositories

import android.content.Context
import dagger.hilt.android.qualifiers.ApplicationContext
import foundation.e.notificationsreceiver.domain.entities.Message
import foundation.e.notificationsreceiver.domain.entities.Message.IconType
import foundation.e.notificationsreceiver.domain.entities.Topic
import foundation.e.notificationsreceiver.domain.repositories.MessagesRepository
import foundation.e.notificationsreceiver.domain.utils.runSuspendCatching
import io.heckel.ntfy.db.Database
import io.heckel.ntfy.db.NotificationDao
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext
import java.time.Instant
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class MessagesRepositoryImpl @Inject constructor(
    @ApplicationContext private val appContext: Context,

) : MessagesRepository {
    private val notificationsDao: NotificationDao

    init {
        val database = Database.getInstance(appContext)
        notificationsDao = database.notificationDao()
    }

    override fun messages(subscriptions: List<Topic>): Flow<List<Message>> {
        return notificationsDao.listFlow(subscriptions.map { it.localId }).map { notifications ->
            notifications.mapNotNull {
                with(it) {
                    runSuspendCatching {
                        Message(
                            id = id,
                            timestamp = Instant.ofEpochSecond(timestamp),
                            title = title,
                            content = message,
                            icon = IconType.EOS,
                            read = deleted,
                            notificationId = notificationId,
                        )
                    }.getOrNull()
                }
            }
        }
    }

    override suspend fun markAsRead(localId: String) {
        withContext(Dispatchers.IO) {
            notificationsDao.markAsDeleted(notificationId = localId)
        }
    }
}
+4 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import foundation.e.notificationsreceiver.domain.repositories.MessagesRepository
import foundation.e.notificationsreceiver.domain.repositories.SubscriptionsRepository

@InstallIn(SingletonComponent::class)
@@ -28,4 +29,7 @@ import foundation.e.notificationsreceiver.domain.repositories.SubscriptionsRepos
abstract class RepositoryModule {
    @Binds
    abstract fun bindSubscriptionsRepository(impl: SubscriptionsRepositoryImpl): SubscriptionsRepository

    @Binds
    abstract fun bindMessagesRepository(impl: MessagesRepositoryImpl): MessagesRepository
}
+34 −5
Original line number Diff line number Diff line
@@ -26,17 +26,22 @@ import io.heckel.ntfy.db.Database
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.Subscription
import io.heckel.ntfy.db.SubscriptionDao
import io.heckel.ntfy.db.SubscriptionWithMetadata
import io.heckel.ntfy.service.SubscriberServiceManager
import io.heckel.ntfy.util.randomSubscriptionId
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.Date
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.collections.map

@Singleton
class SubscriptionsRepositoryImpl @Inject constructor(
@@ -57,15 +62,19 @@ class SubscriptionsRepositoryImpl @Inject constructor(

    private var willRefreshSubscriptionJob: Job? = null

    override val subscriptions = subscriptionDao.listFlow().map { list ->
        list.map(::toTopic)
    }.shareIn(scope = backgroundScope, started = SharingStarted.Lazily)

    override fun getBaseUrl(): String {
        return repository.getDefaultBaseUrl() ?: appContext.getString(R.string.app_base_url)
    }

    override suspend fun getSubscriptions(): List<Topic> = withContext(Dispatchers.IO) {
        subscriptionDao.list().map { Topic(localId = it.id, baseUrl = it.baseUrl, topic = it.topic) }
        subscriptionDao.list().map(::toTopic)
    }

    override suspend fun subscribe(topic: Topic) = withContext(Dispatchers.IO) {
    override suspend fun createSubscription(topic: Topic) = withContext(Dispatchers.IO) {
        val subscription = Subscription(
            id = randomSubscriptionId(),
            baseUrl = topic.baseUrl,
@@ -74,7 +83,7 @@ class SubscriptionsRepositoryImpl @Inject constructor(
            dedicatedChannels = false,
            mutedUntil = 0,
            minPriority = Repository.MIN_PRIORITY_USE_GLOBAL,
            autoDelete = Repository.AUTO_DELETE_USE_GLOBAL,
            autoDelete = Repository.AUTO_DELETE_NEVER,
            insistent = Repository.INSISTENT_MAX_PRIORITY_USE_GLOBAL,
            lastNotificationId = null,
            icon = null,
@@ -90,11 +99,31 @@ class SubscriptionsRepositoryImpl @Inject constructor(
        debouncedRefreshSubscriptions()
    }

    override suspend fun unsubscribe(topic: Topic): Unit = withContext(Dispatchers.IO) {
        subscriptionDao.remove(topic.localId)
    override suspend fun deactivateSubscription(topic: Topic) {
        withContext(Dispatchers.IO) {
            subscriptionDao.setEnabled(topic.localId, false)
        }
        debouncedRefreshSubscriptions()
    }

    override suspend fun reactivateSubscription(topic: Topic) {
        withContext(Dispatchers.IO) {
            subscriptionDao.setEnabled(topic.localId, true)
        }
        debouncedRefreshSubscriptions()
    }

    private fun toTopic(subscription: SubscriptionWithMetadata): Topic {
        with(subscription) {
            return Topic(
                localId = id,
                baseUrl = baseUrl,
                topic = topic,
                enabled = instant,
            )
        }
    }

    private fun debouncedRefreshSubscriptions() {
        willRefreshSubscriptionJob?.cancel()

+5 −0
Original line number Diff line number Diff line
@@ -2,9 +2,11 @@ package io.heckel.ntfy.app

import android.app.Application
import dagger.hilt.android.HiltAndroidApp
import foundation.e.notificationsreceiver.ui.NotificationsPresenter
import foundation.e.notificationsreceiver.utils.ETelemetryLogger
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.util.Log
import javax.inject.Inject

@HiltAndroidApp
class Application : Application() {
@@ -16,8 +18,11 @@ class Application : Application() {
        repository
    }

    @Inject lateinit var notificationsPresenter: NotificationsPresenter

    override fun onCreate() {
        super.onCreate()
        ETelemetryLogger().initializeAsLoggerImplementation(this)
        notificationsPresenter.listen()
    }
}
Loading