Adds NIP19 parser to the AccountViewModel thread scope

This commit is contained in:
Vitor Pamplona
2023-09-25 11:35:39 -04:00
parent f2b6a9bedb
commit fc4433e7ae
4 changed files with 29 additions and 26 deletions
@@ -32,7 +32,6 @@ import com.halilibo.richtext.markdown.Markdown
import com.halilibo.richtext.markdown.MarkdownParseOptions import com.halilibo.richtext.markdown.MarkdownParseOptions
import com.halilibo.richtext.ui.material.MaterialRichText import com.halilibo.richtext.ui.material.MaterialRichText
import com.vitorpamplona.amethyst.model.HashtagIcon import com.vitorpamplona.amethyst.model.HashtagIcon
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.model.checkForHashtagWithIcon import com.vitorpamplona.amethyst.model.checkForHashtagWithIcon
@@ -57,6 +56,7 @@ import com.vitorpamplona.amethyst.ui.note.LoadUser
import com.vitorpamplona.amethyst.ui.note.NoteCompose import com.vitorpamplona.amethyst.ui.note.NoteCompose
import com.vitorpamplona.amethyst.ui.note.toShortenHex import com.vitorpamplona.amethyst.ui.note.toShortenHex
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.LoadedBechLink
import com.vitorpamplona.amethyst.ui.theme.Font17SP import com.vitorpamplona.amethyst.ui.theme.Font17SP
import com.vitorpamplona.amethyst.ui.theme.HalfVertPadding import com.vitorpamplona.amethyst.ui.theme.HalfVertPadding
import com.vitorpamplona.amethyst.ui.theme.MarkdownTextStyle import com.vitorpamplona.amethyst.ui.theme.MarkdownTextStyle
@@ -404,7 +404,7 @@ private fun ObserveNIP19Event(
if (baseNote == null) { if (baseNote == null) {
LaunchedEffect(key1 = it.hex) { LaunchedEffect(key1 = it.hex) {
if (it.type == Nip19.Type.NOTE || it.type == Nip19.Type.EVENT || it.type == Nip19.Type.ADDRESS) { if (it.type == Nip19.Type.NOTE || it.type == Nip19.Type.EVENT || it.type == Nip19.Type.ADDRESS) {
accountViewModel.checkGetOrCreateNote(it.hex)?.let { note -> accountViewModel.checkGetOrCreateNote(it.hex) { note ->
launch(Dispatchers.Main) { baseNote = note } launch(Dispatchers.Main) { baseNote = note }
} }
} }
@@ -461,30 +461,14 @@ private fun ObserveUser(user: User, onRefresh: () -> Unit) {
} }
} }
@Immutable
data class LoadedBechLink(val baseNote: Note?, val nip19: Nip19.Return)
@Composable @Composable
fun BechLink(word: String, canPreview: Boolean, backgroundColor: MutableState<Color>, accountViewModel: AccountViewModel, nav: (String) -> Unit) { fun BechLink(word: String, canPreview: Boolean, backgroundColor: MutableState<Color>, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
var loadedLink by remember { mutableStateOf<LoadedBechLink?>(null) } var loadedLink by remember { mutableStateOf<LoadedBechLink?>(null) }
if (loadedLink == null) { if (loadedLink == null) {
LaunchedEffect(key1 = word) { LaunchedEffect(key1 = word) {
launch(Dispatchers.IO) { accountViewModel.parseNIP19(word) {
Nip19.uriToRoute(word)?.let { loadedLink = it
var returningNote: Note? = null
if (it.type == Nip19.Type.NOTE || it.type == Nip19.Type.EVENT || it.type == Nip19.Type.ADDRESS) {
LocalCache.checkGetOrCreateNote(it.hex)?.let { note ->
returningNote = note
}
}
val newLink = LoadedBechLink(returningNote, it)
launch(Dispatchers.Main) {
loadedLink = newLink
}
}
} }
} }
} }
@@ -504,7 +488,7 @@ fun BechLink(word: String, canPreview: Boolean, backgroundColor: MutableState<Co
ClickableRoute(loadedLink?.nip19!!, accountViewModel, nav) ClickableRoute(loadedLink?.nip19!!, accountViewModel, nav)
} }
} else { } else {
val text = remember { val text = remember(word) {
if (word.length > 16) { if (word.length > 16) {
word.replaceRange(8, word.length - 8, ":") word.replaceRange(8, word.length - 8, ":")
} else { } else {
@@ -233,7 +233,7 @@ fun NoteCompose(
) { ) {
val hasEvent by baseNote.live().hasEvent.observeAsState(baseNote.event != null) val hasEvent by baseNote.live().hasEvent.observeAsState(baseNote.event != null)
Crossfade(targetState = hasEvent) { Crossfade(targetState = hasEvent, label = "Event presence") {
if (it) { if (it) {
CheckHiddenNoteCompose( CheckHiddenNoteCompose(
note = baseNote, note = baseNote,
@@ -114,10 +114,11 @@ private fun VerticalDivider(color: Color) =
fun LongPressToQuickAction(baseNote: Note, accountViewModel: AccountViewModel, content: @Composable (() -> Unit) -> Unit) { fun LongPressToQuickAction(baseNote: Note, accountViewModel: AccountViewModel, content: @Composable (() -> Unit) -> Unit) {
val popupExpanded = remember { mutableStateOf(false) } val popupExpanded = remember { mutableStateOf(false) }
val showPopup = remember { { popupExpanded.value = true } } val showPopup = remember { { popupExpanded.value = true } }
val hidePopup = remember { { popupExpanded.value = false } }
content(showPopup) content(showPopup)
NoteQuickActionMenu(baseNote, popupExpanded.value, { popupExpanded.value = false }, accountViewModel) NoteQuickActionMenu(baseNote, popupExpanded.value, hidePopup, accountViewModel)
} }
@Composable @Composable
@@ -606,7 +606,7 @@ class AccountViewModel(val account: Account) : ViewModel(), Dao {
return LocalCache.getUserIfExists(hex) return LocalCache.getUserIfExists(hex)
} }
suspend fun checkGetOrCreateNote(key: HexKey): Note? { private suspend fun checkGetOrCreateNote(key: HexKey): Note? {
return LocalCache.checkGetOrCreateNote(key) return LocalCache.checkGetOrCreateNote(key)
} }
@@ -634,7 +634,7 @@ class AccountViewModel(val account: Account) : ViewModel(), Dao {
} }
} }
suspend fun getOrCreateAddressableNote(key: ATag): AddressableNote? { private suspend fun getOrCreateAddressableNote(key: ATag): AddressableNote? {
return LocalCache.getOrCreateAddressableNote(key) return LocalCache.getOrCreateAddressableNote(key)
} }
@@ -654,7 +654,7 @@ class AccountViewModel(val account: Account) : ViewModel(), Dao {
} }
} }
suspend fun checkGetOrCreateChannel(key: HexKey): Channel? { private suspend fun checkGetOrCreateChannel(key: HexKey): Channel? {
return LocalCache.checkGetOrCreateChannel(key) return LocalCache.checkGetOrCreateChannel(key)
} }
@@ -705,9 +705,27 @@ class AccountViewModel(val account: Account) : ViewModel(), Dao {
} }
} }
fun parseNIP19(str: String, onNote: (LoadedBechLink) -> Unit) {
viewModelScope.launch(Dispatchers.IO) {
Nip19.uriToRoute(str)?.let {
var returningNote: Note? = null
if (it.type == Nip19.Type.NOTE || it.type == Nip19.Type.EVENT || it.type == Nip19.Type.ADDRESS) {
LocalCache.checkGetOrCreateNote(it.hex)?.let { note ->
returningNote = note
}
}
onNote(LoadedBechLink(returningNote, it))
}
}
}
class Factory(val account: Account) : ViewModelProvider.Factory { class Factory(val account: Account) : ViewModelProvider.Factory {
override fun <AccountViewModel : ViewModel> create(modelClass: Class<AccountViewModel>): AccountViewModel { override fun <AccountViewModel : ViewModel> create(modelClass: Class<AccountViewModel>): AccountViewModel {
return AccountViewModel(account) as AccountViewModel return AccountViewModel(account) as AccountViewModel
} }
} }
} }
@Immutable
data class LoadedBechLink(val baseNote: Note?, val nip19: Nip19.Return)