Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
77c3848
fix: remove check on balance change
jvsena42 Dec 23, 2025
84a9085
chore: log context tag
jvsena42 Dec 23, 2025
9c558a2
refactor: move timed sheet logic to specific classes
jvsena42 Dec 24, 2025
0ed3260
test: timed sheet tests
jvsena42 Dec 24, 2025
b7879fd
refactor: replace timed sheet logic with manager
jvsena42 Dec 24, 2025
6e99ee1
fix: reimplement critical update logic
jvsena42 Dec 24, 2025
4e13983
fix: add two seconds delay
jvsena42 Dec 24, 2025
a72fc22
refactor: Migrate navigation to nav3
ovitrif Dec 23, 2025
06d5091
chore: Update deps
ovitrif Dec 24, 2025
4fe4ecc
Merge branch 'feat/nav3' into fix/uniffy-timed-sheet-behavior
jvsena42 Dec 24, 2025
a110582
Merge remote-tracking branch 'origin/fix/uniffy-timed-sheet-behavior'…
jvsena42 Dec 24, 2025
920aa1d
refactor: Migrate navigation to nav3
ovitrif Dec 23, 2025
5b5fe6e
chore: Update deps
ovitrif Dec 24, 2025
6059092
Merge remote-tracking branch 'origin/feat/nav3' into feat/nav3
jvsena42 Dec 24, 2025
eabe2c0
Merge branch 'feat/nav3' into fix/uniffy-timed-sheet-behavior
jvsena42 Dec 24, 2025
697bf90
refactor: Migrate navigation to nav3
ovitrif Dec 23, 2025
e73fbef
chore: Update deps
ovitrif Dec 24, 2025
a66ffe6
Merge remote-tracking branch 'origin/feat/nav3' into feat/nav3
jvsena42 Dec 24, 2025
b25be02
Merge branch 'feat/nav3' into fix/uniffy-timed-sheet-behavior
jvsena42 Dec 24, 2025
63897cf
fix: sheet navigation
jvsena42 Dec 24, 2025
989602d
fix: detect when the sheet is dismissed by swipe down
jvsena42 Dec 24, 2025
9bd5cc6
fix: return early if sheet is null
jvsena42 Dec 24, 2025
b37efac
fix: text log
jvsena42 Dec 24, 2025
2f1b45d
chore: lint
jvsena42 Dec 24, 2025
89dd6e7
refactor: replace try catch with runCatching
jvsena42 Dec 26, 2025
e4e14cc
refactor: Implement custom sheet component
ovitrif Dec 25, 2025
2f0b00c
fix: add transition delay
jvsena42 Dec 26, 2025
ba10eb3
fix: clear backstack on critical update navigation
jvsena42 Dec 26, 2025
e3f963f
fix: Polish navigation
ovitrif Dec 26, 2025
ad97ef0
chore: remove redundant drop
jvsena42 Dec 26, 2025
f80b6f4
fix: qr code decoding error message
jvsena42 Dec 26, 2025
0f37ce2
fix: skip refresh for disabled widgets
jvsena42 Dec 26, 2025
ceafe3a
fix: refresh on preview
jvsena42 Dec 26, 2025
97a63fb
fix: keep jobs only for enabled widgets
jvsena42 Dec 26, 2025
f24bc05
chore: remove unused code
jvsena42 Dec 26, 2025
e93ca82
chore: logs
jvsena42 Dec 26, 2025
595dfbb
refactor: Introduce nav routes hierarchy
ovitrif Dec 26, 2025
ed166a4
Merge branch 'feat/nav3' into fix/skip-autorefresh-for-disabled-widgets
jvsena42 Dec 26, 2025
6a9eb9c
chore: lint
jvsena42 Dec 26, 2025
4dfdbde
Merge remote-tracking branch 'origin/fix/skip-autorefresh-for-disable…
jvsena42 Dec 26, 2025
e24de5c
refactor: migrate navigation to nav3
ovitrif Dec 23, 2025
9dc383e
chore: update deps
ovitrif Dec 24, 2025
84c4c59
refactor: implement custom sheet component
ovitrif Dec 25, 2025
8e6f857
fix: polish navigation
ovitrif Dec 26, 2025
5bd99b5
refactor: introduce nav routes hierarchy
ovitrif Dec 26, 2025
1eb159f
chore: cleanup
ovitrif Dec 26, 2025
b357b6f
fix: sheet dismiss on fast swipe
ovitrif Dec 26, 2025
5e19b1a
fix: sheet bg gap on sheet upward drag
ovitrif Dec 26, 2025
342365d
fix: sheet dismiss sensitivity
ovitrif Dec 26, 2025
46d7e73
fix: apply receive brightness only when seeing QR
ovitrif Dec 26, 2025
fd95f09
fix: drawer menu positioning
ovitrif Dec 27, 2025
1065fac
fix: move regtest mining to viewmodel
ovitrif Dec 27, 2025
edd77d7
chore: remove unused parameter
jvsena42 Dec 29, 2025
6de2a1c
Merge branch 'feat/nav3' into fix/skip-autorefresh-for-disabled-widgets
jvsena42 Dec 29, 2025
d12093c
Merge branch 'feat/nav3' into fix/error-decoding-qr-msg
jvsena42 Dec 29, 2025
8fe29b9
Merge branch 'feat/nav3' into fix/uniffy-timed-sheet-behavior
jvsena42 Dec 29, 2025
fe8b2d9
fix: detect dismiss by swipe down
jvsena42 Dec 29, 2025
b2e8b70
fix: clear backstack on critical update navigation
jvsena42 Dec 29, 2025
e6a9de6
re-add ReceiveScreen test tag
piotr-iohk Dec 29, 2025
e72d4ce
Merge branch 'feat/nav3' into fix/uniffy-timed-sheet-behavior
jvsena42 Dec 29, 2025
a8b6ebd
Merge branch 'feat/nav3' into fix/error-decoding-qr-msg
ovitrif Dec 29, 2025
cbc152e
Merge pull request #556 from synonymdev/fix/uniffy-timed-sheet-behavior
ovitrif Dec 29, 2025
c2e62e9
Merge branch 'feat/nav3' into fix/skip-autorefresh-for-disabled-widgets
ovitrif Dec 29, 2025
4df76af
Merge pull request #560 from synonymdev/fix/skip-autorefresh-for-disa…
ovitrif Dec 29, 2025
bfcd8ca
Merge branch 'feat/nav3' into fix/error-decoding-qr-msg
ovitrif Dec 29, 2025
9e96420
Merge pull request #559 from synonymdev/fix/error-decoding-qr-msg
ovitrif Dec 29, 2025
0248536
Merge branch 'master' into feat/nav3
ovitrif Dec 29, 2025
8dded68
fix: close receive sheet on back/swipe from edit
ovitrif Dec 29, 2025
d9778b5
fix: preserve amount when returning to edit screen
ovitrif Dec 29, 2025
9232635
refactor: use sealed interfaces for route grouping
ovitrif Dec 29, 2025
c31269f
Merge branch 'master' into feat/nav3
ovitrif Dec 29, 2025
cc74a6e
fix: receive flow sheet navigation
ovitrif Dec 29, 2025
3ad4a88
fix: in-sheet navigation fix
ovitrif Dec 29, 2025
7485bef
Merge branch 'master' into feat/nav3
ovitrif Dec 31, 2025
d54f349
refactor: injectable Navigator instead of effects
ovitrif Dec 31, 2025
91ea1af
fix: use preset transitions for in-sheet nav
ovitrif Dec 31, 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
50 changes: 49 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,54 @@ suspend fun getData(): Result<Data> = withContext(Dispatchers.IO) {
}
```

### Rules
### Sheet Navigation Flows

`SheetSceneStrategy.calculateScene()` finds the FIRST entry with sheet metadata (the sheet root) and renders ALL subsequent entries within that same sheet container. Swiping to dismiss closes the entire sheet flow.

**Pattern:**

- Only ROOT routes need `metadata = SheetSceneStrategy.sheet()` (e.g., `Pin.Prompt`, `Receive.Qr`)
- Sub-routes have NO metadata - they navigate within the parent sheet container

**Flows:**

1. **Pin Flow** (root: `Pin.Prompt`)

- Pin.Prompt → Pin.Choose → Pin.Confirm → Pin.Biometrics → Pin.Result

2. **Backup Flow** (root: `Backup.Intro`)

- Backup.Intro → ShowMnemonic → ShowPassphrase → ConfirmMnemonic → ConfirmPassphrase → Warning → Success → MultipleDevices → Metadata

3. **Send Flow** (root: `Send.Recipient`)

- Send.Recipient → Address → Amount → QrScanner → CoinSelection → FeeRate → FeeCustom → Confirm → Success/Error
- Also: WithdrawConfirm, WithdrawError, Support, AddTag, PinCheck, QuickPay

4. **Receive Flow** (root: `Receive.Qr`)

- Receive.Qr → EditInvoice → AddTag
- Receive.Qr → Amount → Confirm → Liquidity
- Receive.Qr → GeoBlock
- Also: ConfirmInbound, LiquidityAdditional

5. **Gift Flow** (root: `Gift.Loading`)

- Gift.Loading → Used/UsedUp/Error/Success

**Standalone Sheets** (single-screen, each has sheet metadata):

- Activity.DateRangeSelectorSheet
- Activity.TagSelectorSheet
- Sheet.LnurlAuth
- Sheet.ForceTransfer
- Sheet.Update
- Sheet.Backup
- Sheet.Notifications
- Sheet.QuickPay
- Sheet.HighBalance

## Rules

- USE coding rules from `.cursor/default.rules.mdc`
- ALWAYS run `./gradlew compileDevDebugKotlin` after code changes to verify code compiles
Expand Down Expand Up @@ -195,6 +242,7 @@ suspend fun getData(): Result<Data> = withContext(Dispatchers.IO) {
- ALWAYS be mindful of thread safety when working with mutable lists & state
- ALWAYS split screen composables into parent accepting viewmodel + inner private child accepting state and callbacks `Content()`
- ALWAYS name lambda parameters in a composable function using present tense, NEVER use past tense
- ALWAYS use a single root layout node in composables that emit UI
- ALWAYS list 3 suggested commit messages after implementation work for the entire set of uncommitted changes
- NEVER use `wheneverBlocking` in unit test expression body functions wrapped in a `= test {}` lambda
- ALWAYS wrap unit tests `setUp` methods mocking suspending calls with `runBlocking`, e.g `setUp() = runBlocking { }`
Expand Down
7 changes: 4 additions & 3 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ dependencies {
implementation(libs.material)
implementation(libs.datastore.preferences)
implementation(libs.kotlinx.datetime)
implementation(libs.kotlinx.collections.immutable)
implementation(libs.biometric)
implementation(libs.zxing)
implementation(libs.barcode.scanning)
Expand Down Expand Up @@ -232,9 +233,9 @@ dependencies {
implementation(libs.charts)
implementation(libs.haze)
implementation(libs.haze.materials)
// Compose Navigation
implementation(libs.navigation.compose)
androidTestImplementation(libs.navigation.testing)
// Navigation
implementation(libs.navigation.runtime)
implementation(libs.navigation.ui)
implementation(libs.hilt.navigation.compose)
// Hilt - DI
implementation(libs.hilt.android)
Expand Down
13 changes: 5 additions & 8 deletions app/detekt-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@
<ID>ComplexCondition:MapWebViewClient.kt$MapWebViewClient$it.errorCode == ERROR_HOST_LOOKUP || it.errorCode == ERROR_CONNECT || it.errorCode == ERROR_TIMEOUT || it.errorCode == ERROR_FILE_NOT_FOUND</ID>
<ID>ComplexCondition:ShopWebViewClient.kt$ShopWebViewClient$it.errorCode == ERROR_HOST_LOOKUP || it.errorCode == ERROR_CONNECT || it.errorCode == ERROR_TIMEOUT || it.errorCode == ERROR_FILE_NOT_FOUND</ID>
<ID>CyclomaticComplexMethod:ActivityListGrouped.kt$private fun groupActivityItems(activityItems: List&lt;Activity&gt;): List&lt;Any&gt;</ID>
<ID>CyclomaticComplexMethod:ActivityRow.kt$@Composable fun ActivityRow( item: Activity, onClick: (String) -&gt; Unit, testTag: String, )</ID>
<ID>CyclomaticComplexMethod:ActivityRow.kt$@Composable fun ActivityRow( item: Activity, onClick: (Activity) -&gt; Unit, testTag: String, )</ID>
<ID>CyclomaticComplexMethod:AppViewModel.kt$AppViewModel$private fun observeSendEvents()</ID>
<ID>CyclomaticComplexMethod:AppViewModel.kt$AppViewModel$private suspend fun handleSanityChecks(amountSats: ULong)</ID>
<ID>CyclomaticComplexMethod:BlocktankRegtestScreen.kt$@Composable fun BlocktankRegtestScreen( navController: NavController, viewModel: BlocktankRegtestViewModel = hiltViewModel(), )</ID>
<ID>CyclomaticComplexMethod:BlocktankRegtestScreen.kt$@Composable private fun BlocktankRegtestContent( onBack: () -&gt; Unit, viewModel: BlocktankRegtestViewModel, )</ID>
<ID>CyclomaticComplexMethod:ConfirmMnemonicScreen.kt$@Composable fun ConfirmMnemonicScreen( uiState: BackupContract.UiState, onContinue: () -&gt; Unit, onBack: () -&gt; Unit, )</ID>
<ID>CyclomaticComplexMethod:HealthRepo.kt$HealthRepo$private fun collectState()</ID>
<ID>CyclomaticComplexMethod:HomeScreen.kt$@Composable fun HomeScreen( mainUiState: MainUiState, drawerState: DrawerState, rootNavController: NavController, walletNavController: NavHostController, settingsViewModel: SettingsViewModel, walletViewModel: WalletViewModel, appViewModel: AppViewModel, activityListViewModel: ActivityListViewModel, homeViewModel: HomeViewModel = hiltViewModel(), )</ID>
<ID>CyclomaticComplexMethod:SendSheet.kt$@Composable fun SendSheet( appViewModel: AppViewModel, walletViewModel: WalletViewModel, startDestination: SendRoute = SendRoute.Recipient, )</ID>
<ID>CyclomaticComplexMethod:HomeScreen.kt$@Composable fun HomeScreen( mainUiState: MainUiState, drawerState: DrawerState, navigator: Navigator, settingsViewModel: SettingsViewModel, walletViewModel: WalletViewModel, appViewModel: AppViewModel, activityListViewModel: ActivityListViewModel, homeViewModel: HomeViewModel = hiltViewModel(), )</ID>
<ID>CyclomaticComplexMethod:SettingsButtonRow.kt$@Composable fun SettingsButtonRow( title: String, modifier: Modifier = Modifier, subtitle: String? = null, value: SettingsButtonValue = SettingsButtonValue.None, description: String? = null, iconRes: Int? = null, iconTint: Color = Color.Unspecified, iconSize: Dp = 32.dp, maxLinesSubtitle: Int = Int.MAX_VALUE, enabled: Boolean = true, loading: Boolean = false, onClick: () -&gt; Unit, )</ID>
<ID>CyclomaticComplexMethod:Slider.kt$@Composable fun StepSlider( value: Int, steps: List&lt;Int&gt;, onValueChange: (Int) -&gt; Unit, modifier: Modifier = Modifier, )</ID>
<ID>DestructuringDeclarationWithTooManyEntries:ActivityRow.kt$val (_, _, _, _, _, displayUnit, primaryDisplay) = LocalCurrencies.current</ID>
Expand All @@ -34,7 +33,6 @@
<ID>EnumNaming:BlocktankNotificationType.kt$BlocktankNotificationType$wakeToTimeout</ID>
<ID>ForbiddenComment:ActivityDetailScreen.kt$/* TODO: Implement assign functionality */</ID>
<ID>ForbiddenComment:BoostTransactionViewModel.kt$BoostTransactionUiState$// TODO: Implement dynamic time estimation</ID>
<ID>ForbiddenComment:ContentView.kt$// TODO: display as sheet</ID>
<ID>ForbiddenComment:ExternalNodeViewModel.kt$ExternalNodeViewModel$// TODO: pass customFeeRate to ldk-node when supported</ID>
<ID>ForbiddenComment:LightningConnectionsViewModel.kt$LightningConnectionsViewModel$// TODO: sort channels to get consistent index; node.listChannels returns a list in random order</ID>
<ID>ForbiddenComment:LightningService.kt$LightningService$// TODO: cleanup sensitive data after implementing a `SecureString` value holder for Keychain return values</ID>
Expand All @@ -43,12 +41,11 @@
<ID>FunctionOnlyReturningConstant:ShopWebViewInterface.kt$ShopWebViewInterface$@JavascriptInterface fun isReady(): Boolean</ID>
<ID>ImplicitDefaultLocale:BlocksService.kt$BlocksService$String.format("%.2f", blockInfo.difficulty / 1_000_000_000_000.0)</ID>
<ID>ImplicitDefaultLocale:PriceService.kt$PriceService$String.format("%.2f", price)</ID>
<ID>ImportOrdering:TransferEntries.kt$import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation3.runtime.EntryProviderScope import androidx.navigation3.runtime.NavKey import to.bitkit.models.Toast import to.bitkit.ui.nav.Navigator import to.bitkit.ui.nav.Routes import to.bitkit.ui.screens.transfer.FundingAdvancedScreen import to.bitkit.ui.screens.transfer.FundingScreen import to.bitkit.ui.screens.transfer.LiquidityScreen import to.bitkit.ui.screens.transfer.SavingsAdvancedScreen import to.bitkit.ui.screens.transfer.SavingsAvailabilityScreen import to.bitkit.ui.screens.transfer.SavingsConfirmScreen import to.bitkit.ui.screens.transfer.SavingsIntroScreen import to.bitkit.ui.screens.transfer.SavingsProgressScreen import to.bitkit.ui.screens.transfer.SettingUpScreen import to.bitkit.ui.screens.transfer.SpendingAdvancedScreen import to.bitkit.ui.screens.transfer.SpendingAmountScreen import to.bitkit.ui.screens.transfer.SpendingConfirmScreen import to.bitkit.ui.screens.transfer.SpendingIntroScreen import to.bitkit.ui.screens.transfer.TransferIntroScreen import to.bitkit.ui.screens.transfer.external.ExternalAmountScreen import to.bitkit.ui.screens.transfer.external.ExternalConfirmScreen import to.bitkit.ui.screens.transfer.external.ExternalConnectionScreen import to.bitkit.ui.screens.transfer.external.ExternalFeeCustomScreen import to.bitkit.ui.screens.transfer.external.ExternalNodeViewModel import to.bitkit.ui.screens.transfer.external.ExternalSuccessScreen import to.bitkit.ui.screens.transfer.external.LnurlChannelScreen import to.bitkit.ui.screens.scanner.QrScanningScreen import to.bitkit.viewmodels.AppViewModel import to.bitkit.viewmodels.SettingsViewModel import to.bitkit.viewmodels.TransferViewModel import to.bitkit.viewmodels.WalletViewModel</ID>
<ID>InstanceOfCheckForException:LightningService.kt$LightningService$e is NodeException</ID>
<ID>LargeClass:AppViewModel.kt$AppViewModel : ViewModel</ID>
<ID>LargeClass:LightningRepo.kt$LightningRepo</ID>
<ID>LongMethod:AppViewModel.kt$AppViewModel$private suspend fun proceedWithPayment()</ID>
<ID>LongMethod:ContentView.kt$@Suppress("LongParameterList") private fun NavGraphBuilder.home( walletViewModel: WalletViewModel, appViewModel: AppViewModel, activityListViewModel: ActivityListViewModel, settingsViewModel: SettingsViewModel, navController: NavHostController, drawerState: DrawerState, )</ID>
<ID>LongMethod:ContentView.kt$private fun NavGraphBuilder.widgets( navController: NavHostController, settingsViewModel: SettingsViewModel, currencyViewModel: CurrencyViewModel, )</ID>
<ID>LongMethod:CoreService.kt$ActivityService$suspend fun generateRandomTestData(count: Int = 100)</ID>
<ID>LongMethod:MainActivity.kt$MainActivity$override fun onCreate(savedInstanceState: Bundle?)</ID>
<ID>LongParameterList:BiometricPrompt.kt$( activity: Context, title: String, cancelButtonText: String, onAuthSucceed: () -&gt; Unit, onAuthFailed: (() -&gt; Unit), onAuthError: ((errorCode: Int, errString: CharSequence) -&gt; Unit), )</ID>
Expand Down Expand Up @@ -112,6 +109,7 @@
<ID>MaxLineLength:HeadlineCard.kt$headline = "How Bitcoin changed El Salvador in more ways a big headline to test the text overflooooooow"</ID>
<ID>MaxLineLength:LightningBalance.kt$is LightningBalance.ClaimableAwaitingConfirmations -&gt; "Claimable Awaiting Confirmations (Height: $confirmationHeight)"</ID>
<ID>MaxLineLength:LightningConnectionsScreen.kt$if (showClosed) R.string.lightning__conn_closed_hide else R.string.lightning__conn_closed_show</ID>
<ID>MaxLineLength:LightningRepo.kt$LightningRepo$"Cannot execute $operationName: Node is ${_lightningState.value.nodeLifecycleState} and not starting"</ID>
<ID>MaxLineLength:LightningRepo.kt$LightningRepo$"accelerateByCpfp error originalTxId: $originalTxId, satsPerVByte: $satsPerVByte destinationAddress: $destinationAddress"</ID>
<ID>MaxLineLength:LightningRepo.kt$LightningRepo$"accelerateByCpfp success, newDestinationTxId: $newDestinationTxId originalTxId: $originalTxId, satsPerVByte: $satsPerVByte destinationAddress: $destinationAddress"</ID>
<ID>MaxLineLength:LightningRepo.kt$LightningRepo$"bumpFeeByRbf success, replacementTxId: $replacementTxId originalTxId: $originalTxId, satsPerVByte: $satsPerVByte"</ID>
Expand Down Expand Up @@ -190,7 +188,6 @@
<ID>TooManyFunctions:BackupNavSheetViewModel.kt$BackupNavSheetViewModel : ViewModel</ID>
<ID>TooManyFunctions:BlocktankRepo.kt$BlocktankRepo</ID>
<ID>TooManyFunctions:CacheStore.kt$CacheStore</ID>
<ID>TooManyFunctions:ContentView.kt$to.bitkit.ui.ContentView.kt</ID>
<ID>TooManyFunctions:CoreService.kt$ActivityService</ID>
<ID>TooManyFunctions:CoreService.kt$BlocktankService</ID>
<ID>TooManyFunctions:DevSettingsViewModel.kt$DevSettingsViewModel : ViewModel</ID>
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/to/bitkit/data/backup/VssBackupClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ class VssBackupClient @Inject constructor(
}
}

companion object Companion {
companion object {
private const val TAG = "VssBackupClient"
}
}
22 changes: 22 additions & 0 deletions app/src/main/java/to/bitkit/di/NavigationModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package to.bitkit.di

import androidx.compose.runtime.mutableStateListOf
import androidx.navigation3.runtime.NavKey
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import to.bitkit.ui.nav.Navigator
import to.bitkit.ui.nav.Routes
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object NavigationModule {
@Singleton
@Provides
fun provideNavigator(): Navigator {
val backStack = mutableStateListOf<NavKey>(Routes.Home)
return Navigator(backStack)
}
}
18 changes: 18 additions & 0 deletions app/src/main/java/to/bitkit/di/TimedSheetModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package to.bitkit.di

import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import kotlinx.coroutines.CoroutineScope
import to.bitkit.utils.timedsheets.TimedSheetManager

@Module
@InstallIn(SingletonComponent::class)
object TimedSheetModule {

@Provides
fun provideTimedSheetManagerProvider(): (CoroutineScope) -> TimedSheetManager {
return ::TimedSheetManager
}
}
6 changes: 5 additions & 1 deletion app/src/main/java/to/bitkit/repositories/WalletRepo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ class WalletRepo @Inject constructor(
suspend fun refreshBip21(): Result<Unit> = withContext(bgDispatcher) {
Logger.debug("Refreshing bip21", context = TAG)

// Preserve current amount/description before clearing
val currentAmount = _walletState.value.bip21AmountSats
val currentDescription = _walletState.value.bip21Description

// Get old payment ID and tags before refreshing (which may change payment ID)
val oldPaymentId = paymentId()
val tagsToMigrate = if (oldPaymentId != null && oldPaymentId.isNotEmpty()) {
Expand All @@ -123,7 +127,7 @@ class WalletRepo @Inject constructor(

clearBip21State(clearTags = false)
refreshAddressIfNeeded()
updateBip21Invoice()
updateBip21Invoice(amountSats = currentAmount, description = currentDescription)

val newPaymentId = paymentId()
val newBip21Url = _walletState.value.bip21
Expand Down
Loading
Loading