Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 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
2f0b00c
fix: add transition delay
jvsena42 Dec 26, 2025
ba10eb3
fix: clear backstack on critical update navigation
jvsena42 Dec 26, 2025
ad97ef0
chore: remove redundant drop
jvsena42 Dec 26, 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
6 changes: 3 additions & 3 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,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
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
}
}
Loading
Loading