Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
d6ff00a
chore: organize categories in an enum
jvsena42 Sep 26, 2025
852cb98
feat: high balance rule
jvsena42 Sep 26, 2025
d1f827b
chore: move app update sheet logic to home
jvsena42 Sep 26, 2025
da98bcd
feat: backup sheet logic
jvsena42 Sep 29, 2025
d7ece6e
feat: notifications sheet logic
jvsena42 Sep 29, 2025
d3d8f64
feat: quick pay sheet logic
jvsena42 Sep 29, 2025
f109ad9
fix: notifications interval
jvsena42 Sep 29, 2025
03c12c7
feat: trigger timed sheet check
jvsena42 Sep 29, 2025
c93b4bd
feat: quick pay intro sheet
jvsena42 Sep 29, 2025
5daab99
feat: display backup
jvsena42 Sep 29, 2025
61584ca
feat: display update sheet
jvsena42 Sep 29, 2025
4aee4d5
feat: display quick pay sheet
jvsena42 Sep 29, 2025
7e42de3
feat: save notifications preferences
jvsena42 Sep 29, 2025
f4355e2
feat: BackgroundPaymentsIntroScreen.kt
jvsena42 Sep 29, 2025
36b08b1
feat: BackgroundPaymentsIntroSheet.kt
jvsena42 Sep 29, 2025
4150438
feat: BackgroundPaymentsSettings.kt WIP
jvsena42 Sep 29, 2025
f95acc9
feat: BackgroundPaymentsSettings.kt WIP
jvsena42 Sep 29, 2025
ab4419e
feat: NotificationPreview.kt WIP
jvsena42 Sep 30, 2025
57565b3
feat: text style
jvsena42 Sep 30, 2025
7ed0ce8
feat: overlay disabled
jvsena42 Sep 30, 2025
b9fd508
feat: set notification icon
jvsena42 Sep 30, 2025
576e5ff
feat: warning disabled notifications
jvsena42 Sep 30, 2025
13e7750
feat: settings notification settings button
jvsena42 Sep 30, 2025
37e4a61
feat: save notification details preference
jvsena42 Sep 30, 2025
ae1a214
feat: bell icon
jvsena42 Sep 30, 2025
60bcbf1
feat: navigation
jvsena42 Oct 1, 2025
e89ad71
feat: settings navigation
jvsena42 Oct 1, 2025
b7200ef
feat: save permission change
jvsena42 Oct 1, 2025
f6ba2dd
fix: notification update caching
jvsena42 Oct 1, 2025
015cbce
feat: animate description
jvsena42 Oct 1, 2025
40a29c4
feat: handle continue from sheet
jvsena42 Oct 1, 2025
9974a46
chore: logs
jvsena42 Oct 1, 2025
29e8e10
chore: dismiss sheet before navigate
jvsena42 Oct 1, 2025
60896f1
fix: display backup intro
jvsena42 Oct 1, 2025
11223bc
fix: implement bottom sheet to update
jvsena42 Oct 1, 2025
3510a58
fix: quick pay navigation
jvsena42 Oct 1, 2025
bc95f47
chore: code clean up
jvsena42 Oct 1, 2025
ab9c30d
feat: notification body
jvsena42 Oct 1, 2025
3b5c77a
feat: critical update navigation
jvsena42 Oct 1, 2025
d81844e
fix: check delay 2 seconds
jvsena42 Oct 1, 2025
11b1a1b
Merge branch 'master' into feat/time-sheet-polish
jvsena42 Oct 1, 2025
12f1454
chore: code cleanup
jvsena42 Oct 1, 2025
6139161
chore: lint
jvsena42 Oct 1, 2025
f67c3bf
chore: lint
jvsena42 Oct 1, 2025
a4c96d9
chore: scope lazy initialization
jvsena42 Oct 1, 2025
176b35c
fix: label
jvsena42 Oct 1, 2025
d5def7b
fix: don't show quick pay sheet if already enabled
jvsena42 Oct 1, 2025
0135263
fix: small icon
jvsena42 Oct 1, 2025
bd4ed2e
fix: gradient bg
jvsena42 Oct 1, 2025
5ee1d8b
chore: restore comments
jvsena42 Oct 2, 2025
10242d9
chore: vertical spacer
jvsena42 Oct 2, 2025
699e35a
chore: vertical spacer
jvsena42 Oct 2, 2025
c00024b
chore: vertical spacer
jvsena42 Oct 2, 2025
7dca72f
chore: clean imports
jvsena42 Oct 2, 2025
9475c22
fix: don't show notifications sheet if user have no spending balance
jvsena42 Oct 2, 2025
e4d0601
fix: don't show notifications sheet if user have no spending balance
jvsena42 Oct 2, 2025
8ab0a03
fix: empty state update
jvsena42 Oct 2, 2025
76222b8
fix: check quick pay intro as seen after display for the first time
jvsena42 Oct 3, 2025
fcd32c9
chore: imports
jvsena42 Oct 5, 2025
a393204
fix: route name
jvsena42 Oct 6, 2025
b170713
fix: trigger timed cheats check on balance change
jvsena42 Oct 7, 2025
68debe1
fix: implement queue logic
jvsena42 Oct 7, 2025
1cd10a2
fix: sort
jvsena42 Oct 7, 2025
6dc6ffa
chore: lift dismiss callback
jvsena42 Oct 7, 2025
5d5e3cc
chore: logs
jvsena42 Oct 7, 2025
0ea0bf1
chore: implement sheet host
jvsena42 Oct 8, 2025
aadfdfb
chore: lint
jvsena42 Oct 8, 2025
1918111
fix: add a bottom sheet wrapper to don't be render behind TabBar
jvsena42 Oct 8, 2025
c3c87cd
fix: set as seen after dismiss
jvsena42 Oct 8, 2025
f9420c2
fix: reimplement rememberUpdatedState
jvsena42 Oct 8, 2025
06d07d4
fix: checkTimedSheets on balance change
jvsena42 Oct 8, 2025
20e25e9
Merge branch 'master' into feat/time-sheet-polish
jvsena42 Oct 9, 2025
323c067
chore: solve conflicts
jvsena42 Oct 9, 2025
018eced
fix: quickpay intro seen update
jvsena42 Oct 9, 2025
dd80166
Merge branch 'master' into feat/time-sheet-polish
jvsena42 Oct 9, 2025
eb15d59
Merge branch 'master' into feat/time-sheet-polish
jvsena42 Oct 9, 2025
6606ed3
chore: formating
jvsena42 Oct 9, 2025
26f6bdf
Merge branch 'master' into feat/time-sheet-polish
jvsena42 Oct 9, 2025
321f20f
fix: don't clear processed payment list
jvsena42 Oct 10, 2025
2045d30
chore: replace DisposableEffect with LaunchedEffect
jvsena42 Oct 10, 2025
d85b70b
chore: move timed sheets to parent
jvsena42 Oct 10, 2025
b271df8
chore: remove unnecessary state
jvsena42 Oct 10, 2025
627f3df
fix: timed sheet dismiss
jvsena42 Oct 10, 2025
af409e6
chore: remove sheet wrapper
jvsena42 Oct 10, 2025
a58a1a8
chore: lint
jvsena42 Oct 10, 2025
d1c3f96
chore: lint
jvsena42 Oct 10, 2025
b5e63a9
chore: lint
jvsena42 Oct 10, 2025
df850e6
chore: lint
jvsena42 Oct 10, 2025
dd2aa5d
chore: lint
jvsena42 Oct 10, 2025
208bad8
fix: don't display notifications intro if already granted
jvsena42 Oct 10, 2025
0163101
chore: lint
jvsena42 Oct 10, 2025
0c99fea
chore: add comment
jvsena42 Oct 13, 2025
75b09e8
feat: display notifications settings
jvsena42 Oct 13, 2025
a58768b
chore: remove animation
jvsena42 Oct 13, 2025
84e228d
fix: listen for balance change
jvsena42 Oct 13, 2025
c367549
chore: add log
jvsena42 Oct 13, 2025
90aedea
fix: skip queue check
jvsena42 Oct 13, 2025
ad69db7
Merge pull request #435 from synonymdev/chore/move-to-parent
jvsena42 Oct 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion app/src/main/java/to/bitkit/data/SettingsStore.kt
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ data class SettingsData(
val hasSeenShopIntro: Boolean = false,
val hasSeenProfileIntro: Boolean = false,
val quickPayIntroSeen: Boolean = false,
val bgPaymentsIntroSeen: Boolean = false,
val isQuickPayEnabled: Boolean = false,
val quickPayAmount: Int = 5,
val lightningSetupStep: Int = 0,
Expand All @@ -99,8 +100,12 @@ data class SettingsData(
val enableAutoReadClipboard: Boolean = false,
val enableSendAmountWarning: Boolean = false,
val backupVerified: Boolean = false,
val notificationsGranted: Boolean = false,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be used to #134 , didn't implemented here because the PR is already big

val showNotificationDetails: Boolean = true,
val dismissedSuggestions: List<String> = emptyList(),
val lastTimeAskedBalanceWarningMillis: Long = 0,
val balanceWarningIgnoredMillis: Long = 0,
val backupWarningIgnoredMillis: Long = 0,
val notificationsIgnoredMillis: Long = 0,
val balanceWarningTimes: Int = 0,
val coinSelectAuto: Boolean = true,
val coinSelectPreference: CoinSelectionPreference = CoinSelectionPreference.BranchAndBound,
Expand Down
17 changes: 11 additions & 6 deletions app/src/main/java/to/bitkit/fcm/WakeNodeWorker.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,17 @@ import androidx.work.workDataOf
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.withTimeout
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.contentOrNull
import kotlinx.serialization.json.jsonObject
import org.lightningdevkit.ldknode.Event
import to.bitkit.data.SettingsStore
import to.bitkit.di.json
import to.bitkit.ext.amountOnClose
import to.bitkit.models.BITCOIN_SYMBOL
import to.bitkit.models.BlocktankNotificationType
import to.bitkit.models.BlocktankNotificationType.cjitPaymentArrived
import to.bitkit.models.BlocktankNotificationType.incomingHtlc
Expand All @@ -42,6 +45,7 @@ class WakeNodeWorker @AssistedInject constructor(
private val lightningRepo: LightningRepo,
private val blocktankRepo: BlocktankRepo,
private val activityRepo: ActivityRepo,
private val settingsStore: SettingsStore,
) : CoroutineWorker(appContext, workerParams) {
private val self = this

Expand Down Expand Up @@ -113,6 +117,8 @@ class WakeNodeWorker @AssistedInject constructor(
* @param event The LDK event to check.
*/
private suspend fun handleLdkEvent(event: Event) {
val showDetails = settingsStore.data.first().showNotificationDetails
val openBitkitMessage = "Open Bitkit to see details"
when (event) {
is Event.PaymentReceived -> {
bestAttemptContent?.title = "Payment Received"
Expand All @@ -127,7 +133,8 @@ class WakeNodeWorker @AssistedInject constructor(
sats = sats.toLong(),
)
)
bestAttemptContent?.body = "⚡ $sats"
val content = if (showDetails) "$BITCOIN_SYMBOL $sats" else openBitkitMessage
bestAttemptContent?.body = content
if (self.notificationType == incomingHtlc) {
self.deliver()
}
Expand All @@ -146,19 +153,17 @@ class WakeNodeWorker @AssistedInject constructor(

lightningRepo.getChannels()?.find { it.channelId == event.channelId }?.let { channel ->
val sats = channel.amountOnClose
self.bestAttemptContent?.title = "Received ⚡ $sats sats"

val content = if (showDetails) "$BITCOIN_SYMBOL $sats" else openBitkitMessage
self.bestAttemptContent?.title = content
val cjitEntry = channel.let { blocktankRepo.getCjitEntry(it) }
if (cjitEntry != null) {
val amount = channel.amountOnClose.toLong()

// Save for UI to pick up
NewTransactionSheetDetails.save(
appContext,
NewTransactionSheetDetails(
type = NewTransactionSheetType.LIGHTNING,
direction = NewTransactionSheetDirection.RECEIVED,
sats = amount,
sats = sats.toLong(),
)
)
activityRepo.insertActivityFromCjit(cjitEntry = cjitEntry, channel = channel)
Expand Down
86 changes: 81 additions & 5 deletions app/src/main/java/to/bitkit/ui/ContentView.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package to.bitkit.ui

import android.content.Intent
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.DisposableEffect
Expand All @@ -12,6 +13,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import androidx.core.net.toUri
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
Expand All @@ -29,13 +31,16 @@ import androidx.navigation.toRoute
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.serialization.Serializable
import to.bitkit.env.Env
import to.bitkit.models.NewTransactionSheetDetails
import to.bitkit.models.NodeLifecycleState
import to.bitkit.models.Toast
import to.bitkit.models.WidgetType
import to.bitkit.ui.Routes.ExternalConnection
import to.bitkit.ui.components.AuthCheckScreen
import to.bitkit.ui.components.Sheet
import to.bitkit.ui.components.SheetHost
import to.bitkit.ui.components.TimedSheetType
import to.bitkit.ui.onboarding.InitializingWalletView
import to.bitkit.ui.onboarding.WalletRestoreErrorView
import to.bitkit.ui.onboarding.WalletRestoreSuccessView
Expand Down Expand Up @@ -114,6 +119,8 @@ import to.bitkit.ui.settings.advanced.CoinSelectPreferenceScreen
import to.bitkit.ui.settings.advanced.ElectrumConfigScreen
import to.bitkit.ui.settings.advanced.RgsServerScreen
import to.bitkit.ui.settings.appStatus.AppStatusScreen
import to.bitkit.ui.settings.backgroundPayments.BackgroundPaymentsIntroScreen
import to.bitkit.ui.settings.backgroundPayments.BackgroundPaymentsSettings
import to.bitkit.ui.settings.backups.ResetAndRestoreScreen
import to.bitkit.ui.settings.general.DefaultUnitSettingsScreen
import to.bitkit.ui.settings.general.GeneralSettingsScreen
Expand All @@ -136,10 +143,14 @@ import to.bitkit.ui.settings.support.ReportIssueScreen
import to.bitkit.ui.settings.support.SupportScreen
import to.bitkit.ui.settings.transactionSpeed.CustomFeeSettingsScreen
import to.bitkit.ui.settings.transactionSpeed.TransactionSpeedSettingsScreen
import to.bitkit.ui.sheets.BackgroundPaymentsIntroSheet
import to.bitkit.ui.sheets.BackupRoute
import to.bitkit.ui.sheets.BackupSheet
import to.bitkit.ui.sheets.ForceTransferSheet
import to.bitkit.ui.sheets.HighBalanceWarningSheet
import to.bitkit.ui.sheets.LnurlAuthSheet
import to.bitkit.ui.sheets.PinSheet
import to.bitkit.ui.sheets.QuickPayIntroSheet
import to.bitkit.ui.sheets.SendSheet
import to.bitkit.ui.sheets.UpdateSheet
import to.bitkit.ui.theme.TRANSITION_SHEET_MS
Expand Down Expand Up @@ -320,7 +331,7 @@ fun ContentView(
) {
AutoReadClipboardHandler()

val currentSheet by appViewModel.currentSheet
val currentSheet by appViewModel.currentSheet.collectAsStateWithLifecycle()
SheetHost(
shouldExpand = currentSheet != null,
onDismiss = { appViewModel.hideSheet() },
Expand All @@ -340,7 +351,7 @@ fun ContentView(
ReceiveSheet(
walletState = walletUiState,
navigateToExternalConnection = {
navController.navigate(Routes.ExternalConnection())
navController.navigate(ExternalConnection())
appViewModel.hideSheet()
}
)
Expand All @@ -349,10 +360,53 @@ fun ContentView(
is Sheet.ActivityDateRangeSelector -> DateRangeSelectorSheet()
is Sheet.ActivityTagSelector -> TagSelectorSheet()
is Sheet.Pin -> PinSheet(sheet, appViewModel)
is Sheet.Backup -> BackupSheet(sheet, appViewModel)
is Sheet.Backup -> BackupSheet(sheet, onDismiss = { appViewModel.hideSheet() })
is Sheet.LnurlAuth -> LnurlAuthSheet(sheet, appViewModel)
Sheet.Update -> UpdateSheet(onCancel = { appViewModel.hideSheet() })
Sheet.ForceTransfer -> ForceTransferSheet(appViewModel, transferViewModel)
is Sheet.TimedSheet -> {
when (sheet.type) {
TimedSheetType.APP_UPDATE -> {
UpdateSheet(onCancel = { appViewModel.dismissTimedSheet() })
}

TimedSheetType.BACKUP -> {
BackupSheet(
sheet = Sheet.Backup(BackupRoute.Intro),
onDismiss = { appViewModel.dismissTimedSheet() }
)
}

TimedSheetType.NOTIFICATIONS -> {
BackgroundPaymentsIntroSheet(
onContinue = {
appViewModel.dismissTimedSheet(skipQueue = true)
navController.navigate(Routes.BackgroundPaymentsSettings)
settingsViewModel.setBgPaymentsIntroSeen(true)
},
)
}

TimedSheetType.QUICK_PAY -> {
QuickPayIntroSheet(
onContinue = {
appViewModel.dismissTimedSheet(skipQueue = true)
navController.navigate(Routes.QuickPaySettings)
},
)
}

TimedSheetType.HIGH_BALANCE -> {
HighBalanceWarningSheet(
understoodClick = { appViewModel.dismissTimedSheet() },
learnMoreClick = {
val intent = Intent(Intent.ACTION_VIEW, Env.STORING_BITCOINS_URL.toUri())
context.startActivity(intent)
appViewModel.dismissTimedSheet(skipQueue = true)
}
)
}
}
}
}
}
) {
Expand Down Expand Up @@ -763,6 +817,22 @@ private fun NavGraphBuilder.generalSettings(navController: NavHostController) {
composableWithDefaultTransitions<Routes.TagsSettings> {
TagsSettingsScreen(navController)
}
composableWithDefaultTransitions<Routes.BackgroundPaymentsSettings> {
BackgroundPaymentsSettings(
onBack = { navController.popBackStack() },
onClose = { navController.navigateToHome() },
)
}

composableWithDefaultTransitions<Routes.BackgroundPaymentsIntro> {
BackgroundPaymentsIntroScreen(
onBack = { navController.popBackStack() },
onClose = { navController.navigateToHome() },
onContinue = {
navController.navigate(Routes.BackgroundPaymentsSettings)
}
)
}
}

private fun NavGraphBuilder.advancedSettings(navController: NavHostController) {
Expand Down Expand Up @@ -1031,7 +1101,7 @@ private fun NavGraphBuilder.update() {

private fun NavGraphBuilder.recoveryMode(
navController: NavHostController,
appViewModel: AppViewModel
appViewModel: AppViewModel,
) {
composableWithDefaultTransitions<Routes.RecoveryMode> {
RecoveryModeScreen(
Expand Down Expand Up @@ -1719,4 +1789,10 @@ sealed interface Routes {

@Serializable
data object RecoveryMnemonic : Routes

@Serializable
data object BackgroundPaymentsIntro : Routes

@Serializable
data object BackgroundPaymentsSettings : Routes
}
2 changes: 1 addition & 1 deletion app/src/main/java/to/bitkit/ui/Notifications.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ internal fun Context.notificationBuilder(
val pendingIntent = PendingIntent.getActivity(this, 0, intent, flags)

return NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.ic_notification)
.setSmallIcon(R.drawable.ic_launcher_fg_regtest)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setContentIntent(pendingIntent) // fired on tap
Expand Down
100 changes: 100 additions & 0 deletions app/src/main/java/to/bitkit/ui/components/NotificationPreview.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package to.bitkit.ui.components

import androidx.compose.animation.AnimatedContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import to.bitkit.R
import to.bitkit.ui.theme.AppThemeSurface
import to.bitkit.ui.theme.Colors
import to.bitkit.ui.theme.Shapes

@Composable
fun NotificationPreview(
enabled: Boolean,
title: String,
description: String,
showDetails: Boolean,
modifier: Modifier = Modifier,
) {
Box(modifier = modifier) {
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier
.clip(Shapes.medium)
.background(Colors.White80)
.padding(9.dp)
) {
Image(
painter = painterResource(R.drawable.ic_notification),
contentDescription = null,
modifier = Modifier
.size(38.dp)
)

Column(
modifier = Modifier.weight(1f),
verticalArrangement = Arrangement.SpaceBetween
) {
BodySSB(text = title, color = Colors.Black)
val textDescription = if (showDetails) description else "Open Bitkit to see details" // TODO Transifex
AnimatedContent(targetState = textDescription) { text ->
Footnote(text = text, color = Colors.Gray3)
}
}

Caption("3m ago", color = Colors.Gray2)
}

if (!enabled) {
Box(
modifier = Modifier
.matchParentSize()
.clip(Shapes.medium)
.background(Colors.Black70)
)
}
}
}

@Preview(showSystemUi = true)
@Composable
private fun Preview() {
AppThemeSurface {
Column(
modifier = Modifier
.fillMaxSize()
.padding(8.dp),
verticalArrangement = Arrangement.Center
) {
NotificationPreview(
enabled = true,
title = "Payment Received",
description = "₿ 21 000",
showDetails = true,
modifier = Modifier.fillMaxWidth()
)
VerticalSpacer(16.dp)
NotificationPreview(
enabled = false,
title = "Payment Received",
description = "₿ 21 000",
showDetails = false,
modifier = Modifier.fillMaxWidth()
)
}
}
}
12 changes: 11 additions & 1 deletion app/src/main/java/to/bitkit/ui/components/SheetHost.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,18 @@ sealed interface Sheet {
data object ActivityDateRangeSelector : Sheet
data object ActivityTagSelector : Sheet
data class LnurlAuth(val domain: String, val lnurl: String, val k1: String) : Sheet
data object Update : Sheet
data object ForceTransfer : Sheet

data class TimedSheet(val type: TimedSheetType) : Sheet
}

/**@param priority Priority levels for timed sheets (higher number = higher priority)*/
enum class TimedSheetType(val priority: Int) {
APP_UPDATE(priority = 5),
BACKUP(priority = 4),
NOTIFICATIONS(priority = 3),
QUICK_PAY(priority = 2),
HIGH_BALANCE(priority = 1)
}

@OptIn(ExperimentalMaterial3Api::class)
Expand Down
Loading
Loading