mirror of
https://github.com/twofas/2fas-android.git
synced 2024-11-27 20:59:52 +01:00
Implement internal periodic notifications
This commit is contained in:
parent
9c12a99460
commit
13721cdab9
296
app/schemas/com.twofasapp.storage.AppDatabase/13.json
Normal file
296
app/schemas/com.twofasapp.storage.AppDatabase/13.json
Normal file
@ -0,0 +1,296 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 13,
|
||||
"identityHash": "00659315e21cc36273e2fcd4ae35ce93",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "local_services",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `secret` TEXT NOT NULL, `serviceTypeId` TEXT, `iconCollectionId` TEXT, `source` TEXT, `otpLink` TEXT, `otpLabel` TEXT, `otpAccount` TEXT, `otpIssuer` TEXT, `otpDigits` INTEGER, `otpPeriod` INTEGER, `otpAlgorithm` TEXT, `backupSyncStatus` TEXT NOT NULL, `updatedAt` INTEGER NOT NULL, `badgeColor` TEXT, `selectedImageType` TEXT, `labelText` TEXT, `labelBackgroundColor` TEXT, `groupId` TEXT, `isDeleted` INTEGER, `authType` TEXT, `hotpCounter` INTEGER, `hotpCounterTimestamp` INTEGER, `revealTimestamp` INTEGER, `assignedDomains` TEXT)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "name",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "secret",
|
||||
"columnName": "secret",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "serviceTypeId",
|
||||
"columnName": "serviceTypeId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "iconCollectionId",
|
||||
"columnName": "iconCollectionId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "source",
|
||||
"columnName": "source",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "otpLink",
|
||||
"columnName": "otpLink",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "otpLabel",
|
||||
"columnName": "otpLabel",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "otpAccount",
|
||||
"columnName": "otpAccount",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "otpIssuer",
|
||||
"columnName": "otpIssuer",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "otpDigits",
|
||||
"columnName": "otpDigits",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "otpPeriod",
|
||||
"columnName": "otpPeriod",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "otpAlgorithm",
|
||||
"columnName": "otpAlgorithm",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "backupSyncStatus",
|
||||
"columnName": "backupSyncStatus",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "updatedAt",
|
||||
"columnName": "updatedAt",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "badgeColor",
|
||||
"columnName": "badgeColor",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "selectedImageType",
|
||||
"columnName": "selectedImageType",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "labelText",
|
||||
"columnName": "labelText",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "labelBackgroundColor",
|
||||
"columnName": "labelBackgroundColor",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "groupId",
|
||||
"columnName": "groupId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "isDeleted",
|
||||
"columnName": "isDeleted",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "authType",
|
||||
"columnName": "authType",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "hotpCounter",
|
||||
"columnName": "hotpCounter",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "hotpCounterTimestamp",
|
||||
"columnName": "hotpCounterTimestamp",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "revealTimestamp",
|
||||
"columnName": "revealTimestamp",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "assignedDomains",
|
||||
"columnName": "assignedDomains",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": true,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "paired_browsers",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `extensionPublicKey` TEXT NOT NULL, `pairedAt` INTEGER NOT NULL, PRIMARY KEY(`id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "name",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "extensionPublicKey",
|
||||
"columnName": "extensionPublicKey",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pairedAt",
|
||||
"columnName": "pairedAt",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "notifications",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `category` TEXT NOT NULL, `link` TEXT NOT NULL, `message` TEXT NOT NULL, `publishTime` INTEGER NOT NULL, `push` INTEGER NOT NULL, `platform` TEXT NOT NULL, `isRead` INTEGER NOT NULL, `periodicType` TEXT, `internalRoute` TEXT, PRIMARY KEY(`id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "category",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "link",
|
||||
"columnName": "link",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "message",
|
||||
"columnName": "message",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "publishTime",
|
||||
"columnName": "publishTime",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "push",
|
||||
"columnName": "push",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "platform",
|
||||
"columnName": "platform",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "isRead",
|
||||
"columnName": "isRead",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "periodicType",
|
||||
"columnName": "periodicType",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "internalRoute",
|
||||
"columnName": "internalRoute",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '00659315e21cc36273e2fcd4ae35ce93')"
|
||||
]
|
||||
}
|
||||
}
|
@ -31,12 +31,13 @@ import java.text.Normalizer
|
||||
autoMigrations = [
|
||||
AutoMigration(from = 7, to = 8),
|
||||
AutoMigration(from = 8, to = 9),
|
||||
AutoMigration(from = 12, to = 13),
|
||||
]
|
||||
)
|
||||
@TypeConverters(Converters::class)
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
companion object {
|
||||
const val DB_VERSION = 12
|
||||
const val DB_VERSION = 13
|
||||
}
|
||||
|
||||
abstract fun serviceDao(): ServiceDao
|
||||
|
@ -10,8 +10,9 @@ import com.twofasapp.base.lifecycle.AuthAware
|
||||
import com.twofasapp.base.lifecycle.AuthLifecycle
|
||||
import com.twofasapp.data.session.SettingsRepository
|
||||
import com.twofasapp.designsystem.AppThemeState
|
||||
import com.twofasapp.workmanager.SyncTimeWorkDispatcher
|
||||
import com.twofasapp.workmanager.OnAppStartWork
|
||||
import com.twofasapp.workmanager.OnAppUpdatedWorkDispatcher
|
||||
import com.twofasapp.workmanager.SyncTimeWorkDispatcher
|
||||
import org.koin.android.ext.android.get
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koin.core.parameter.parametersOf
|
||||
@ -32,6 +33,7 @@ class StartActivity : AppCompatActivity(), AuthAware {
|
||||
|
||||
onAppUpdatedWorkDispatcher.dispatch()
|
||||
syncTimeWorkDispatcher.dispatch()
|
||||
OnAppStartWork.dispatch(this)
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
authTracker.onSplashScreen()
|
||||
|
165
app/src/main/java/com/twofasapp/workmanager/OnAppStartWork.kt
Normal file
165
app/src/main/java/com/twofasapp/workmanager/OnAppStartWork.kt
Normal file
@ -0,0 +1,165 @@
|
||||
package com.twofasapp.workmanager
|
||||
|
||||
import android.content.Context
|
||||
import androidx.work.CoroutineWorker
|
||||
import androidx.work.ExistingWorkPolicy
|
||||
import androidx.work.OneTimeWorkRequest
|
||||
import androidx.work.OneTimeWorkRequestBuilder
|
||||
import androidx.work.WorkManager
|
||||
import androidx.work.WorkerParameters
|
||||
import com.twofasapp.android.navigation.Screen
|
||||
import com.twofasapp.data.browserext.BrowserExtRepository
|
||||
import com.twofasapp.data.notifications.NotificationsRepository
|
||||
import com.twofasapp.data.notifications.domain.Notification
|
||||
import com.twofasapp.data.notifications.domain.PeriodicNotificationType
|
||||
import com.twofasapp.data.services.BackupRepository
|
||||
import com.twofasapp.data.services.ServicesRepository
|
||||
import com.twofasapp.data.session.SessionRepository
|
||||
import kotlinx.coroutines.flow.first
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
import timber.log.Timber
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
import java.util.UUID
|
||||
|
||||
class OnAppStartWork(
|
||||
private val context: Context,
|
||||
params: WorkerParameters,
|
||||
) : CoroutineWorker(context, params), KoinComponent {
|
||||
|
||||
companion object {
|
||||
fun dispatch(context: Context) {
|
||||
val request: OneTimeWorkRequest = OneTimeWorkRequestBuilder<OnAppStartWork>()
|
||||
.build()
|
||||
|
||||
Timber.d("Append new OnAppStartWork")
|
||||
WorkManager.getInstance(context)
|
||||
.enqueueUniqueWork("OnAppStartWork", ExistingWorkPolicy.APPEND_OR_REPLACE, request)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private val sessionRepository: SessionRepository by inject()
|
||||
private val notificationsRepository: NotificationsRepository by inject()
|
||||
private val backupRepository: BackupRepository by inject()
|
||||
private val servicesRepository: ServicesRepository by inject()
|
||||
private val browserExtRepository: BrowserExtRepository by inject()
|
||||
|
||||
override suspend fun doWork(): Result {
|
||||
checkPeriodicNotifications()
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
private suspend fun checkPeriodicNotifications() {
|
||||
if (sessionRepository.isOnboardingDisplayed().not()) {
|
||||
Timber.d("This is first app launch -> do nothing")
|
||||
// This is first app launch -> do nothing
|
||||
return
|
||||
}
|
||||
|
||||
val n = notificationsRepository.getPeriodicNotificationCounter()
|
||||
val timestampMillis = notificationsRepository.getPeriodicNotificationTimestamp()
|
||||
val timestamp = Instant.ofEpochMilli(timestampMillis)
|
||||
val now = Instant.now()
|
||||
|
||||
Timber.d("n = $n")
|
||||
|
||||
if (timestampMillis != 0L && now.isBefore(timestamp.plusSeconds(Duration.ofDays(30).toSeconds()))) {
|
||||
Timber.d("Less than 30 days")
|
||||
// Finish when last notification was triggered less than 30 days ago
|
||||
return
|
||||
}
|
||||
|
||||
val notificationToShow = when (n) {
|
||||
-1 -> PeriodicNotificationType.TipsAndTricks
|
||||
0 -> PeriodicNotificationType.Backup
|
||||
1 -> PeriodicNotificationType.BrowserExtension
|
||||
2 -> PeriodicNotificationType.Donate
|
||||
else -> return
|
||||
}
|
||||
|
||||
showNotification(notificationToShow)
|
||||
|
||||
notificationsRepository.setPeriodicNotificationCounter(if (n == 2) 0 else n + 1)
|
||||
notificationsRepository.setPeriodicNotificationTimestamp(now.toEpochMilli())
|
||||
}
|
||||
|
||||
private suspend fun showNotification(type: PeriodicNotificationType) {
|
||||
Timber.d("Show notification: $type")
|
||||
notificationsRepository.clearPeriodicNotifications()
|
||||
|
||||
when (type) {
|
||||
PeriodicNotificationType.TipsAndTricks -> {
|
||||
notificationsRepository.insertPeriodicNotification(
|
||||
type = type,
|
||||
notification = createPeriodicNotification(
|
||||
category = Notification.Category.Youtube,
|
||||
message = context.getString(com.twofasapp.locale.R.string.periodic_notification_tips),
|
||||
link = "https://2fas.com/2fasauth-tutorial",
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
PeriodicNotificationType.Backup -> {
|
||||
if (servicesRepository.getServices().isNotEmpty() && backupRepository.observeCloudBackupStatus().first().active.not()) {
|
||||
// User has services but backup is inactive
|
||||
notificationsRepository.insertPeriodicNotification(
|
||||
type = type,
|
||||
notification = createPeriodicNotification(
|
||||
category = Notification.Category.Updates,
|
||||
message = context.getString(com.twofasapp.locale.R.string.periodic_notification_backup),
|
||||
link = "",
|
||||
internalRoute = Screen.Backup.route,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
PeriodicNotificationType.BrowserExtension -> {
|
||||
if (servicesRepository.getServices().isNotEmpty() && browserExtRepository.observePairedBrowsers().first().isEmpty()) {
|
||||
notificationsRepository.insertPeriodicNotification(
|
||||
type = type,
|
||||
notification = createPeriodicNotification(
|
||||
category = Notification.Category.News,
|
||||
message = context.getString(com.twofasapp.locale.R.string.periodic_notification_browser_extension),
|
||||
link = "https://2fas.com/browser-extension/",
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
PeriodicNotificationType.Donate -> {
|
||||
if (servicesRepository.getServices().isNotEmpty()) {
|
||||
notificationsRepository.insertPeriodicNotification(
|
||||
type = type,
|
||||
notification = createPeriodicNotification(
|
||||
category = Notification.Category.Features,
|
||||
message = context.getString(com.twofasapp.locale.R.string.periodic_notification_donate),
|
||||
link = "https://2fas.com/donate/",
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createPeriodicNotification(
|
||||
category: Notification.Category,
|
||||
message: String,
|
||||
link: String,
|
||||
internalRoute: String? = null,
|
||||
): Notification {
|
||||
return Notification(
|
||||
id = UUID.randomUUID().toString(),
|
||||
category = category,
|
||||
link = link,
|
||||
message = message,
|
||||
publishTime = Instant.now().toEpochMilli(),
|
||||
push = false,
|
||||
platform = "android",
|
||||
isRead = false,
|
||||
internalRoute = internalRoute,
|
||||
)
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
Release: Working copy
|
||||
Locale: de-DE, German (Germany)
|
||||
Exported by: rafakob
|
||||
Exported at: Thu, 21 Dec 2023 12:34:52 -0800
|
||||
Exported at: Sun, 07 Jan 2024 11:57:56 -0800
|
||||
-->
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<!-- InfoPlist.strings
|
||||
@ -824,4 +824,8 @@
|
||||
<string name="settings__manage_tokens">Token verwalten</string>
|
||||
<string name="settings__info_footer">Deine Unterstützung ermöglicht uns die Entwicklung neuer Funktionen und Verbesserungen. Danke dir!</string>
|
||||
<string name="settings__trash_option">Wiederherstellen aus dem Papierkorb</string>
|
||||
<string name="periodic_notification_tips">Schön, dass du bei 2FAS dabei bist! 🌟 Nimm dir einen Moment Zeit, um hilfreiche Tipps & Tricks 🛠️ in der App für mehr Sicherheit zu entdecken 🔒.</string>
|
||||
<string name="periodic_notification_backup">Aktiviere 2FAS Backup & Sync, um sicherzustellen, dass du nie ausgesperrt wirst, selbst wenn du dein Telefon verlierst - Dein Seelenfrieden mit einem Fingertipp! 🔐📱</string>
|
||||
<string name="periodic_notification_browser_extension">Beschleunige deine Anmeldungen mit der 2FAS-Browsererweiterung! 🚀 Jetzt herunterladen für eine schnellere und bequemere Authentifizierung. 🌐✨</string>
|
||||
<string name="periodic_notification_donate">Wir sind dankbar für deine Unterstützung von 2FAS! 🌟 Wenn du unsere App hilfreich findest, ziehe eine Spende in Betracht, um uns zu helfen, deine digitale Welt sicher zu halten. Jedes bisschen hilft! 🙏💙</string>
|
||||
</resources>
|
||||
|
@ -5,7 +5,7 @@
|
||||
Release: Working copy
|
||||
Locale: es-ES, Spanish (Spain)
|
||||
Exported by: rafakob
|
||||
Exported at: Thu, 21 Dec 2023 12:34:52 -0800
|
||||
Exported at: Sun, 07 Jan 2024 11:57:56 -0800
|
||||
-->
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<!-- InfoPlist.strings
|
||||
@ -824,4 +824,8 @@
|
||||
<string name="settings__manage_tokens">Gestionar tokens</string>
|
||||
<string name="settings__info_footer">Tu apoyo nos permite desarrollar nuevas características y mejoras. ¡Gracias!</string>
|
||||
<string name="settings__trash_option">Recuperar de la papelera</string>
|
||||
<string name="periodic_notification_tips">Glad you\'re with us at 2FAS! 🌟 Take a moment to discover helpful Tips & Tricks 🛠️ in the app for enhanced security 🔒.</string>
|
||||
<string name="periodic_notification_backup">Enable 2FAS Backup & Sync to ensure you never get locked out, even if you lose your phone - your peace of mind in one tap! 🔐📱</string>
|
||||
<string name="periodic_notification_browser_extension">Speed up your logins with the 2FAS Browser Extension! 🚀 Download now for a faster, more convenient authentication. 🌐✨</string>
|
||||
<string name="periodic_notification_donate">We\'re grateful for your support of 2FAS! 🌟 If you find our app helpful, consider making a donation to help us keep your digital world secure. Every bit helps! 🙏💙</string>
|
||||
</resources>
|
||||
|
@ -5,7 +5,7 @@
|
||||
Release: Working copy
|
||||
Locale: fr-FR, French (France)
|
||||
Exported by: rafakob
|
||||
Exported at: Thu, 21 Dec 2023 12:34:52 -0800
|
||||
Exported at: Sun, 07 Jan 2024 11:57:56 -0800
|
||||
-->
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<!-- InfoPlist.strings
|
||||
@ -824,4 +824,8 @@
|
||||
<string name="settings__manage_tokens">Gérer les jetons</string>
|
||||
<string name="settings__info_footer">Votre soutien nous permet de développer de nouvelles fonctionnalités et\naméliorations. Merci!</string>
|
||||
<string name="settings__trash_option">Récupérer de la corbeille</string>
|
||||
<string name="periodic_notification_tips">Glad you\'re with us at 2FAS! 🌟 Take a moment to discover helpful Tips & Tricks 🛠️ in the app for enhanced security 🔒.</string>
|
||||
<string name="periodic_notification_backup">Enable 2FAS Backup & Sync to ensure you never get locked out, even if you lose your phone - your peace of mind in one tap! 🔐📱</string>
|
||||
<string name="periodic_notification_browser_extension">Speed up your logins with the 2FAS Browser Extension! 🚀 Download now for a faster, more convenient authentication. 🌐✨</string>
|
||||
<string name="periodic_notification_donate">We\'re grateful for your support of 2FAS! 🌟 If you find our app helpful, consider making a donation to help us keep your digital world secure. Every bit helps! 🙏💙</string>
|
||||
</resources>
|
||||
|
@ -5,7 +5,7 @@
|
||||
Release: Working copy
|
||||
Locale: id-ID, Indonesian (Indonesia)
|
||||
Exported by: rafakob
|
||||
Exported at: Thu, 21 Dec 2023 12:34:52 -0800
|
||||
Exported at: Sun, 07 Jan 2024 11:57:56 -0800
|
||||
-->
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<!-- InfoPlist.strings
|
||||
@ -818,4 +818,8 @@
|
||||
<string name="settings__manage_tokens">Mengelola token</string>
|
||||
<string name="settings__info_footer">Dukungan Anda memungkinkan kami untuk mengembangkan fitur-fitur baru dan\nperbaikan. Terima kasih!</string>
|
||||
<string name="settings__trash_option">Ambil dari tempat sampah</string>
|
||||
<string name="periodic_notification_tips">Glad you\'re with us at 2FAS! 🌟 Take a moment to discover helpful Tips & Tricks 🛠️ in the app for enhanced security 🔒.</string>
|
||||
<string name="periodic_notification_backup">Enable 2FAS Backup & Sync to ensure you never get locked out, even if you lose your phone - your peace of mind in one tap! 🔐📱</string>
|
||||
<string name="periodic_notification_browser_extension">Speed up your logins with the 2FAS Browser Extension! 🚀 Download now for a faster, more convenient authentication. 🌐✨</string>
|
||||
<string name="periodic_notification_donate">We\'re grateful for your support of 2FAS! 🌟 If you find our app helpful, consider making a donation to help us keep your digital world secure. Every bit helps! 🙏💙</string>
|
||||
</resources>
|
||||
|
@ -5,7 +5,7 @@
|
||||
Release: Working copy
|
||||
Locale: it-IT, Italian (Italy)
|
||||
Exported by: rafakob
|
||||
Exported at: Thu, 21 Dec 2023 12:34:52 -0800
|
||||
Exported at: Sun, 07 Jan 2024 11:57:56 -0800
|
||||
-->
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<!-- InfoPlist.strings
|
||||
@ -824,4 +824,8 @@
|
||||
<string name="settings__manage_tokens">Gestisci i token</string>
|
||||
<string name="settings__info_footer">Il tuo supporto ci permette di sviluppare nuove funzionalità e miglioramenti. Grazie!</string>
|
||||
<string name="settings__trash_option">Ripristina dal cestino</string>
|
||||
<string name="periodic_notification_tips">Glad you\'re with us at 2FAS! 🌟 Take a moment to discover helpful Tips & Tricks 🛠️ in the app for enhanced security 🔒.</string>
|
||||
<string name="periodic_notification_backup">Enable 2FAS Backup & Sync to ensure you never get locked out, even if you lose your phone - your peace of mind in one tap! 🔐📱</string>
|
||||
<string name="periodic_notification_browser_extension">Speed up your logins with the 2FAS Browser Extension! 🚀 Download now for a faster, more convenient authentication. 🌐✨</string>
|
||||
<string name="periodic_notification_donate">We\'re grateful for your support of 2FAS! 🌟 If you find our app helpful, consider making a donation to help us keep your digital world secure. Every bit helps! 🙏💙</string>
|
||||
</resources>
|
||||
|
@ -5,7 +5,7 @@
|
||||
Release: Working copy
|
||||
Locale: nl-NL, Dutch (Netherlands)
|
||||
Exported by: rafakob
|
||||
Exported at: Thu, 21 Dec 2023 12:34:52 -0800
|
||||
Exported at: Sun, 07 Jan 2024 11:57:56 -0800
|
||||
-->
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<!-- InfoPlist.strings
|
||||
@ -824,4 +824,8 @@
|
||||
<string name="settings__manage_tokens">Tokens beheren</string>
|
||||
<string name="settings__info_footer">Dankzij uw steun kunnen we nieuwe functies en\nverbeteringen. Hartelijk dank!</string>
|
||||
<string name="settings__trash_option">Ophalen uit prullenbak</string>
|
||||
<string name="periodic_notification_tips">Glad you\'re with us at 2FAS! 🌟 Take a moment to discover helpful Tips & Tricks 🛠️ in the app for enhanced security 🔒.</string>
|
||||
<string name="periodic_notification_backup">Enable 2FAS Backup & Sync to ensure you never get locked out, even if you lose your phone - your peace of mind in one tap! 🔐📱</string>
|
||||
<string name="periodic_notification_browser_extension">Speed up your logins with the 2FAS Browser Extension! 🚀 Download now for a faster, more convenient authentication. 🌐✨</string>
|
||||
<string name="periodic_notification_donate">We\'re grateful for your support of 2FAS! 🌟 If you find our app helpful, consider making a donation to help us keep your digital world secure. Every bit helps! 🙏💙</string>
|
||||
</resources>
|
||||
|
@ -5,7 +5,7 @@
|
||||
Release: Working copy
|
||||
Locale: pl-PL, Polish (Poland)
|
||||
Exported by: rafakob
|
||||
Exported at: Thu, 21 Dec 2023 12:34:52 -0800
|
||||
Exported at: Sun, 07 Jan 2024 11:57:56 -0800
|
||||
-->
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<!-- InfoPlist.strings
|
||||
@ -830,4 +830,8 @@
|
||||
<string name="settings__manage_tokens">Zarządzaj tokenami</string>
|
||||
<string name="settings__info_footer">Twoje wsparcie pozwala nam rozwijać nowe funkcje i ulepszać aplikację. Dziękujemy!</string>
|
||||
<string name="settings__trash_option">Przywróć z kosza</string>
|
||||
<string name="periodic_notification_tips">Glad you\'re with us at 2FAS! 🌟 Take a moment to discover helpful Tips & Tricks 🛠️ in the app for enhanced security 🔒.</string>
|
||||
<string name="periodic_notification_backup">Enable 2FAS Backup & Sync to ensure you never get locked out, even if you lose your phone - your peace of mind in one tap! 🔐📱</string>
|
||||
<string name="periodic_notification_browser_extension">Speed up your logins with the 2FAS Browser Extension! 🚀 Download now for a faster, more convenient authentication. 🌐✨</string>
|
||||
<string name="periodic_notification_donate">We\'re grateful for your support of 2FAS! 🌟 If you find our app helpful, consider making a donation to help us keep your digital world secure. Every bit helps! 🙏💙</string>
|
||||
</resources>
|
||||
|
@ -5,7 +5,7 @@
|
||||
Release: Working copy
|
||||
Locale: pt-BR, Brazilian Portuguese
|
||||
Exported by: rafakob
|
||||
Exported at: Thu, 21 Dec 2023 12:34:52 -0800
|
||||
Exported at: Sun, 07 Jan 2024 11:57:56 -0800
|
||||
-->
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<!-- InfoPlist.strings
|
||||
@ -824,4 +824,8 @@
|
||||
<string name="settings__manage_tokens">Gerenciar tokens</string>
|
||||
<string name="settings__info_footer">O seu apoio nos permite desenvolver novas funcionalidades e melhorias. Obrigado!\n\n\n\n\n\n</string>
|
||||
<string name="settings__trash_option">Recuperar da lixeira</string>
|
||||
<string name="periodic_notification_tips">Glad you\'re with us at 2FAS! 🌟 Take a moment to discover helpful Tips & Tricks 🛠️ in the app for enhanced security 🔒.</string>
|
||||
<string name="periodic_notification_backup">Enable 2FAS Backup & Sync to ensure you never get locked out, even if you lose your phone - your peace of mind in one tap! 🔐📱</string>
|
||||
<string name="periodic_notification_browser_extension">Speed up your logins with the 2FAS Browser Extension! 🚀 Download now for a faster, more convenient authentication. 🌐✨</string>
|
||||
<string name="periodic_notification_donate">We\'re grateful for your support of 2FAS! 🌟 If you find our app helpful, consider making a donation to help us keep your digital world secure. Every bit helps! 🙏💙</string>
|
||||
</resources>
|
||||
|
@ -5,7 +5,7 @@
|
||||
Release: Working copy
|
||||
Locale: pt-PT, Portuguese (Portugal)
|
||||
Exported by: rafakob
|
||||
Exported at: Thu, 21 Dec 2023 12:34:52 -0800
|
||||
Exported at: Sun, 07 Jan 2024 11:57:56 -0800
|
||||
-->
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<!-- InfoPlist.strings
|
||||
@ -824,4 +824,8 @@
|
||||
<string name="settings__manage_tokens">Manage tokens</string>
|
||||
<string name="settings__info_footer">Your support allows us to develop new features and\nimprovements. Thank you!</string>
|
||||
<string name="settings__trash_option">Retrieve from trash</string>
|
||||
<string name="periodic_notification_tips">Glad you\'re with us at 2FAS! 🌟 Take a moment to discover helpful Tips & Tricks 🛠️ in the app for enhanced security 🔒.</string>
|
||||
<string name="periodic_notification_backup">Enable 2FAS Backup & Sync to ensure you never get locked out, even if you lose your phone - your peace of mind in one tap! 🔐📱</string>
|
||||
<string name="periodic_notification_browser_extension">Speed up your logins with the 2FAS Browser Extension! 🚀 Download now for a faster, more convenient authentication. 🌐✨</string>
|
||||
<string name="periodic_notification_donate">We\'re grateful for your support of 2FAS! 🌟 If you find our app helpful, consider making a donation to help us keep your digital world secure. Every bit helps! 🙏💙</string>
|
||||
</resources>
|
||||
|
@ -5,7 +5,7 @@
|
||||
Release: Working copy
|
||||
Locale: tr-TR, Turkish (Turkey)
|
||||
Exported by: rafakob
|
||||
Exported at: Thu, 21 Dec 2023 12:34:52 -0800
|
||||
Exported at: Sun, 07 Jan 2024 11:57:56 -0800
|
||||
-->
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<!-- InfoPlist.strings
|
||||
@ -824,4 +824,8 @@
|
||||
<string name="settings__manage_tokens">Jetonları yönetin</string>
|
||||
<string name="settings__info_footer">Desteğiniz yeni özellikler geliştirmemize ve\niyileştirmeler. Teşekkür ederim!</string>
|
||||
<string name="settings__trash_option">Çöp kutusundan al</string>
|
||||
<string name="periodic_notification_tips">Glad you\'re with us at 2FAS! 🌟 Take a moment to discover helpful Tips & Tricks 🛠️ in the app for enhanced security 🔒.</string>
|
||||
<string name="periodic_notification_backup">Enable 2FAS Backup & Sync to ensure you never get locked out, even if you lose your phone - your peace of mind in one tap! 🔐📱</string>
|
||||
<string name="periodic_notification_browser_extension">Speed up your logins with the 2FAS Browser Extension! 🚀 Download now for a faster, more convenient authentication. 🌐✨</string>
|
||||
<string name="periodic_notification_donate">We\'re grateful for your support of 2FAS! 🌟 If you find our app helpful, consider making a donation to help us keep your digital world secure. Every bit helps! 🙏💙</string>
|
||||
</resources>
|
||||
|
@ -5,7 +5,7 @@
|
||||
Release: Working copy
|
||||
Locale: uk-UA, Ukrainian (Ukraine)
|
||||
Exported by: rafakob
|
||||
Exported at: Thu, 21 Dec 2023 12:34:52 -0800
|
||||
Exported at: Sun, 07 Jan 2024 11:57:56 -0800
|
||||
-->
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<!-- InfoPlist.strings
|
||||
@ -830,4 +830,8 @@
|
||||
<string name="settings__manage_tokens">Manage tokens</string>
|
||||
<string name="settings__info_footer">Your support allows us to develop new features and\nimprovements. Thank you!</string>
|
||||
<string name="settings__trash_option">Retrieve from trash</string>
|
||||
<string name="periodic_notification_tips">Glad you\'re with us at 2FAS! 🌟 Take a moment to discover helpful Tips & Tricks 🛠️ in the app for enhanced security 🔒.</string>
|
||||
<string name="periodic_notification_backup">Enable 2FAS Backup & Sync to ensure you never get locked out, even if you lose your phone - your peace of mind in one tap! 🔐📱</string>
|
||||
<string name="periodic_notification_browser_extension">Speed up your logins with the 2FAS Browser Extension! 🚀 Download now for a faster, more convenient authentication. 🌐✨</string>
|
||||
<string name="periodic_notification_donate">We\'re grateful for your support of 2FAS! 🌟 If you find our app helpful, consider making a donation to help us keep your digital world secure. Every bit helps! 🙏💙</string>
|
||||
</resources>
|
||||
|
@ -5,7 +5,7 @@
|
||||
Release: Working copy
|
||||
Locale: en, English
|
||||
Exported by: rafakob
|
||||
Exported at: Thu, 21 Dec 2023 12:34:52 -0800
|
||||
Exported at: Sun, 07 Jan 2024 11:57:56 -0800
|
||||
-->
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<!-- InfoPlist.strings
|
||||
@ -824,4 +824,8 @@
|
||||
<string name="settings__manage_tokens">Manage tokens</string>
|
||||
<string name="settings__info_footer">Your support allows us to develop new features and\nimprovements. Thank you!</string>
|
||||
<string name="settings__trash_option">Retrieve from trash</string>
|
||||
<string name="periodic_notification_tips">Glad you\'re with us at 2FAS! 🌟 Take a moment to discover helpful Tips & Tricks 🛠️ in the app for enhanced security 🔒.</string>
|
||||
<string name="periodic_notification_backup">Enable 2FAS Backup & Sync to ensure you never get locked out, even if you lose your phone - your peace of mind in one tap! 🔐📱</string>
|
||||
<string name="periodic_notification_browser_extension">Speed up your logins with the 2FAS Browser Extension! 🚀 Download now for a faster, more convenient authentication. 🌐✨</string>
|
||||
<string name="periodic_notification_donate">We\'re grateful for your support of 2FAS! 🌟 If you find our app helpful, consider making a donation to help us keep your digital world secure. Every bit helps! 🙏💙</string>
|
||||
</resources>
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.twofasapp.data.notifications
|
||||
|
||||
import com.twofasapp.data.notifications.domain.Notification
|
||||
import com.twofasapp.data.notifications.domain.PeriodicNotificationType
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface NotificationsRepository {
|
||||
@ -8,4 +9,10 @@ interface NotificationsRepository {
|
||||
suspend fun fetchNotifications(sinceMillis: Long)
|
||||
suspend fun readAllNotifications()
|
||||
fun hasUnreadNotifications(): Flow<Boolean>
|
||||
suspend fun getPeriodicNotificationCounter(): Int
|
||||
suspend fun setPeriodicNotificationCounter(counter: Int)
|
||||
suspend fun getPeriodicNotificationTimestamp(): Long
|
||||
suspend fun setPeriodicNotificationTimestamp(timestamp: Long)
|
||||
suspend fun clearPeriodicNotifications()
|
||||
suspend fun insertPeriodicNotification(type: PeriodicNotificationType, notification: Notification)
|
||||
}
|
@ -2,6 +2,7 @@ package com.twofasapp.data.notifications
|
||||
|
||||
import com.twofasapp.common.coroutines.Dispatchers
|
||||
import com.twofasapp.data.notifications.domain.Notification
|
||||
import com.twofasapp.data.notifications.domain.PeriodicNotificationType
|
||||
import com.twofasapp.data.notifications.local.NotificationsLocalSource
|
||||
import com.twofasapp.data.notifications.mappper.asDomain
|
||||
import com.twofasapp.data.notifications.remote.NotificationsRemoteSource
|
||||
@ -47,4 +48,40 @@ internal class NotificationsRepositoryImpl(
|
||||
private fun List<Notification>.sortedByTime(): List<Notification> {
|
||||
return sortedWith(compareBy({ it.isRead }, { it.publishTime.unaryMinus() }))
|
||||
}
|
||||
|
||||
override suspend fun getPeriodicNotificationCounter(): Int {
|
||||
return withContext(dispatchers.io) {
|
||||
local.getPeriodicNotificationCounter()
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun setPeriodicNotificationCounter(counter: Int) {
|
||||
withContext(dispatchers.io) {
|
||||
local.setPeriodicNotificationCounter(counter)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getPeriodicNotificationTimestamp(): Long {
|
||||
return withContext(dispatchers.io) {
|
||||
local.getPeriodicNotificationTimestamp()
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun setPeriodicNotificationTimestamp(timestamp: Long) {
|
||||
withContext(dispatchers.io) {
|
||||
local.setPeriodicNotificationTimestamp(timestamp)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun clearPeriodicNotifications() {
|
||||
withContext(dispatchers.io) {
|
||||
local.clearPeriodicNotifications()
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun insertPeriodicNotification(type: PeriodicNotificationType, notification: Notification) {
|
||||
withContext(dispatchers.io) {
|
||||
local.insertPeriodicNotification(type, notification)
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ data class Notification(
|
||||
val id: String,
|
||||
val category: Category,
|
||||
val link: String,
|
||||
val internalRoute: String?,
|
||||
val message: String,
|
||||
val publishTime: Long,
|
||||
val push: Boolean,
|
||||
|
@ -0,0 +1,9 @@
|
||||
package com.twofasapp.data.notifications.domain
|
||||
|
||||
enum class PeriodicNotificationType {
|
||||
TipsAndTricks,
|
||||
Backup,
|
||||
BrowserExtension,
|
||||
Donate,
|
||||
;
|
||||
}
|
@ -1,6 +1,11 @@
|
||||
package com.twofasapp.data.notifications.local
|
||||
|
||||
import androidx.room.*
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import androidx.room.Update
|
||||
import com.twofasapp.data.notifications.local.model.NotificationEntity
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@ -44,6 +49,9 @@ interface NotificationsDao {
|
||||
@Query("DELETE FROM notifications WHERE id IN (:ids)")
|
||||
fun delete(ids: List<String>)
|
||||
|
||||
@Query("DELETE FROM notifications")
|
||||
@Query("DELETE FROM notifications WHERE periodicType IS NOT NULL")
|
||||
fun deleteAllPeriodic()
|
||||
|
||||
@Query("DELETE FROM notifications WHERE periodicType IS NULL")
|
||||
fun deleteAll()
|
||||
}
|
@ -1,15 +1,23 @@
|
||||
package com.twofasapp.data.notifications.local
|
||||
|
||||
import com.twofasapp.data.notifications.domain.Notification
|
||||
import com.twofasapp.data.notifications.domain.PeriodicNotificationType
|
||||
import com.twofasapp.data.notifications.mappper.asDomain
|
||||
import com.twofasapp.data.notifications.mappper.asEntity
|
||||
import com.twofasapp.storage.PlainPreferences
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
internal class NotificationsLocalSource(
|
||||
private val notificationsDao: NotificationsDao,
|
||||
private val preferences: PlainPreferences,
|
||||
) {
|
||||
|
||||
companion object {
|
||||
private const val KeyPeriodicNotificationCounter = "periodicNotificationCounter"
|
||||
private const val KeyPeriodicNotificationTimestamp = "periodicNotificationTimestamp" // Time when last notification was triggered
|
||||
}
|
||||
|
||||
suspend fun getNotifications(): List<Notification> {
|
||||
return notificationsDao.select().map { it.asDomain() }
|
||||
}
|
||||
@ -29,4 +37,28 @@ internal class NotificationsLocalSource(
|
||||
*notificationsDao.select().map { it.copy(isRead = true) }.toTypedArray()
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun getPeriodicNotificationCounter(): Int {
|
||||
return preferences.getInt(KeyPeriodicNotificationCounter) ?: -1
|
||||
}
|
||||
|
||||
suspend fun setPeriodicNotificationCounter(counter: Int) {
|
||||
preferences.putInt(KeyPeriodicNotificationCounter, counter)
|
||||
}
|
||||
|
||||
suspend fun getPeriodicNotificationTimestamp(): Long {
|
||||
return preferences.getLong(KeyPeriodicNotificationTimestamp) ?: 0
|
||||
}
|
||||
|
||||
suspend fun setPeriodicNotificationTimestamp(timestamp: Long) {
|
||||
preferences.putLong(KeyPeriodicNotificationTimestamp, timestamp)
|
||||
}
|
||||
|
||||
suspend fun clearPeriodicNotifications() {
|
||||
notificationsDao.deleteAllPeriodic()
|
||||
}
|
||||
|
||||
suspend fun insertPeriodicNotification(periodicType: PeriodicNotificationType, notification: Notification) {
|
||||
notificationsDao.insert(notification.asEntity(periodicType.name))
|
||||
}
|
||||
}
|
||||
|
@ -13,4 +13,6 @@ data class NotificationEntity(
|
||||
val push: Boolean,
|
||||
val platform: String,
|
||||
val isRead: Boolean,
|
||||
val periodicType: String?,
|
||||
val internalRoute: String?,
|
||||
)
|
@ -4,7 +4,7 @@ import com.twofasapp.data.notifications.domain.Notification
|
||||
import com.twofasapp.data.notifications.local.model.NotificationEntity
|
||||
import com.twofasapp.data.notifications.remote.model.NotificationJson
|
||||
|
||||
internal fun Notification.asEntity() = NotificationEntity(
|
||||
internal fun Notification.asEntity(periodicType: String? = null) = NotificationEntity(
|
||||
id = id,
|
||||
category = category.name,
|
||||
link = link,
|
||||
@ -13,6 +13,8 @@ internal fun Notification.asEntity() = NotificationEntity(
|
||||
push = push,
|
||||
platform = platform,
|
||||
isRead = isRead,
|
||||
periodicType = periodicType,
|
||||
internalRoute = internalRoute,
|
||||
)
|
||||
|
||||
internal fun NotificationEntity.asDomain() = Notification(
|
||||
@ -24,6 +26,7 @@ internal fun NotificationEntity.asDomain() = Notification(
|
||||
push = push,
|
||||
platform = platform,
|
||||
isRead = isRead,
|
||||
internalRoute = internalRoute,
|
||||
)
|
||||
|
||||
internal fun NotificationJson.asDomain() = Notification(
|
||||
@ -35,4 +38,5 @@ internal fun NotificationJson.asDomain() = Notification(
|
||||
push = push,
|
||||
platform = platform,
|
||||
isRead = false,
|
||||
internalRoute = null,
|
||||
)
|
@ -45,7 +45,19 @@ fun NavGraphBuilder.homeNavigation(
|
||||
}
|
||||
|
||||
composable(Screen.Notifications.route) {
|
||||
NotificationsScreen()
|
||||
NotificationsScreen(
|
||||
openInternalRoute = { route ->
|
||||
when (route) {
|
||||
Screen.Backup.route -> {
|
||||
navController.navigate(Screen.Backup.routeWithArgs(NavArg.TurnOnBackup to true))
|
||||
}
|
||||
|
||||
else -> {
|
||||
navController.navigate(route)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
composable(Screen.EditService.route, listOf(NavArg.ServiceId)) {
|
||||
|
@ -38,12 +38,14 @@ import org.koin.androidx.compose.koinViewModel
|
||||
@Composable
|
||||
internal fun NotificationsScreen(
|
||||
viewModel: NotificationsViewModel = koinViewModel(),
|
||||
openInternalRoute: (String) -> Unit,
|
||||
) {
|
||||
val notifications by viewModel.notificationsList.collectAsStateWithLifecycle()
|
||||
|
||||
ScreenContent(
|
||||
notifications = notifications,
|
||||
onNotificationClick = { viewModel.onNotificationClick(it) }
|
||||
onNotificationClick = { viewModel.onNotificationClick(it) },
|
||||
onInternalRouteClick = openInternalRoute,
|
||||
)
|
||||
}
|
||||
|
||||
@ -51,6 +53,7 @@ internal fun NotificationsScreen(
|
||||
private fun ScreenContent(
|
||||
notifications: List<Notification>,
|
||||
onNotificationClick: (Notification) -> Unit,
|
||||
onInternalRouteClick: (String) -> Unit,
|
||||
) {
|
||||
val uriHandler = LocalUriHandler.current
|
||||
val context = LocalContext.current
|
||||
@ -77,10 +80,24 @@ private fun ScreenContent(
|
||||
Notification(
|
||||
notification = notification,
|
||||
modifier = Modifier
|
||||
.clickable {
|
||||
.clickable(
|
||||
notification.link.isNotBlank() || notification.internalRoute
|
||||
.isNullOrBlank()
|
||||
.not()
|
||||
) {
|
||||
onNotificationClick(notification)
|
||||
|
||||
if (notification.link.isNotBlank()) {
|
||||
uriHandler.openSafely(notification.link, context)
|
||||
}
|
||||
|
||||
if (notification.internalRoute
|
||||
.isNullOrBlank()
|
||||
.not()
|
||||
) {
|
||||
onInternalRouteClick(notification.internalRoute.orEmpty())
|
||||
}
|
||||
}
|
||||
.background(if (notification.isRead) TwTheme.color.surface else TwTheme.color.background)
|
||||
.padding(16.dp)
|
||||
)
|
||||
@ -133,6 +150,8 @@ private fun Notification(
|
||||
|
||||
Spacer(modifier = Modifier.width(24.dp))
|
||||
|
||||
if (notification.link.isNotBlank()) {
|
||||
Icon(painter = TwIcons.ExternalLink, contentDescription = null, tint = TwTheme.color.iconTint)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user