-
Notifications
You must be signed in to change notification settings - Fork 1
/
EditProfileViewModel.kt
98 lines (86 loc) · 3.59 KB
/
EditProfileViewModel.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package com.dluvian.voyage.core.viewModel
import android.util.Log
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.dluvian.nostr_kt.getMetadata
import com.dluvian.nostr_kt.secs
import com.dluvian.voyage.R
import com.dluvian.voyage.core.DELAY_1SEC
import com.dluvian.voyage.core.EditProfileViewAction
import com.dluvian.voyage.core.LoadFullProfile
import com.dluvian.voyage.core.SaveProfile
import com.dluvian.voyage.core.launchIO
import com.dluvian.voyage.core.showToast
import com.dluvian.voyage.core.toRelevantMetadata
import com.dluvian.voyage.data.inMemory.MetadataInMemory
import com.dluvian.voyage.data.nostr.NostrService
import com.dluvian.voyage.data.provider.RelayProvider
import com.dluvian.voyage.data.room.dao.FullProfileDao
import com.dluvian.voyage.data.room.dao.tx.FullProfileUpsertDao
import com.dluvian.voyage.data.room.dao.tx.ProfileUpsertDao
import com.dluvian.voyage.data.room.entity.FullProfileEntity
import com.dluvian.voyage.data.room.entity.ProfileEntity
import kotlinx.coroutines.delay
import rust.nostr.protocol.Event
private const val TAG = "EditProfileViewModel"
class EditProfileViewModel(
private val fullProfileUpsertDao: FullProfileUpsertDao,
private val nostrService: NostrService,
private val snackbar: SnackbarHostState,
private val relayProvider: RelayProvider,
private val fullProfileDao: FullProfileDao,
private val metadataInMemory: MetadataInMemory,
private val profileUpsertDao: ProfileUpsertDao,
) : ViewModel() {
val isSaving = mutableStateOf(false)
val fullProfile = mutableStateOf<FullProfileEntity?>(null)
fun handle(action: EditProfileViewAction) {
when (action) {
is LoadFullProfile -> loadProfile()
is SaveProfile -> saveProfile(action = action)
}
}
private fun loadProfile() {
viewModelScope.launchIO {
fullProfile.value = fullProfileDao.getFullProfile()
}
}
private fun saveProfile(action: SaveProfile) {
if (isSaving.value) return
isSaving.value = true
viewModelScope.launchIO {
val result = nostrService.publishProfile(
metadata = action.metadata,
relayUrls = relayProvider.getPublishRelays(),
signerLauncher = action.signerLauncher
)
if (result.isSuccess) saveInDb(event = result.getOrThrow())
else Log.w(TAG, "Failed to sign profile", result.exceptionOrNull())
delay(DELAY_1SEC)
action.onGoBack()
val msgId = if (result.isSuccess) R.string.profile_updated
else R.string.failed_to_sign_profile
snackbar.showToast(viewModelScope, action.context.getString(msgId))
}.invokeOnCompletion { isSaving.value = false }
}
private suspend fun saveInDb(event: Event) {
val entity = FullProfileEntity.from(event = event)
if (entity == null) {
Log.w(TAG, "Failed to create FullProfileEntity from event")
return
}
event.getMetadata()?.let { metadata ->
metadataInMemory.submit(
pubkey = entity.pubkey,
metadata = metadata.toRelevantMetadata(event.createdAt().secs())
)
}
profileUpsertDao.upsertProfiles(
profiles = listOf(ProfileEntity.from(fullProfileEntity = entity))
)
fullProfileUpsertDao.upsertProfile(profile = entity)
fullProfile.value = entity
}
}