Skip to content

Commit

Permalink
Merge pull request #750 from radixdlt/feature/ABW-2743-create-basic-u…
Browse files Browse the repository at this point in the history
…i-for-bottom-sheet

[ABW-2743] Create basic UI for bottom sheet to access factor sources
  • Loading branch information
giannis-rdx authored Feb 14, 2024
2 parents e41bf0b + 7de83ed commit daad234
Show file tree
Hide file tree
Showing 38 changed files with 1,027 additions and 639 deletions.
29 changes: 26 additions & 3 deletions app/src/main/java/com/babylon/wallet/android/WalletApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.babylon.wallet.android.domain.model.MessageFromDataChannel
import com.babylon.wallet.android.domain.userFriendlyMessage
import com.babylon.wallet.android.presentation.accessfactorsources.accessFactorSources
import com.babylon.wallet.android.presentation.dapp.authorized.login.dAppLoginAuthorized
import com.babylon.wallet.android.presentation.dapp.unauthorized.login.dAppLoginUnauthorized
import com.babylon.wallet.android.presentation.main.MAIN_ROUTE
Expand All @@ -43,7 +44,6 @@ import com.google.accompanist.systemuicontroller.rememberSystemUiController
import kotlinx.coroutines.flow.Flow

@Composable
@Suppress("ModifierMissing")
fun WalletApp(
modifier: Modifier = Modifier,
mainViewModel: MainViewModel,
Expand Down Expand Up @@ -103,6 +103,10 @@ fun WalletApp(
)
}
}
HandleAccessFactorSourcesEvents(
navController = navController,
accessFactorSourcesEvents = mainViewModel.accessFactorSourcesEvents
)
HandleStatusEvents(
navController = navController,
statusEvents = mainViewModel.statusEvents
Expand Down Expand Up @@ -175,7 +179,26 @@ private fun SyncStatusBarWithScreenChanges(navController: NavHostController) {
}

@Composable
fun HandleStatusEvents(navController: NavController, statusEvents: Flow<AppEvent.Status>) {
private fun HandleAccessFactorSourcesEvents(
navController: NavController,
accessFactorSourcesEvents: Flow<AppEvent.AccessFactorSources.DeriveAccountPublicKey>
) {
LaunchedEffect(Unit) {
accessFactorSourcesEvents.collect { event ->
when (event) {
is AppEvent.AccessFactorSources -> {
navController.accessFactorSources()
}
}
}
}
}

@Composable
private fun HandleStatusEvents(
navController: NavController,
statusEvents: Flow<AppEvent.Status>
) {
LaunchedEffect(Unit) {
statusEvents.collect { event ->
when (event) {
Expand All @@ -192,7 +215,7 @@ fun HandleStatusEvents(navController: NavController, statusEvents: Flow<AppEvent
}

@Composable
fun ObserveHighPriorityScreens(
private fun ObserveHighPriorityScreens(
navController: NavController,
onLowPriorityScreen: () -> Unit,
onHighPriorityScreen: () -> Unit
Expand Down
24 changes: 24 additions & 0 deletions app/src/main/java/com/babylon/wallet/android/di/UiModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.babylon.wallet.android.di

import com.babylon.wallet.android.presentation.accessfactorsources.AccessFactorSourcesProxy
import com.babylon.wallet.android.presentation.accessfactorsources.AccessFactorSourcesProxyImpl
import com.babylon.wallet.android.presentation.accessfactorsources.AccessFactorSourcesUiProxy
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityRetainedComponent

@Module
@InstallIn(ActivityRetainedComponent::class)
interface UiModule {

@Binds
fun bindAccessFactorSourcesUiProxy(
accessFactorSourcesProxyImpl: AccessFactorSourcesProxyImpl
): AccessFactorSourcesUiProxy

@Binds
fun bindAccessFactorSourcesProxy(
accessFactorSourcesProxyImpl: AccessFactorSourcesProxyImpl
): AccessFactorSourcesProxy
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.babylon.wallet.android.domain.usecases

import com.babylon.wallet.android.data.repository.ResolveAccountsLedgerStateRepository
import com.babylon.wallet.android.presentation.accessfactorsources.AccessFactorSourcesOutput
import kotlinx.coroutines.flow.first
import rdx.works.profile.data.model.apppreferences.Radix
import rdx.works.profile.data.model.currentNetwork
import rdx.works.profile.data.model.extensions.createAccount
import rdx.works.profile.data.model.factorsources.FactorSource
import rdx.works.profile.data.model.pernetwork.Network
import rdx.works.profile.data.model.pernetwork.addAccounts
import rdx.works.profile.data.repository.ProfileRepository
import rdx.works.profile.data.repository.profile
import rdx.works.profile.derivation.model.NetworkId
import javax.inject.Inject

class CreateAccountUseCase @Inject constructor(
private val profileRepository: ProfileRepository,
private val resolveAccountsLedgerStateRepository: ResolveAccountsLedgerStateRepository
) {

suspend operator fun invoke(
displayName: String,
factorSource: FactorSource.CreatingEntity,
publicKeyAndDerivationPath: AccessFactorSourcesOutput.PublicKeyAndDerivationPath,
onNetworkId: NetworkId?
): Network.Account {
val currentProfile = profileRepository.profile.first()
val networkId = onNetworkId ?: currentProfile.currentNetwork?.knownNetworkId ?: Radix.Gateway.default.network.networkId()

val newAccount = currentProfile.createAccount(
displayName = displayName,
onNetworkId = networkId,
factorSource = factorSource,
derivationPath = publicKeyAndDerivationPath.derivationPath,
compressedPublicKey = publicKeyAndDerivationPath.compressedPublicKey,
onLedgerSettings = Network.Account.OnLedgerSettings.init()
)

val accountWithOnLedgerStatusResult = resolveAccountsLedgerStateRepository(listOf(newAccount))

val accountToAdd = if (accountWithOnLedgerStatusResult.isSuccess) {
accountWithOnLedgerStatusResult.getOrThrow().first().account
} else {
newAccount
}

val updatedProfile = currentProfile.addAccounts(
accounts = listOf(accountToAdd),
onNetwork = networkId
)
// Save updated profile
profileRepository.saveProfile(updatedProfile)
// Return new account
return accountToAdd
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.babylon.wallet.android.presentation.accessfactorsources

import androidx.compose.ui.window.DialogProperties
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.dialog

fun NavController.accessFactorSources() {
navigate("access_factor_source_bottom_sheet")
}

fun NavGraphBuilder.accessFactorSources(
onDismiss: () -> Unit
) {
dialog(
route = "access_factor_source_bottom_sheet",
dialogProperties = DialogProperties(usePlatformDefaultWidth = false)
) {
AccessFactorSourcesDialog(
viewModel = hiltViewModel(),
onDismiss = onDismiss
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.babylon.wallet.android.presentation.accessfactorsources

import rdx.works.profile.data.model.factorsources.FactorSource
import rdx.works.profile.data.model.pernetwork.DerivationPath
import rdx.works.profile.derivation.model.NetworkId

// interface for clients that need access to factor sources
interface AccessFactorSourcesProxy {

suspend fun getPublicKeyAndDerivationPathForFactorSource(
accessFactorSourcesInput: AccessFactorSourcesInput.ToDerivePublicKey
): Result<AccessFactorSourcesOutput.PublicKeyAndDerivationPath>
}

// interface for the AccessFactorSourceViewModel that works as a mediator between the clients
// and the AccessFactorSourcesProvider
interface AccessFactorSourcesUiProxy {

fun getInput(): AccessFactorSourcesInput

suspend fun setOutput(output: AccessFactorSourcesOutput)
}

// ----- Models for input/output ----- //

sealed interface AccessFactorSourcesInput {

data class ToDerivePublicKey(
val forNetworkId: NetworkId,
val factorSource: FactorSource.CreatingEntity? = null
) : AccessFactorSourcesInput

// just for demonstration - will change in next PR
data class ToSign(
val someData: List<Int>
) : AccessFactorSourcesInput

data object Init : AccessFactorSourcesInput
}

sealed interface AccessFactorSourcesOutput {

data class PublicKeyAndDerivationPath(
val compressedPublicKey: ByteArray,
val derivationPath: DerivationPath
) : AccessFactorSourcesOutput

// just for demonstration - will change in next PR
data class Signers(
val someData: List<String>
) : AccessFactorSourcesOutput

data class Failure(
val error: Throwable
) : AccessFactorSourcesOutput

data object Init : AccessFactorSourcesOutput
}
Loading

0 comments on commit daad234

Please sign in to comment.