Account creation workflow... still need logic.
This commit is contained in:
@@ -9,12 +9,16 @@ import ac.aux.compose.database.dao.PostDao
|
||||
import ac.aux.compose.database.dao.ProfileDao
|
||||
import ac.aux.compose.database.dao.ReactionDao
|
||||
import ac.aux.compose.database.dao.RepostDao
|
||||
import ac.aux.compose.database.dao.UnsignedNostrEventDao
|
||||
import ac.aux.compose.database.dao.ZapDao
|
||||
import ac.aux.compose.database.model.BroadcastNostrEventReceipt
|
||||
import ac.aux.compose.database.model.BroadcastNostrEventRequest
|
||||
import ac.aux.compose.database.model.NostrEvent
|
||||
import ac.aux.compose.database.model.Post
|
||||
import ac.aux.compose.database.model.Profile
|
||||
import ac.aux.compose.database.model.Reaction
|
||||
import ac.aux.compose.database.model.Repost
|
||||
import ac.aux.compose.database.model.UnsignedNostrEvent
|
||||
import ac.aux.compose.database.model.Zap
|
||||
import androidx.room.Database
|
||||
import androidx.room.RoomDatabase
|
||||
@@ -22,11 +26,14 @@ import androidx.room.TypeConverters
|
||||
|
||||
@Database(
|
||||
entities = [
|
||||
BroadcastNostrEventReceipt::class,
|
||||
BroadcastNostrEventRequest::class,
|
||||
NostrEvent::class,
|
||||
Post::class,
|
||||
Profile::class,
|
||||
Reaction::class,
|
||||
Repost::class,
|
||||
UnsignedNostrEvent::class,
|
||||
Zap::class
|
||||
],
|
||||
version = 1
|
||||
@@ -42,5 +49,7 @@ abstract class AuxDatabase: RoomDatabase() {
|
||||
abstract fun profileDao(): ProfileDao
|
||||
abstract fun reactionDao(): ReactionDao
|
||||
abstract fun repostDao(): RepostDao
|
||||
|
||||
abstract fun unsignedNostrEventDao(): UnsignedNostrEventDao
|
||||
abstract fun zapDao(): ZapDao
|
||||
}
|
||||
@@ -20,5 +20,5 @@ interface UnsignedNostrEventDao {
|
||||
fun getUnsignedNostrEventById(id: Long): Flow<UnsignedNostrEvent?>
|
||||
|
||||
@Upsert
|
||||
suspend fun upsert(unsignedNostrEvent: UnsignedNostrEvent)
|
||||
suspend fun upsert(unsignedNostrEvent: UnsignedNostrEvent): Long
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import ac.aux.compose.database.model.traits.LocalStoreEntity
|
||||
import ac.aux.compose.database.model.traits.SoftDeletableEntity
|
||||
import ac.aux.compose.database.model.traits.TimestampedEntity
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Ignore
|
||||
import androidx.room.PrimaryKey
|
||||
import co.touchlab.kermit.Logger
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
@@ -36,7 +37,8 @@ data class NostrEvent(
|
||||
override val deletedAt: Instant? = null,
|
||||
override val broadcastedAt: Instant? = null,
|
||||
): TimestampedEntity, LocalStoreEntity, BroadcastableEntity, SoftDeletableEntity {
|
||||
val logger = Logger.withTag("NostrEvent")
|
||||
@Ignore
|
||||
private val logger = Logger.withTag("NostrEvent")
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package ac.aux.compose.database.repository
|
||||
|
||||
import ac.aux.compose.database.AuxDatabase
|
||||
import ac.aux.compose.database.model.UnsignedNostrEvent
|
||||
import ac.aux.compose.repository.NostrRepository
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
class DatabaseNostrRepository(
|
||||
private val database: AuxDatabase
|
||||
): NostrRepository {
|
||||
|
||||
override suspend fun saveUnsignedNostrEvent(unsignedNostrEvent: UnsignedNostrEvent): UnsignedNostrEvent? = try {
|
||||
delay(2_100) // Just to make it look like we are doing serious work...
|
||||
unsignedNostrEvent.copy(
|
||||
id = database.unsignedNostrEventDao().upsert(unsignedNostrEvent)
|
||||
)
|
||||
} catch (e: Throwable) {
|
||||
null
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package ac.aux.compose.repository
|
||||
|
||||
import ac.aux.compose.database.model.UnsignedNostrEvent
|
||||
|
||||
interface NostrRepository {
|
||||
suspend fun saveUnsignedNostrEvent(unsignedNostrEvent: UnsignedNostrEvent): UnsignedNostrEvent?
|
||||
}
|
||||
@@ -1,6 +1,12 @@
|
||||
package ac.aux.compose.ui.composable
|
||||
|
||||
import ac.aux.compose.database.model.Profile
|
||||
import ac.aux.compose.database.model.UnsignedNostrEvent
|
||||
import ac.aux.compose.repository.NostrRepository
|
||||
import ac.aux.compose.ui.composable.widgets.LoadingDataIndicator
|
||||
import ac.aux.compose.ui.theme.AuxTheme
|
||||
import ac.aux.compose.ui.theme.BluePill
|
||||
import ac.aux.compose.ui.theme.RedPill
|
||||
import ac.aux.compose.ui.view.model.CreateProfileViewModel
|
||||
import ac.aux.compose.ui.view.state.CreateProfileUIState
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
@@ -14,7 +20,11 @@ import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Badge
|
||||
import androidx.compose.material.icons.filled.Description
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.LoadingIndicator
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Surface
|
||||
@@ -23,20 +33,25 @@ import androidx.compose.material3.TextField
|
||||
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.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Composable
|
||||
fun CreateProfileScreen(
|
||||
initialCreateProfileUIState: CreateProfileUIState = CreateProfileUIState.Declaration,
|
||||
onNavigateToChatListRoute: () -> Unit
|
||||
onNavigateToSocialPreconditionRoute: () -> Unit,
|
||||
onEndThis: () -> Unit,
|
||||
nostrRepository: NostrRepository
|
||||
) {
|
||||
val createProfileViewModel: CreateProfileViewModel = viewModel (
|
||||
factory = CreateProfileViewModel.factory(
|
||||
initialCreateProfileUIState
|
||||
initialCreateProfileUIState,
|
||||
nostrRepository
|
||||
)
|
||||
)
|
||||
Scaffold { innerPadding ->
|
||||
@@ -191,11 +206,17 @@ fun CreateProfileScreen(
|
||||
Button(
|
||||
onClick = {
|
||||
|
||||
createProfileViewModel.createProfileUIState.value =
|
||||
CreateProfileUIState.ConfirmInput(
|
||||
name = createProfileViewModel.createProfileFormState.nameField.text.value,
|
||||
bio = createProfileViewModel.createProfileFormState.biographyField.text.value
|
||||
)
|
||||
createProfileViewModel.validateInput().let { isInputValid ->
|
||||
if (isInputValid) {
|
||||
createProfileViewModel.createProfileUIState.value =
|
||||
CreateProfileUIState.ConfirmInput(
|
||||
name = createProfileViewModel.createProfileFormState.nameField.text.value,
|
||||
bio = createProfileViewModel.createProfileFormState.biographyField.text.value
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
@@ -245,13 +266,135 @@ fun CreateProfileScreen(
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
if (createProfileViewModel.isActionPending.value) {
|
||||
LoadingIndicator(
|
||||
modifier = Modifier
|
||||
)
|
||||
} else {
|
||||
Button(
|
||||
onClick = {
|
||||
createProfileViewModel.createAccount()
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
text = "Create Profile"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
is CreateProfileUIState.Error -> {
|
||||
Spacer(
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
Text(
|
||||
text = "Something went wrong and we were unable to sign you up. Please try again later.",
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
Spacer(
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
}
|
||||
is CreateProfileUIState.UnsignedProfile -> {
|
||||
Spacer(
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
Text(
|
||||
text = "Your profile is almost ready... just getting it's first cryptographic signature together.",
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
Text(
|
||||
text = "As long as you control your keys there can be no dispute about who ${createAccountUIState.name} actually is.",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
LoadingDataIndicator(
|
||||
fillScreen = false
|
||||
)
|
||||
|
||||
Spacer(
|
||||
modifier = Modifier.weight(2f)
|
||||
)
|
||||
}
|
||||
is CreateProfileUIState.UnbroadcastedProfile -> {
|
||||
Spacer(
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
Text(
|
||||
text = "Everything is cryptographical sound. Just announcing your profile to the world.",
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
Text(
|
||||
text = "Aux will be broadcast to what you publish to relays so that it's distributed and decentralized.",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
LoadingDataIndicator(
|
||||
fillScreen = false
|
||||
)
|
||||
|
||||
Spacer(
|
||||
modifier = Modifier.weight(2f)
|
||||
)
|
||||
}
|
||||
is CreateProfileUIState.ProfileReady -> {
|
||||
|
||||
Spacer(
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
Text(
|
||||
text = "Profile is ready",
|
||||
style = MaterialTheme.typography.headlineLarge,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
Text(
|
||||
text = "After this there is no turning back."
|
||||
)
|
||||
|
||||
Button(
|
||||
onClick = onNavigateToChatListRoute
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = RedPill,
|
||||
contentColor = Color.White
|
||||
),
|
||||
onClick = {
|
||||
|
||||
onNavigateToSocialPreconditionRoute.invoke()
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
text = "Create Profile"
|
||||
text = "See how deep the rabbit hole goes"
|
||||
)
|
||||
}
|
||||
|
||||
HorizontalDivider(
|
||||
modifier = Modifier.padding(20.dp)
|
||||
)
|
||||
|
||||
Button(
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = BluePill,
|
||||
contentColor = Color.DarkGray
|
||||
),
|
||||
onClick = {
|
||||
// TODO: Delete everything and close the app
|
||||
onEndThis.invoke()
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
text = "end this"
|
||||
)
|
||||
}
|
||||
Spacer(
|
||||
modifier = Modifier.weight(2f)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,13 +413,48 @@ fun CreateAccountScreenPreview() {
|
||||
) {
|
||||
CreateProfileScreen(
|
||||
initialCreateProfileUIState =
|
||||
// CreateProfileUIState.InputPrompt
|
||||
CreateProfileUIState.ConfirmInput(
|
||||
name = "Alan Turing",
|
||||
bio = "Polyglot: Math... is my middle name, computer scientist. cryptographer, and gold hider."
|
||||
// CreateProfileUIState.InputPrompt,
|
||||
// CreateProfileUIState.Error,
|
||||
// CreateProfileUIState.ConfirmInput(
|
||||
// name = "Alan Turing",
|
||||
// bio = "Polyglot: Math... is my middle name, computer scientist. cryptographer, and gold hider."
|
||||
// ),
|
||||
// CreateProfileUIState.UnsignedProfile(
|
||||
// unsignedNostrEvent = UnsignedNostrEvent(
|
||||
// kind = 0,
|
||||
// content = "Something here",
|
||||
// tags = emptyArray(),
|
||||
// ),
|
||||
// name = "Alan Turing",
|
||||
// bio = "Polyglot: Math... is my middle name, computer scientist. cryptographer, and gold hider."
|
||||
// ),
|
||||
// CreateProfileUIState.UnbroadcastedProfile(
|
||||
// nostrEvent = NostrEvent(
|
||||
// id = "",
|
||||
// pubKey = "",
|
||||
// kind = 0,
|
||||
// content = "Something here",
|
||||
// tags = emptyArray(),
|
||||
// sig = ""
|
||||
// ),
|
||||
// name = "Alan Turing",
|
||||
// bio = "Polyglot: Math... is my middle name, computer scientist. cryptographer, and gold hider."
|
||||
// ),
|
||||
CreateProfileUIState.ProfileReady(
|
||||
profile = Profile(
|
||||
publicKey = "",
|
||||
nostrEventId = "",
|
||||
displayName = "Alan Turing",
|
||||
about = "Polyglot: Math... is my middle name, computer scientist. cryptographer, and gold hider."
|
||||
)
|
||||
),
|
||||
onNavigateToChatListRoute = {}
|
||||
)
|
||||
onNavigateToSocialPreconditionRoute = {},
|
||||
onEndThis = {},
|
||||
nostrRepository = object : NostrRepository {
|
||||
override suspend fun saveUnsignedNostrEvent(unsignedNostrEvent: UnsignedNostrEvent): UnsignedNostrEvent? {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,7 +77,7 @@ fun SocialPreconditionScreen(
|
||||
)
|
||||
|
||||
Text(
|
||||
"Tell friends to join you on Aux so your feed stays lively and fresh.",
|
||||
"Tell friends to join you so your feed stays lively and fresh.",
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package ac.aux.compose.ui.composable.navigation
|
||||
|
||||
import ac.aux.compose.database.model.UnsignedNostrEvent
|
||||
import ac.aux.compose.repository.NostrRepository
|
||||
import ac.aux.compose.ui.composable.CreateProfileScreen
|
||||
import ac.aux.compose.ui.composable.FeedScreen
|
||||
import ac.aux.compose.ui.composable.ImplementationPendingScreen
|
||||
import ac.aux.compose.ui.composable.LandingScreen
|
||||
import ac.aux.compose.ui.composable.SocialPreconditionScreen
|
||||
import ac.aux.compose.ui.composable.navigation.routes.BlankRoute
|
||||
import ac.aux.compose.ui.composable.navigation.routes.CreateProfileRoute
|
||||
import ac.aux.compose.ui.composable.navigation.routes.FeedRoute
|
||||
import ac.aux.compose.ui.composable.navigation.routes.ImplementationPendingRoute
|
||||
@@ -18,6 +21,12 @@ import ac.aux.compose.ui.composable.navigation.routes.Route
|
||||
import ac.aux.compose.ui.composable.navigation.routes.SocialPreconditionRoute
|
||||
import ac.aux.compose.ui.composable.widgets.feed.DUMMY_EVENTS
|
||||
import ac.aux.compose.ui.view.state.FeedListUIState
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
@Composable
|
||||
fun AuxNavHost(
|
||||
@@ -50,12 +59,25 @@ fun AuxNavHost(
|
||||
}
|
||||
composable<CreateProfileRoute> {
|
||||
CreateProfileScreen(
|
||||
onNavigateToChatListRoute = {
|
||||
onNavigateToSocialPreconditionRoute = {
|
||||
navController.navigate(
|
||||
route = SocialPreconditionRoute
|
||||
)
|
||||
}
|
||||
)
|
||||
},
|
||||
onEndThis = {
|
||||
// TODO: Delete everything and close the app
|
||||
navController.navigate(
|
||||
route = BlankRoute
|
||||
) {
|
||||
popUpTo(0)
|
||||
}
|
||||
},
|
||||
nostrRepository = object : NostrRepository {
|
||||
override suspend fun saveUnsignedNostrEvent(unsignedNostrEvent: UnsignedNostrEvent): UnsignedNostrEvent? {
|
||||
delay(2_100)
|
||||
return unsignedNostrEvent
|
||||
}
|
||||
})
|
||||
}
|
||||
composable<SocialPreconditionRoute> {
|
||||
SocialPreconditionScreen(
|
||||
@@ -90,6 +112,15 @@ fun AuxNavHost(
|
||||
}
|
||||
)
|
||||
}
|
||||
composable<BlankRoute> {
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
color = Color.Black
|
||||
) {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
composable<ImplementationPendingRoute> { backStackEntry ->
|
||||
val route: ImplementationPendingRoute = backStackEntry.toRoute()
|
||||
ImplementationPendingScreen(
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package ac.aux.compose.ui.composable.navigation.routes
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
object BlankRoute: Route()
|
||||
@@ -2,6 +2,9 @@ package ac.aux.compose.ui.theme
|
||||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
val BluePill = Color(0xFF5D8DD6)
|
||||
val RedPill = Color(230, 32, 32, 191)
|
||||
|
||||
val primaryLight = Color(0xFF000000)
|
||||
val onPrimaryLight = Color(0xFFFFFFFF)
|
||||
val primaryContainerLight = Color(0xFF1B1B1B)
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package ac.aux.compose.ui.view.model
|
||||
|
||||
import ac.aux.compose.database.model.NostrEvent
|
||||
import ac.aux.compose.database.model.Profile
|
||||
import ac.aux.compose.database.model.UnsignedNostrEvent
|
||||
import ac.aux.compose.repository.NostrRepository
|
||||
import ac.aux.compose.ui.view.state.CreateProfileUIState
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
@@ -8,21 +12,31 @@ import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewmodel.initializer
|
||||
import androidx.lifecycle.viewmodel.viewModelFactory
|
||||
import ac.aux.compose.ui.view.state.form.CreateProfileFormState
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import co.touchlab.kermit.Logger
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.IO
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.time.Instant
|
||||
|
||||
class CreateProfileViewModel(
|
||||
val initialCreateProfileUIState: CreateProfileUIState,
|
||||
val createProfileFormState: CreateProfileFormState = CreateProfileFormState(),
|
||||
val nostrRepository: NostrRepository
|
||||
): ViewModel() {
|
||||
companion object {
|
||||
private const val TAG = "CreateAccountViewModel"
|
||||
|
||||
fun factory(
|
||||
initialCreateProfileUIState: CreateProfileUIState
|
||||
initialCreateProfileUIState: CreateProfileUIState,
|
||||
nostrRepository: NostrRepository
|
||||
): ViewModelProvider.Factory = viewModelFactory {
|
||||
initializer {
|
||||
CreateProfileViewModel(
|
||||
initialCreateProfileUIState
|
||||
initialCreateProfileUIState,
|
||||
nostrRepository = nostrRepository
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -36,11 +50,82 @@ class CreateProfileViewModel(
|
||||
initialCreateProfileUIState
|
||||
)
|
||||
|
||||
public fun createAccount(
|
||||
onSuccess: () -> Unit,
|
||||
onFailure: () -> Unit
|
||||
) {
|
||||
fun validateInput(): Boolean {
|
||||
if (createProfileFormState.nameField.text.value.isBlank()) {
|
||||
createProfileFormState.nameField.errorMessage.value = "Please input a display name"
|
||||
return false
|
||||
} else {
|
||||
createProfileFormState.nameField.errorMessage.value = null
|
||||
}
|
||||
|
||||
if (createProfileFormState.biographyField.text.value.isBlank()) {
|
||||
createProfileFormState.biographyField.errorMessage.value = "Please input a biography"
|
||||
return false
|
||||
} else {
|
||||
createProfileFormState.biographyField.errorMessage.value = null
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
public fun createAccount() {
|
||||
logger.d { "createAccount" }
|
||||
onFailure.invoke()
|
||||
isActionPending.value = true
|
||||
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
|
||||
val profileEventTemplate = MetadataEvent.createNew(
|
||||
name = createProfileFormState.nameField.text.value,
|
||||
about = createProfileFormState.biographyField.text.value
|
||||
)
|
||||
|
||||
val unsignedNostrEvent = nostrRepository.saveUnsignedNostrEvent(
|
||||
UnsignedNostrEvent(
|
||||
kind = profileEventTemplate.kind,
|
||||
createdAt = Instant.fromEpochMilliseconds(profileEventTemplate.createdAt),
|
||||
tags = profileEventTemplate.tags,
|
||||
content = profileEventTemplate.content
|
||||
)
|
||||
)
|
||||
|
||||
isActionPending.value = false
|
||||
|
||||
if (unsignedNostrEvent != null) {
|
||||
createProfileUIState.value = CreateProfileUIState.UnsignedProfile(
|
||||
unsignedNostrEvent = unsignedNostrEvent,
|
||||
name = createProfileFormState.nameField.text.value,
|
||||
bio = createProfileFormState.biographyField.text.value
|
||||
)
|
||||
|
||||
delay(7_500) // Seeming busy is very important...
|
||||
|
||||
createProfileUIState.value = CreateProfileUIState.UnbroadcastedProfile(
|
||||
nostrEvent = NostrEvent(
|
||||
id = "",
|
||||
pubKey = "",
|
||||
kind = 0,
|
||||
content = "Something here",
|
||||
tags = emptyArray(),
|
||||
sig = ""
|
||||
),
|
||||
name = createProfileFormState.nameField.text.value,
|
||||
bio = createProfileFormState.biographyField.text.value
|
||||
)
|
||||
|
||||
delay(4_500) // Seeming busy is very important...
|
||||
|
||||
createProfileUIState.value = CreateProfileUIState.ProfileReady(
|
||||
profile = Profile(
|
||||
publicKey = "",
|
||||
nostrEventId = "",
|
||||
displayName = createProfileFormState.nameField.text.value,
|
||||
about = createProfileFormState.biographyField.text.value,
|
||||
)
|
||||
)
|
||||
} else {
|
||||
createProfileUIState.value = CreateProfileUIState.Error
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,11 @@
|
||||
package ac.aux.compose.ui.view.state
|
||||
|
||||
import ac.aux.compose.database.model.NostrEvent
|
||||
import ac.aux.compose.database.model.Profile
|
||||
import ac.aux.compose.database.model.UnsignedNostrEvent
|
||||
|
||||
abstract class CreateProfileUIState {
|
||||
data object Error: CreateProfileUIState()
|
||||
|
||||
data object Declaration: CreateProfileUIState()
|
||||
|
||||
@@ -10,4 +15,20 @@ abstract class CreateProfileUIState {
|
||||
val name: String,
|
||||
val bio: String
|
||||
) : CreateProfileUIState()
|
||||
|
||||
data class UnsignedProfile(
|
||||
val unsignedNostrEvent: UnsignedNostrEvent,
|
||||
val name: String,
|
||||
val bio: String,
|
||||
) : CreateProfileUIState()
|
||||
|
||||
data class UnbroadcastedProfile(
|
||||
val nostrEvent: NostrEvent,
|
||||
val name: String,
|
||||
val bio: String
|
||||
) : CreateProfileUIState()
|
||||
|
||||
data class ProfileReady(
|
||||
val profile: Profile
|
||||
) : CreateProfileUIState()
|
||||
}
|
||||
Reference in New Issue
Block a user