Skip to content

Commit

Permalink
- connect new repository to TopBar navigation so that it can read us…
Browse files Browse the repository at this point in the history
…er saved profile. Added same code for iOS though not tested yet
  • Loading branch information
rodvar committed Dec 3, 2024
1 parent a72458e commit 20ecfb1
Show file tree
Hide file tree
Showing 13 changed files with 117 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package network.bisq.mobile.domain.data.model

import kotlinx.serialization.Serializable
import network.bisq.mobile.domain.PlatformImage

/**
*
*/
@Serializable
open class User: BaseModel() {
var uniqueAvatar: PlatformImage? = null
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ open class MyTradesRepository : SingleObjectRepository<MyTrades>() {
}
}
open class SettingsRepository(keyValueStorage: KeyValueStorage<Settings>): SingleObjectRepository<Settings>(keyValueStorage, Settings())
open class UserRepository(keyValueStorage: KeyValueStorage<User>): SingleObjectRepository<User>(keyValueStorage, User())
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@ import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import network.bisq.mobile.domain.data.model.Greeting
import network.bisq.mobile.domain.data.persistance.KeyValueStorage
import network.bisq.mobile.domain.data.repository.BisqStatsRepository
import network.bisq.mobile.domain.data.repository.BtcPriceRepository
import network.bisq.mobile.domain.data.repository.GreetingRepository
import network.bisq.mobile.domain.data.repository.MyTradesRepository
import network.bisq.mobile.domain.data.repository.SettingsRepository
import network.bisq.mobile.domain.data.repository.*
import network.bisq.mobile.domain.getPlatformSettings
import org.koin.dsl.module

Expand All @@ -32,4 +28,5 @@ val domainModule = module {
single<BtcPriceRepository> { BtcPriceRepository() }
single<MyTradesRepository> { MyTradesRepository() }
single<SettingsRepository> { SettingsRepository(get()) }
single<UserRepository> { UserRepository(get()) }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package network.bisq.mobile.presentation.ui.components.atoms.icons

import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.graphics.painter.Painter
import network.bisq.mobile.domain.PlatformImage

actual fun rememberPlatformImagePainter(platformImage: PlatformImage): Painter {
return BitmapPainter(platformImage.bitmap)
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import network.bisq.mobile.domain.data.BackgroundDispatcher
import network.bisq.mobile.domain.data.model.BaseModel
import network.bisq.mobile.utils.Logging

Expand Down Expand Up @@ -47,6 +48,7 @@ abstract class BasePresenter(private val rootPresenter: MainPresenter?): ViewPre
protected var view: Any? = null
// Coroutine scope for the presenter
protected val presenterScope = CoroutineScope(Dispatchers.Main + Job())
protected val backgroundScope = CoroutineScope(BackgroundDispatcher)

private val dependants = if (isRoot()) mutableListOf<BasePresenter>() else null

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import androidx.navigation.NavHostController
import network.bisq.mobile.client.ClientMainPresenter
import network.bisq.mobile.presentation.MainPresenter
import network.bisq.mobile.presentation.ui.AppPresenter
import network.bisq.mobile.presentation.ui.components.molecules.ITopBarPresenter
import network.bisq.mobile.presentation.ui.components.molecules.TopBarPresenter
import network.bisq.mobile.presentation.ui.uicases.GettingStartedPresenter
import network.bisq.mobile.presentation.ui.uicases.IGettingStarted
import network.bisq.mobile.presentation.ui.uicases.offers.MarketListPresenter
Expand All @@ -27,6 +29,8 @@ val presentationModule = module {

single<MainPresenter> { ClientMainPresenter(get(), get(), get()) } bind AppPresenter::class

single<TopBarPresenter> { TopBarPresenter(get(), get()) } bind ITopBarPresenter::class

single {
SplashPresenter(
get(),
Expand All @@ -51,6 +55,7 @@ val presentationModule = module {

single {
CreateProfilePresenter(
get(),
get(),
get()
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ package network.bisq.mobile.presentation.ui.components.atoms.icons
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter
import bisqapps.shared.presentation.generated.resources.Res
import bisqapps.shared.presentation.generated.resources.*
import network.bisq.mobile.domain.PlatformImage
import org.jetbrains.compose.resources.painterResource

expect fun rememberPlatformImagePainter(platformImage: PlatformImage): Painter

@Composable
fun BellIcon(modifier: Modifier = Modifier) {
Image(painterResource(Res.drawable.icon_bell), "Bell icon", modifier = modifier)
Expand All @@ -33,6 +37,12 @@ fun SortIcon(modifier: Modifier = Modifier) {
}

@Composable
fun UserIcon(modifier: Modifier = Modifier) {
Image(painterResource(Res.drawable.img_bot_image), "User icon", modifier = modifier)
fun UserIcon(platformImage: PlatformImage?, modifier: Modifier = Modifier) {
if (platformImage == null) {
// show default
Image(painterResource(Res.drawable.img_bot_image), "User icon", modifier = modifier)
} else {
val painter = rememberPlatformImagePainter(platformImage)
Image(painter = painter, contentDescription = "User icon", modifier = modifier)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package network.bisq.mobile.presentation.ui.components.molecules

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
Expand All @@ -13,9 +12,11 @@ import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import kotlinx.coroutines.flow.StateFlow
import network.bisq.mobile.domain.PlatformImage
import network.bisq.mobile.presentation.ViewPresenter
import network.bisq.mobile.presentation.ui.components.atoms.BisqText
import network.bisq.mobile.presentation.ui.components.atoms.icons.BellIcon
import network.bisq.mobile.presentation.ui.components.atoms.icons.BisqLogoSmall
Expand All @@ -24,6 +25,10 @@ import network.bisq.mobile.presentation.ui.theme.BisqTheme
import org.koin.compose.koinInject
import org.koin.core.qualifier.named

interface ITopBarPresenter: ViewPresenter {
val uniqueAvatar: StateFlow<PlatformImage?>
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TopBar(
Expand All @@ -32,6 +37,7 @@ fun TopBar(
customBackButton: @Composable (() -> Unit)? = null
) {
val navController: NavHostController = koinInject(named("RootNavController"))
val presenter: ITopBarPresenter = koinInject()

val showBackButton = customBackButton == null && navController.previousBackStackEntry != null

Expand Down Expand Up @@ -74,7 +80,7 @@ fun TopBar(
Row(modifier = Modifier.padding(end = 16.dp), verticalAlignment = Alignment.CenterVertically) {
BellIcon(modifier = Modifier.size(30.dp))
Spacer(modifier = Modifier.width(12.dp))
UserIcon(modifier = Modifier.size(30.dp))
UserIcon(presenter.uniqueAvatar.value, modifier = Modifier.size(30.dp))
}
},
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package network.bisq.mobile.presentation.ui.components.molecules

import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import network.bisq.mobile.domain.PlatformImage
import network.bisq.mobile.domain.data.repository.UserRepository
import network.bisq.mobile.presentation.BasePresenter
import network.bisq.mobile.presentation.MainPresenter

open class TopBarPresenter(
private val userRepository: UserRepository,
mainPresenter: MainPresenter
): BasePresenter(mainPresenter), ITopBarPresenter {

private val _uniqueAvatar = MutableStateFlow(userRepository.data.value?.uniqueAvatar)
override val uniqueAvatar: StateFlow<PlatformImage?> get() = _uniqueAvatar

private fun setUniqueAvatar(value: PlatformImage?) {
_uniqueAvatar.value = value
}

init {
refresh()
}

override fun onViewAttached() {
super.onViewAttached()
refresh()
}

private fun refresh() {
backgroundScope.launch {
userRepository.fetch().let {
setUniqueAvatar(it?.uniqueAvatar)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package network.bisq.mobile.presentation.ui.uicases

import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.runtime.*
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import androidx.navigation.compose.currentBackStackEntryAsState
import bisqapps.shared.presentation.generated.resources.*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import network.bisq.mobile.presentation.ui.components.molecules.DirectionToggle
import network.bisq.mobile.presentation.ui.components.molecules.OfferCard
import network.bisq.mobile.presentation.ui.components.molecules.TopBar
import network.bisq.mobile.presentation.ui.helpers.RememberPresenterLifecycle
import network.bisq.mobile.presentation.ui.theme.BisqTheme
import network.bisq.mobile.presentation.ui.theme.BisqUIConstants
import org.koin.compose.koinInject
import org.koin.core.qualifier.named
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import network.bisq.mobile.domain.PlatformImage
import network.bisq.mobile.domain.data.model.User
import network.bisq.mobile.domain.data.repository.UserRepository
import network.bisq.mobile.domain.service.user_profile.UserProfileServiceFacade
import network.bisq.mobile.presentation.BasePresenter
import network.bisq.mobile.presentation.MainPresenter
import network.bisq.mobile.presentation.ui.navigation.Routes

open class CreateProfilePresenter(
mainPresenter: MainPresenter,
private val userRepository: UserRepository,
private val userProfileService: UserProfileServiceFacade
) : BasePresenter(mainPresenter) {

Expand Down Expand Up @@ -69,6 +72,13 @@ open class CreateProfilePresenter(
cancelJob()
}

init {
// if this presenter gets to work, it means there is no profile saved
backgroundScope.launch {
userRepository.create(User())
}
}

// UI handlers
fun onGenerateKeyPair() {
generateKeyPair()
Expand Down Expand Up @@ -110,6 +120,9 @@ open class CreateProfilePresenter(
setId(id)
setNym(nym)
setProfileIcon(profileIcon)
backgroundScope.launch {
userRepository.update(User().apply { uniqueAvatar = profileIcon })
}
}
setGenerateKeyPairInProgress(false)
log.i { "Hide busy animation for generateKeyPair" }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package network.bisq.mobile.presentation.ui.components.atoms.icons

import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.toComposeImageBitmap
import network.bisq.mobile.domain.PlatformImage
import network.bisq.mobile.service.IosImageUtil.toByteArray
import org.jetbrains.skia.Image
import platform.UIKit.UIImage
import platform.UIKit.UIImagePNGRepresentation

actual fun rememberPlatformImagePainter(platformImage: PlatformImage): Painter {
val uiImage = platformImage as UIImage
val skiaImage = uiImage.toSkiaImage()
return BitmapPainter(skiaImage.toComposeImageBitmap())
}

// Helper function to convert UIImage to Skia Image
fun UIImage.toSkiaImage(): Image {
val nsData = UIImagePNGRepresentation(this)!!
val byteArray = nsData.toByteArray()
return Image.makeFromEncoded(byteArray)
}

0 comments on commit 20ecfb1

Please sign in to comment.