Code clean up
This commit is contained in:
@@ -3,7 +3,7 @@ package com.vitorpamplona.amethyst
|
|||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import com.vitorpamplona.amethyst.service.RichTextParser
|
import com.vitorpamplona.amethyst.service.RichTextParser
|
||||||
import com.vitorpamplona.amethyst.service.RichTextViewerState
|
import com.vitorpamplona.amethyst.service.RichTextViewerState
|
||||||
import com.vitorpamplona.quartz.events.ImmutableListOfLists
|
import com.vitorpamplona.quartz.events.EmptyTagList
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
@@ -666,7 +666,7 @@ class RichTextParserTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testTextToParse() {
|
fun testTextToParse() {
|
||||||
val state = RichTextParser().parseText(textToParse, ImmutableListOfLists())
|
val state = RichTextParser().parseText(textToParse, EmptyTagList)
|
||||||
Assert.assertEquals(
|
Assert.assertEquals(
|
||||||
"relay.shitforce.one, relayable.org, universe.nostrich.land, nos.lol, universe.nostrich.land?lang=zh, universe.nostrich.land?lang=en, relay.damus.io, relay.nostr.wirednet.jp, offchain.pub, nostr.rocks, relay.wellorder.net, nostr.oxtr.dev, universe.nostrich.land?lang=ja, relay.mostr.pub, nostr.bitcoiner.social, Nostr-Check.com, MR.Rabbit, Ancap.su, zapper.lol, smies.me, baller.hodl",
|
"relay.shitforce.one, relayable.org, universe.nostrich.land, nos.lol, universe.nostrich.land?lang=zh, universe.nostrich.land?lang=en, relay.damus.io, relay.nostr.wirednet.jp, offchain.pub, nostr.rocks, relay.wellorder.net, nostr.oxtr.dev, universe.nostrich.land?lang=ja, relay.mostr.pub, nostr.bitcoiner.social, Nostr-Check.com, MR.Rabbit, Ancap.su, zapper.lol, smies.me, baller.hodl",
|
||||||
state.urlSet.joinToString(", ")
|
state.urlSet.joinToString(", ")
|
||||||
@@ -3989,7 +3989,7 @@ class RichTextParserTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testShortTextToParse() {
|
fun testShortTextToParse() {
|
||||||
val state = RichTextParser().parseText("Hi, how are you doing? ", ImmutableListOfLists())
|
val state = RichTextParser().parseText("Hi, how are you doing? ", EmptyTagList)
|
||||||
Assert.assertTrue(state.urlSet.isEmpty())
|
Assert.assertTrue(state.urlSet.isEmpty())
|
||||||
Assert.assertTrue(state.imagesForPager.isEmpty())
|
Assert.assertTrue(state.imagesForPager.isEmpty())
|
||||||
Assert.assertTrue(state.imageList.isEmpty())
|
Assert.assertTrue(state.imageList.isEmpty())
|
||||||
@@ -3999,7 +3999,7 @@ class RichTextParserTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testShortNewLinesTextToParse() {
|
fun testShortNewLinesTextToParse() {
|
||||||
val state = RichTextParser().parseText("\nHi, \nhow\n\n\n are you doing? \n", ImmutableListOfLists())
|
val state = RichTextParser().parseText("\nHi, \nhow\n\n\n are you doing? \n", EmptyTagList)
|
||||||
Assert.assertTrue(state.urlSet.isEmpty())
|
Assert.assertTrue(state.urlSet.isEmpty())
|
||||||
Assert.assertTrue(state.imagesForPager.isEmpty())
|
Assert.assertTrue(state.imagesForPager.isEmpty())
|
||||||
Assert.assertTrue(state.imageList.isEmpty())
|
Assert.assertTrue(state.imageList.isEmpty())
|
||||||
@@ -4019,7 +4019,7 @@ See how it can be done here: https://lnshort.it/live-stream-embeds/
|
|||||||
https://nostr.build/i/fd53fcf5ad950fbe45127e4bcee1b59e8301d41de6beee211f45e344db214e8a.jpg
|
https://nostr.build/i/fd53fcf5ad950fbe45127e4bcee1b59e8301d41de6beee211f45e344db214e8a.jpg
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
|
||||||
val state = RichTextParser().parseText(text, ImmutableListOfLists())
|
val state = RichTextParser().parseText(text, EmptyTagList)
|
||||||
Assert.assertEquals("https://lnshort.it/live-stream-embeds/", state.urlSet.firstOrNull())
|
Assert.assertEquals("https://lnshort.it/live-stream-embeds/", state.urlSet.firstOrNull())
|
||||||
Assert.assertEquals("https://nostr.build/i/fd53fcf5ad950fbe45127e4bcee1b59e8301d41de6beee211f45e344db214e8a.jpg", state.imagesForPager.keys.firstOrNull())
|
Assert.assertEquals("https://nostr.build/i/fd53fcf5ad950fbe45127e4bcee1b59e8301d41de6beee211f45e344db214e8a.jpg", state.imagesForPager.keys.firstOrNull())
|
||||||
Assert.assertEquals("https://nostr.build/i/fd53fcf5ad950fbe45127e4bcee1b59e8301d41de6beee211f45e344db214e8a.jpg", state.imageList.firstOrNull()?.url)
|
Assert.assertEquals("https://nostr.build/i/fd53fcf5ad950fbe45127e4bcee1b59e8301d41de6beee211f45e344db214e8a.jpg", state.imageList.firstOrNull()?.url)
|
||||||
@@ -4080,7 +4080,7 @@ https://nostr.build/i/fd53fcf5ad950fbe45127e4bcee1b59e8301d41de6beee211f45e344db
|
|||||||
fun testNewLineAfterImage() {
|
fun testNewLineAfterImage() {
|
||||||
val text = "That’s it ! That’s the #note https://cdn.nostr.build/i/1dc0726b6cb0f94a92bd66765ffb90f6c67e90c17bb957fc3d5d4782cbd73de7.jpg "
|
val text = "That’s it ! That’s the #note https://cdn.nostr.build/i/1dc0726b6cb0f94a92bd66765ffb90f6c67e90c17bb957fc3d5d4782cbd73de7.jpg "
|
||||||
|
|
||||||
val state = RichTextParser().parseText(text, ImmutableListOfLists())
|
val state = RichTextParser().parseText(text, EmptyTagList)
|
||||||
|
|
||||||
printStateForDebug(state)
|
printStateForDebug(state)
|
||||||
|
|
||||||
@@ -4106,7 +4106,7 @@ https://nostr.build/i/fd53fcf5ad950fbe45127e4bcee1b59e8301d41de6beee211f45e344db
|
|||||||
fun testSapceAfterImage() {
|
fun testSapceAfterImage() {
|
||||||
val text = "That’s it! https://cdn.nostr.build/i/1dc0726b6cb0f94a92bd66765ffb90f6c67e90c17bb957fc3d5d4782cbd73de7.jpg That’s the #note"
|
val text = "That’s it! https://cdn.nostr.build/i/1dc0726b6cb0f94a92bd66765ffb90f6c67e90c17bb957fc3d5d4782cbd73de7.jpg That’s the #note"
|
||||||
|
|
||||||
val state = RichTextParser().parseText(text, ImmutableListOfLists())
|
val state = RichTextParser().parseText(text, EmptyTagList)
|
||||||
|
|
||||||
printStateForDebug(state)
|
printStateForDebug(state)
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import kotlinx.coroutines.withContext
|
|||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
|
import java.lang.IllegalArgumentException
|
||||||
|
|
||||||
private const val ELEMENT_TAG_META = "meta"
|
private const val ELEMENT_TAG_META = "meta"
|
||||||
private const val ATTRIBUTE_VALUE_PROPERTY = "property"
|
private const val ATTRIBUTE_VALUE_PROPERTY = "property"
|
||||||
@@ -64,7 +65,11 @@ suspend fun getDocument(url: String, timeOut: Int = 30000): Document =
|
|||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
val request: Request = Request.Builder().url(url).get().build()
|
val request: Request = Request.Builder().url(url).get().build()
|
||||||
val html = HttpClient.getHttpClient().newCall(request).execute().use {
|
val html = HttpClient.getHttpClient().newCall(request).execute().use {
|
||||||
it.body.string()
|
if (it.isSuccessful) {
|
||||||
|
it.body.string()
|
||||||
|
} else {
|
||||||
|
throw IllegalArgumentException("Website returned: " + it.code)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Jsoup.parse(html)
|
Jsoup.parse(html)
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ fun UrlPreviewCard(
|
|||||||
style = MaterialTheme.typography.caption,
|
style = MaterialTheme.typography.caption,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(start = 10.dp, end = 10.dp, top = 10.dp),
|
.padding(start = 10.dp, end = 10.dp, top = 5.dp),
|
||||||
color = Color.Gray,
|
color = Color.Gray,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis
|
overflow = TextOverflow.Ellipsis
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import androidx.compose.runtime.LaunchedEffect
|
|||||||
import androidx.compose.runtime.MutableState
|
import androidx.compose.runtime.MutableState
|
||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
@@ -612,7 +613,7 @@ fun Waveform(
|
|||||||
DrawWaveform(waveform, waveformProgress, modifier)
|
DrawWaveform(waveform, waveformProgress, modifier)
|
||||||
|
|
||||||
val restartFlow = remember {
|
val restartFlow = remember {
|
||||||
mutableStateOf(0)
|
mutableIntStateOf(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keeps the screen on while playing and viewing videos.
|
// Keeps the screen on while playing and viewing videos.
|
||||||
|
|||||||
@@ -477,14 +477,16 @@ private fun AddedImageFeatures(
|
|||||||
if (content.blurhash != null) {
|
if (content.blurhash != null) {
|
||||||
DisplayBlurHash(content.blurhash, content.description, contentScale, myModifier)
|
DisplayBlurHash(content.blurhash, content.description, contentScale, myModifier)
|
||||||
} else {
|
} else {
|
||||||
FlowRow() {
|
FlowRow(Modifier.fillMaxWidth()) {
|
||||||
DisplayUrlWithLoadingSymbol(content)
|
DisplayUrlWithLoadingSymbol(content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is AsyncImagePainter.State.Error -> {
|
is AsyncImagePainter.State.Error -> {
|
||||||
ClickableUrl(urlText = "${content.url} ", url = content.url)
|
FlowRow(Modifier.fillMaxWidth()) {
|
||||||
|
ClickableUrl(urlText = "${content.url} ", url = content.url)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is AsyncImagePainter.State.Success -> {
|
is AsyncImagePainter.State.Success -> {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import androidx.compose.runtime.MutableState
|
|||||||
import androidx.compose.runtime.derivedStateOf
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.livedata.observeAsState
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
@@ -66,6 +67,7 @@ import com.vitorpamplona.amethyst.ui.theme.subtleBorder
|
|||||||
import com.vitorpamplona.quartz.events.ChannelCreateEvent
|
import com.vitorpamplona.quartz.events.ChannelCreateEvent
|
||||||
import com.vitorpamplona.quartz.events.ChannelMetadataEvent
|
import com.vitorpamplona.quartz.events.ChannelMetadataEvent
|
||||||
import com.vitorpamplona.quartz.events.ChatMessageEvent
|
import com.vitorpamplona.quartz.events.ChatMessageEvent
|
||||||
|
import com.vitorpamplona.quartz.events.EmptyTagList
|
||||||
import com.vitorpamplona.quartz.events.ImmutableListOfLists
|
import com.vitorpamplona.quartz.events.ImmutableListOfLists
|
||||||
import com.vitorpamplona.quartz.events.PrivateDmEvent
|
import com.vitorpamplona.quartz.events.PrivateDmEvent
|
||||||
import com.vitorpamplona.quartz.events.toImmutableListOfLists
|
import com.vitorpamplona.quartz.events.toImmutableListOfLists
|
||||||
@@ -285,7 +287,7 @@ fun NormalChatNote(
|
|||||||
modifier = modif,
|
modifier = modif,
|
||||||
horizontalArrangement = alignment
|
horizontalArrangement = alignment
|
||||||
) {
|
) {
|
||||||
val availableBubbleSize = remember { mutableStateOf(0) }
|
val availableBubbleSize = remember { mutableIntStateOf(0) }
|
||||||
var popupExpanded by remember { mutableStateOf(false) }
|
var popupExpanded by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
val modif2 = remember {
|
val modif2 = remember {
|
||||||
@@ -355,7 +357,7 @@ private fun RenderBubble(
|
|||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: (String) -> Unit
|
nav: (String) -> Unit
|
||||||
) {
|
) {
|
||||||
val bubbleSize = remember { mutableStateOf(0) }
|
val bubbleSize = remember { mutableIntStateOf(0) }
|
||||||
|
|
||||||
val bubbleModifier = remember {
|
val bubbleModifier = remember {
|
||||||
Modifier
|
Modifier
|
||||||
@@ -626,7 +628,7 @@ private fun RenderRegularTextNote(
|
|||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: (String) -> Unit
|
nav: (String) -> Unit
|
||||||
) {
|
) {
|
||||||
val tags = remember(note.event) { note.event?.tags()?.toImmutableListOfLists() ?: ImmutableListOfLists() }
|
val tags = remember(note.event) { note.event?.tags()?.toImmutableListOfLists() ?: EmptyTagList }
|
||||||
val eventContent by remember { mutableStateOf(accountViewModel.decrypt(note)) }
|
val eventContent by remember { mutableStateOf(accountViewModel.decrypt(note)) }
|
||||||
val modifier = remember { Modifier.padding(top = 5.dp) }
|
val modifier = remember { Modifier.padding(top = 5.dp) }
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ import com.vitorpamplona.amethyst.ui.theme.bitcoinColor
|
|||||||
import com.vitorpamplona.amethyst.ui.theme.newItemBackgroundColor
|
import com.vitorpamplona.amethyst.ui.theme.newItemBackgroundColor
|
||||||
import com.vitorpamplona.amethyst.ui.theme.overPictureBackground
|
import com.vitorpamplona.amethyst.ui.theme.overPictureBackground
|
||||||
import com.vitorpamplona.amethyst.ui.theme.profile35dpModifier
|
import com.vitorpamplona.amethyst.ui.theme.profile35dpModifier
|
||||||
import com.vitorpamplona.quartz.events.ImmutableListOfLists
|
import com.vitorpamplona.quartz.events.EmptyTagList
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -484,7 +484,7 @@ fun CrossfadeToDisplayComment(
|
|||||||
TranslatableRichTextViewer(
|
TranslatableRichTextViewer(
|
||||||
content = it,
|
content = it,
|
||||||
canPreview = true,
|
canPreview = true,
|
||||||
tags = remember { ImmutableListOfLists() },
|
tags = EmptyTagList,
|
||||||
modifier = textBoxModifier,
|
modifier = textBoxModifier,
|
||||||
backgroundColor = backgroundColor,
|
backgroundColor = backgroundColor,
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
|
|||||||
@@ -179,12 +179,12 @@ import com.vitorpamplona.quartz.events.CommunityPostApprovalEvent
|
|||||||
import com.vitorpamplona.quartz.events.EmojiPackEvent
|
import com.vitorpamplona.quartz.events.EmojiPackEvent
|
||||||
import com.vitorpamplona.quartz.events.EmojiPackSelectionEvent
|
import com.vitorpamplona.quartz.events.EmojiPackSelectionEvent
|
||||||
import com.vitorpamplona.quartz.events.EmojiUrl
|
import com.vitorpamplona.quartz.events.EmojiUrl
|
||||||
|
import com.vitorpamplona.quartz.events.EmptyTagList
|
||||||
import com.vitorpamplona.quartz.events.EventInterface
|
import com.vitorpamplona.quartz.events.EventInterface
|
||||||
import com.vitorpamplona.quartz.events.FileHeaderEvent
|
import com.vitorpamplona.quartz.events.FileHeaderEvent
|
||||||
import com.vitorpamplona.quartz.events.FileStorageHeaderEvent
|
import com.vitorpamplona.quartz.events.FileStorageHeaderEvent
|
||||||
import com.vitorpamplona.quartz.events.GenericRepostEvent
|
import com.vitorpamplona.quartz.events.GenericRepostEvent
|
||||||
import com.vitorpamplona.quartz.events.HighlightEvent
|
import com.vitorpamplona.quartz.events.HighlightEvent
|
||||||
import com.vitorpamplona.quartz.events.ImmutableListOfLists
|
|
||||||
import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent
|
import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent
|
||||||
import com.vitorpamplona.quartz.events.LiveActivitiesEvent
|
import com.vitorpamplona.quartz.events.LiveActivitiesEvent
|
||||||
import com.vitorpamplona.quartz.events.LiveActivitiesEvent.Companion.STATUS_LIVE
|
import com.vitorpamplona.quartz.events.LiveActivitiesEvent.Companion.STATUS_LIVE
|
||||||
@@ -631,7 +631,7 @@ fun LongCommunityHeader(
|
|||||||
TranslatableRichTextViewer(
|
TranslatableRichTextViewer(
|
||||||
content = summary ?: stringResource(id = R.string.community_no_descriptor),
|
content = summary ?: stringResource(id = R.string.community_no_descriptor),
|
||||||
canPreview = false,
|
canPreview = false,
|
||||||
tags = remember { ImmutableListOfLists(emptyList()) },
|
tags = EmptyTagList,
|
||||||
backgroundColor = background,
|
backgroundColor = background,
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav
|
nav = nav
|
||||||
@@ -1343,7 +1343,7 @@ fun RenderTextEvent(
|
|||||||
accountViewModel = accountViewModel
|
accountViewModel = accountViewModel
|
||||||
) {
|
) {
|
||||||
val modifier = remember(note) { Modifier.fillMaxWidth() }
|
val modifier = remember(note) { Modifier.fillMaxWidth() }
|
||||||
val tags = remember(note) { note.event?.tags()?.toImmutableListOfLists() ?: ImmutableListOfLists() }
|
val tags = remember(note) { note.event?.tags()?.toImmutableListOfLists() ?: EmptyTagList }
|
||||||
|
|
||||||
TranslatableRichTextViewer(
|
TranslatableRichTextViewer(
|
||||||
content = eventContent,
|
content = eventContent,
|
||||||
@@ -1382,7 +1382,7 @@ fun RenderPoll(
|
|||||||
overflow = TextOverflow.Ellipsis
|
overflow = TextOverflow.Ellipsis
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
val tags = remember(note) { note.event?.tags()?.toImmutableListOfLists() ?: ImmutableListOfLists() }
|
val tags = remember(note) { note.event?.tags()?.toImmutableListOfLists() ?: EmptyTagList }
|
||||||
|
|
||||||
SensitivityWarning(
|
SensitivityWarning(
|
||||||
note = note,
|
note = note,
|
||||||
@@ -1557,7 +1557,7 @@ fun RenderAppDefinition(
|
|||||||
Row(
|
Row(
|
||||||
modifier = Modifier.padding(top = 5.dp, bottom = 5.dp)
|
modifier = Modifier.padding(top = 5.dp, bottom = 5.dp)
|
||||||
) {
|
) {
|
||||||
val tags = remember(note) { note.event?.tags()?.toImmutableListOfLists() ?: ImmutableListOfLists() }
|
val tags = remember(note) { note.event?.tags()?.toImmutableListOfLists() ?: EmptyTagList }
|
||||||
val bgColor = MaterialTheme.colors.background
|
val bgColor = MaterialTheme.colors.background
|
||||||
val backgroundColor = remember {
|
val backgroundColor = remember {
|
||||||
mutableStateOf(bgColor)
|
mutableStateOf(bgColor)
|
||||||
@@ -1630,7 +1630,7 @@ private fun RenderPrivateMessage(
|
|||||||
val modifier = remember(note.event?.id()) { Modifier.fillMaxWidth() }
|
val modifier = remember(note.event?.id()) { Modifier.fillMaxWidth() }
|
||||||
val isAuthorTheLoggedUser = remember(note.event?.id()) { accountViewModel.isLoggedUser(note.author) }
|
val isAuthorTheLoggedUser = remember(note.event?.id()) { accountViewModel.isLoggedUser(note.author) }
|
||||||
|
|
||||||
val tags = remember(note) { note.event?.tags()?.toImmutableListOfLists() ?: ImmutableListOfLists() }
|
val tags = remember(note) { note.event?.tags()?.toImmutableListOfLists() ?: EmptyTagList }
|
||||||
|
|
||||||
if (eventContent != null) {
|
if (eventContent != null) {
|
||||||
if (makeItShort && isAuthorTheLoggedUser) {
|
if (makeItShort && isAuthorTheLoggedUser) {
|
||||||
@@ -1670,7 +1670,7 @@ private fun RenderPrivateMessage(
|
|||||||
),
|
),
|
||||||
canPreview = !makeItShort,
|
canPreview = !makeItShort,
|
||||||
Modifier.fillMaxWidth(),
|
Modifier.fillMaxWidth(),
|
||||||
ImmutableListOfLists(),
|
EmptyTagList,
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
accountViewModel,
|
accountViewModel,
|
||||||
nav
|
nav
|
||||||
@@ -2308,7 +2308,7 @@ fun RenderPinListEvent(
|
|||||||
TranslatableRichTextViewer(
|
TranslatableRichTextViewer(
|
||||||
content = pin,
|
content = pin,
|
||||||
canPreview = true,
|
canPreview = true,
|
||||||
tags = remember { ImmutableListOfLists() },
|
tags = EmptyTagList,
|
||||||
backgroundColor = backgroundColor,
|
backgroundColor = backgroundColor,
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav
|
nav = nav
|
||||||
@@ -2407,8 +2407,8 @@ private fun RenderReport(
|
|||||||
TranslatableRichTextViewer(
|
TranslatableRichTextViewer(
|
||||||
content = content,
|
content = content,
|
||||||
canPreview = true,
|
canPreview = true,
|
||||||
modifier = remember { Modifier },
|
modifier = Modifier,
|
||||||
tags = remember { ImmutableListOfLists() },
|
tags = EmptyTagList,
|
||||||
backgroundColor = backgroundColor,
|
backgroundColor = backgroundColor,
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav
|
nav = nav
|
||||||
@@ -2880,7 +2880,7 @@ fun DisplayHighlight(
|
|||||||
quote,
|
quote,
|
||||||
canPreview = canPreview && !makeItShort,
|
canPreview = canPreview && !makeItShort,
|
||||||
remember { Modifier.fillMaxWidth() },
|
remember { Modifier.fillMaxWidth() },
|
||||||
remember { ImmutableListOfLists<String>(emptyList()) },
|
EmptyTagList,
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
accountViewModel,
|
accountViewModel,
|
||||||
nav
|
nav
|
||||||
@@ -3527,7 +3527,7 @@ fun AudioHeader(noteEvent: AudioHeaderEvent, note: Note, accountViewModel: Accou
|
|||||||
|
|
||||||
val defaultBackground = MaterialTheme.colors.background
|
val defaultBackground = MaterialTheme.colors.background
|
||||||
val background = remember { mutableStateOf(defaultBackground) }
|
val background = remember { mutableStateOf(defaultBackground) }
|
||||||
val tags = remember(noteEvent) { noteEvent?.tags()?.toImmutableListOfLists() ?: ImmutableListOfLists() }
|
val tags = remember(noteEvent) { noteEvent?.tags()?.toImmutableListOfLists() ?: EmptyTagList }
|
||||||
|
|
||||||
val eventContent = remember(note.event) {
|
val eventContent = remember(note.event) {
|
||||||
val subject = (note.event as? TextNoteEvent)?.subject()?.ifEmpty { null }
|
val subject = (note.event as? TextNoteEvent)?.subject()?.ifEmpty { null }
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import com.vitorpamplona.amethyst.ui.theme.Font14SP
|
|||||||
import com.vitorpamplona.amethyst.ui.theme.QuoteBorder
|
import com.vitorpamplona.amethyst.ui.theme.QuoteBorder
|
||||||
import com.vitorpamplona.amethyst.ui.theme.mediumImportanceLink
|
import com.vitorpamplona.amethyst.ui.theme.mediumImportanceLink
|
||||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||||
|
import com.vitorpamplona.quartz.events.EmptyTagList
|
||||||
import com.vitorpamplona.quartz.events.ImmutableListOfLists
|
import com.vitorpamplona.quartz.events.ImmutableListOfLists
|
||||||
import com.vitorpamplona.quartz.events.LnZapEvent
|
import com.vitorpamplona.quartz.events.LnZapEvent
|
||||||
import com.vitorpamplona.quartz.events.toImmutableListOfLists
|
import com.vitorpamplona.quartz.events.toImmutableListOfLists
|
||||||
@@ -116,7 +117,7 @@ private fun OptionNote(
|
|||||||
nav: (String) -> Unit
|
nav: (String) -> Unit
|
||||||
) {
|
) {
|
||||||
val tags = remember(baseNote) {
|
val tags = remember(baseNote) {
|
||||||
baseNote.event?.tags()?.toImmutableListOfLists() ?: ImmutableListOfLists()
|
baseNote.event?.tags()?.toImmutableListOfLists() ?: EmptyTagList
|
||||||
}
|
}
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ import com.vitorpamplona.amethyst.ui.theme.SmallBorder
|
|||||||
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||||
import com.vitorpamplona.amethyst.ui.theme.StdPadding
|
import com.vitorpamplona.amethyst.ui.theme.StdPadding
|
||||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||||
import com.vitorpamplona.quartz.events.ImmutableListOfLists
|
import com.vitorpamplona.quartz.events.EmptyTagList
|
||||||
import com.vitorpamplona.quartz.events.LiveActivitiesEvent.Companion.STATUS_LIVE
|
import com.vitorpamplona.quartz.events.LiveActivitiesEvent.Companion.STATUS_LIVE
|
||||||
import com.vitorpamplona.quartz.events.Participant
|
import com.vitorpamplona.quartz.events.Participant
|
||||||
import com.vitorpamplona.quartz.events.toImmutableListOfLists
|
import com.vitorpamplona.quartz.events.toImmutableListOfLists
|
||||||
@@ -751,9 +751,9 @@ fun LongChannelHeader(
|
|||||||
|
|
||||||
val tags = remember(channelState) {
|
val tags = remember(channelState) {
|
||||||
if (baseChannel is LiveActivitiesChannel) {
|
if (baseChannel is LiveActivitiesChannel) {
|
||||||
baseChannel.info?.tags()?.toImmutableListOfLists() ?: ImmutableListOfLists()
|
baseChannel.info?.tags()?.toImmutableListOfLists() ?: EmptyTagList
|
||||||
} else {
|
} else {
|
||||||
ImmutableListOfLists()
|
EmptyTagList
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
|
|||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.model.Account
|
import com.vitorpamplona.amethyst.model.Account
|
||||||
|
import com.vitorpamplona.amethyst.model.AddressableNote
|
||||||
import com.vitorpamplona.amethyst.model.LocalCache
|
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
|
||||||
@@ -97,9 +98,9 @@ import com.vitorpamplona.quartz.events.AppDefinitionEvent
|
|||||||
import com.vitorpamplona.quartz.events.BadgeDefinitionEvent
|
import com.vitorpamplona.quartz.events.BadgeDefinitionEvent
|
||||||
import com.vitorpamplona.quartz.events.BadgeProfilesEvent
|
import com.vitorpamplona.quartz.events.BadgeProfilesEvent
|
||||||
import com.vitorpamplona.quartz.events.ChatroomKey
|
import com.vitorpamplona.quartz.events.ChatroomKey
|
||||||
|
import com.vitorpamplona.quartz.events.EmptyTagList
|
||||||
import com.vitorpamplona.quartz.events.GitHubIdentity
|
import com.vitorpamplona.quartz.events.GitHubIdentity
|
||||||
import com.vitorpamplona.quartz.events.IdentityClaim
|
import com.vitorpamplona.quartz.events.IdentityClaim
|
||||||
import com.vitorpamplona.quartz.events.ImmutableListOfLists
|
|
||||||
import com.vitorpamplona.quartz.events.MastodonIdentity
|
import com.vitorpamplona.quartz.events.MastodonIdentity
|
||||||
import com.vitorpamplona.quartz.events.PayInvoiceErrorResponse
|
import com.vitorpamplona.quartz.events.PayInvoiceErrorResponse
|
||||||
import com.vitorpamplona.quartz.events.PayInvoiceSuccessResponse
|
import com.vitorpamplona.quartz.events.PayInvoiceSuccessResponse
|
||||||
@@ -118,7 +119,7 @@ import java.math.BigDecimal
|
|||||||
fun ProfileScreen(userId: String?, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
fun ProfileScreen(userId: String?, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
||||||
if (userId == null) return
|
if (userId == null) return
|
||||||
|
|
||||||
var userBase by remember { mutableStateOf<User?>(LocalCache.getUserIfExists(userId)) }
|
var userBase by remember { mutableStateOf(LocalCache.getUserIfExists(userId)) }
|
||||||
|
|
||||||
if (userBase == null) {
|
if (userBase == null) {
|
||||||
LaunchedEffect(userId) {
|
LaunchedEffect(userId) {
|
||||||
@@ -280,7 +281,6 @@ fun ProfileScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
|
||||||
private fun RenderSurface(
|
private fun RenderSurface(
|
||||||
baseUser: User,
|
baseUser: User,
|
||||||
threadsViewModel: NostrUserProfileNewThreadsFeedViewModel,
|
threadsViewModel: NostrUserProfileNewThreadsFeedViewModel,
|
||||||
@@ -383,7 +383,7 @@ private fun RenderScreen(
|
|||||||
) {
|
) {
|
||||||
val pagerState = rememberPagerState { 9 }
|
val pagerState = rememberPagerState { 9 }
|
||||||
|
|
||||||
Column() {
|
Column {
|
||||||
ProfileHeader(baseUser, appRecommendations, nav, accountViewModel)
|
ProfileHeader(baseUser, appRecommendations, nav, accountViewModel)
|
||||||
ScrollableTabRow(
|
ScrollableTabRow(
|
||||||
backgroundColor = MaterialTheme.colors.background,
|
backgroundColor = MaterialTheme.colors.background,
|
||||||
@@ -449,7 +449,7 @@ private fun CreateAndRenderTabs(
|
|||||||
) {
|
) {
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
|
||||||
val tabs = listOf<@Composable() (() -> Unit)?>(
|
val tabs = listOf<@Composable (() -> Unit)?>(
|
||||||
{ Text(text = stringResource(R.string.notes)) },
|
{ Text(text = stringResource(R.string.notes)) },
|
||||||
{ Text(text = stringResource(R.string.replies)) },
|
{ Text(text = stringResource(R.string.replies)) },
|
||||||
{ FollowTabHeader(baseUser) },
|
{ FollowTabHeader(baseUser) },
|
||||||
@@ -486,7 +486,7 @@ private fun RelaysTabHeader(baseUser: User) {
|
|||||||
@Composable
|
@Composable
|
||||||
private fun ReportsTabHeader(baseUser: User) {
|
private fun ReportsTabHeader(baseUser: User) {
|
||||||
val userState by baseUser.live().reports.observeAsState()
|
val userState by baseUser.live().reports.observeAsState()
|
||||||
var userReports by remember { mutableStateOf(0) }
|
var userReports by remember { mutableIntStateOf(0) }
|
||||||
|
|
||||||
LaunchedEffect(key1 = userState) {
|
LaunchedEffect(key1 = userState) {
|
||||||
launch(Dispatchers.IO) {
|
launch(Dispatchers.IO) {
|
||||||
@@ -503,11 +503,11 @@ private fun ReportsTabHeader(baseUser: User) {
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun FollowedTagsTabHeader(baseUser: User) {
|
private fun FollowedTagsTabHeader(baseUser: User) {
|
||||||
var usertags by remember { mutableStateOf(0) }
|
var usertags by remember { mutableIntStateOf(0) }
|
||||||
|
|
||||||
LaunchedEffect(key1 = baseUser) {
|
LaunchedEffect(key1 = baseUser) {
|
||||||
launch(Dispatchers.IO) {
|
launch(Dispatchers.IO) {
|
||||||
val contactList = baseUser?.latestContactList
|
val contactList = baseUser.latestContactList
|
||||||
|
|
||||||
val newTags = (contactList?.verifiedFollowTagSet?.count() ?: 0)
|
val newTags = (contactList?.verifiedFollowTagSet?.count() ?: 0)
|
||||||
|
|
||||||
@@ -524,7 +524,7 @@ private fun FollowedTagsTabHeader(baseUser: User) {
|
|||||||
private fun BookmarkTabHeader(baseUser: User) {
|
private fun BookmarkTabHeader(baseUser: User) {
|
||||||
val userState by baseUser.live().bookmarks.observeAsState()
|
val userState by baseUser.live().bookmarks.observeAsState()
|
||||||
|
|
||||||
var userBookmarks by remember { mutableStateOf(0) }
|
var userBookmarks by remember { mutableIntStateOf(0) }
|
||||||
|
|
||||||
LaunchedEffect(key1 = userState) {
|
LaunchedEffect(key1 = userState) {
|
||||||
launch(Dispatchers.IO) {
|
launch(Dispatchers.IO) {
|
||||||
@@ -716,8 +716,6 @@ private fun ProfileActions(
|
|||||||
EditButton(accountViewModel.account)
|
EditButton(accountViewModel.account)
|
||||||
}
|
}
|
||||||
|
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
|
|
||||||
WatchIsHiddenUser(baseUser, accountViewModel) { isHidden ->
|
WatchIsHiddenUser(baseUser, accountViewModel) { isHidden ->
|
||||||
if (isHidden) {
|
if (isHidden) {
|
||||||
ShowUserButton {
|
ShowUserButton {
|
||||||
@@ -1002,7 +1000,7 @@ private fun DrawAdditionalInfo(
|
|||||||
TranslatableRichTextViewer(
|
TranslatableRichTextViewer(
|
||||||
content = it,
|
content = it,
|
||||||
canPreview = false,
|
canPreview = false,
|
||||||
tags = remember { ImmutableListOfLists<String>(emptyList()) },
|
tags = EmptyTagList,
|
||||||
backgroundColor = background,
|
backgroundColor = background,
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav
|
nav = nav
|
||||||
@@ -1114,7 +1112,7 @@ private fun DisplayAppRecommendations(
|
|||||||
) { state ->
|
) { state ->
|
||||||
when (state) {
|
when (state) {
|
||||||
is FeedState.Loaded -> {
|
is FeedState.Loaded -> {
|
||||||
Column() {
|
Column {
|
||||||
Text(stringResource(id = R.string.recommended_apps))
|
Text(stringResource(id = R.string.recommended_apps))
|
||||||
|
|
||||||
FlowRow(
|
FlowRow(
|
||||||
@@ -1137,7 +1135,7 @@ private fun DisplayAppRecommendations(
|
|||||||
private fun WatchApp(baseApp: Note, nav: (String) -> Unit) {
|
private fun WatchApp(baseApp: Note, nav: (String) -> Unit) {
|
||||||
val appState by baseApp.live().metadata.observeAsState()
|
val appState by baseApp.live().metadata.observeAsState()
|
||||||
|
|
||||||
var appLogo by remember { mutableStateOf<String?>(null) }
|
var appLogo by remember(baseApp) { mutableStateOf<String?>(null) }
|
||||||
|
|
||||||
LaunchedEffect(key1 = appState) {
|
LaunchedEffect(key1 = appState) {
|
||||||
launch(Dispatchers.Default) {
|
launch(Dispatchers.Default) {
|
||||||
@@ -1185,19 +1183,27 @@ private fun DisplayBadges(
|
|||||||
null
|
null
|
||||||
),
|
),
|
||||||
accountViewModel
|
accountViewModel
|
||||||
) {
|
) { note ->
|
||||||
if (it != null) {
|
if (note != null) {
|
||||||
val badgeList by it.live().metadata.map {
|
WatchAndRenderBadgeList(note, nav)
|
||||||
(it.note.event as? BadgeProfilesEvent)?.badgeAwardEvents()?.toImmutableList()
|
|
||||||
}.distinctUntilChanged().observeAsState()
|
|
||||||
|
|
||||||
badgeList?.let { list ->
|
|
||||||
RenderBadgeList(list, nav)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun WatchAndRenderBadgeList(
|
||||||
|
note: AddressableNote,
|
||||||
|
nav: (String) -> Unit
|
||||||
|
) {
|
||||||
|
val badgeList by note.live().metadata.map {
|
||||||
|
(it.note.event as? BadgeProfilesEvent)?.badgeAwardEvents()?.toImmutableList()
|
||||||
|
}.distinctUntilChanged().observeAsState()
|
||||||
|
|
||||||
|
badgeList?.let { list ->
|
||||||
|
RenderBadgeList(list, nav)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@OptIn(ExperimentalLayoutApi::class)
|
@OptIn(ExperimentalLayoutApi::class)
|
||||||
private fun RenderBadgeList(
|
private fun RenderBadgeList(
|
||||||
@@ -1217,7 +1223,7 @@ private fun RenderBadgeList(
|
|||||||
@Composable
|
@Composable
|
||||||
private fun LoadAndRenderBadge(badgeAwardEventHex: String, nav: (String) -> Unit) {
|
private fun LoadAndRenderBadge(badgeAwardEventHex: String, nav: (String) -> Unit) {
|
||||||
var baseNote by remember {
|
var baseNote by remember {
|
||||||
mutableStateOf<Note?>(LocalCache.getNoteIfExists(badgeAwardEventHex))
|
mutableStateOf(LocalCache.getNoteIfExists(badgeAwardEventHex))
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(key1 = badgeAwardEventHex) {
|
LaunchedEffect(key1 = badgeAwardEventHex) {
|
||||||
@@ -1462,7 +1468,7 @@ fun TabFollows(baseUser: User, feedViewModel: UserFeedViewModel, accountViewMode
|
|||||||
WatchFollowChanges(baseUser, feedViewModel)
|
WatchFollowChanges(baseUser, feedViewModel)
|
||||||
|
|
||||||
Column(Modifier.fillMaxHeight()) {
|
Column(Modifier.fillMaxHeight()) {
|
||||||
Column() {
|
Column {
|
||||||
RefreshingFeedUserFeedView(feedViewModel, accountViewModel, nav, enablePullRefresh = false)
|
RefreshingFeedUserFeedView(feedViewModel, accountViewModel, nav, enablePullRefresh = false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1473,7 +1479,7 @@ fun TabFollowers(baseUser: User, feedViewModel: UserFeedViewModel, accountViewMo
|
|||||||
WatchFollowerChanges(baseUser, feedViewModel)
|
WatchFollowerChanges(baseUser, feedViewModel)
|
||||||
|
|
||||||
Column(Modifier.fillMaxHeight()) {
|
Column(Modifier.fillMaxHeight()) {
|
||||||
Column() {
|
Column {
|
||||||
RefreshingFeedUserFeedView(feedViewModel, accountViewModel, nav, enablePullRefresh = false)
|
RefreshingFeedUserFeedView(feedViewModel, accountViewModel, nav, enablePullRefresh = false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1508,7 +1514,7 @@ fun TabReceivedZaps(baseUser: User, zapFeedViewModel: NostrUserProfileZapsFeedVi
|
|||||||
WatchZapsAndUpdateFeed(baseUser, zapFeedViewModel)
|
WatchZapsAndUpdateFeed(baseUser, zapFeedViewModel)
|
||||||
|
|
||||||
Column(Modifier.fillMaxHeight()) {
|
Column(Modifier.fillMaxHeight()) {
|
||||||
Column() {
|
Column {
|
||||||
LnZapFeedView(zapFeedViewModel, accountViewModel, nav)
|
LnZapFeedView(zapFeedViewModel, accountViewModel, nav)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1531,7 +1537,7 @@ fun TabReports(baseUser: User, feedViewModel: NostrUserProfileReportFeedViewMode
|
|||||||
WatchReportsAndUpdateFeed(baseUser, feedViewModel)
|
WatchReportsAndUpdateFeed(baseUser, feedViewModel)
|
||||||
|
|
||||||
Column(Modifier.fillMaxHeight()) {
|
Column(Modifier.fillMaxHeight()) {
|
||||||
Column() {
|
Column {
|
||||||
RefresheableFeedView(
|
RefresheableFeedView(
|
||||||
feedViewModel,
|
feedViewModel,
|
||||||
null,
|
null,
|
||||||
@@ -1703,7 +1709,6 @@ fun UserProfileDropDownMenu(user: User, popupExpanded: Boolean, onDismiss: () ->
|
|||||||
onDismissRequest = onDismiss
|
onDismissRequest = onDismiss
|
||||||
) {
|
) {
|
||||||
val clipboardManager = LocalClipboardManager.current
|
val clipboardManager = LocalClipboardManager.current
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
|
|
||||||
DropdownMenuItem(onClick = { clipboardManager.setText(AnnotatedString(user.pubkeyNpub())); onDismiss() }) {
|
DropdownMenuItem(onClick = { clipboardManager.setText(AnnotatedString(user.pubkeyNpub())); onDismiss() }) {
|
||||||
Text(stringResource(R.string.copy_user_id))
|
Text(stringResource(R.string.copy_user_id))
|
||||||
|
|||||||
@@ -15,16 +15,28 @@ class AppDefinitionEvent(
|
|||||||
content: String,
|
content: String,
|
||||||
sig: HexKey
|
sig: HexKey
|
||||||
) : BaseAddressableEvent(id, pubKey, createdAt, kind, tags, content, sig) {
|
) : BaseAddressableEvent(id, pubKey, createdAt, kind, tags, content, sig) {
|
||||||
fun appMetaData() = try {
|
@Transient
|
||||||
mapper.readValue(
|
private var cachedMetadata: UserMetadata? = null
|
||||||
ByteArrayInputStream(content.toByteArray(Charsets.UTF_8)),
|
|
||||||
UserMetadata::class.java
|
fun appMetaData() =
|
||||||
)
|
if (cachedMetadata != null) {
|
||||||
} catch (e: Exception) {
|
cachedMetadata
|
||||||
e.printStackTrace()
|
} else {
|
||||||
Log.w("MT", "Content Parse Error ${e.localizedMessage} $content")
|
try {
|
||||||
null
|
val newMetadata = mapper.readValue(
|
||||||
}
|
ByteArrayInputStream(content.toByteArray(Charsets.UTF_8)),
|
||||||
|
UserMetadata::class.java
|
||||||
|
)
|
||||||
|
|
||||||
|
cachedMetadata = newMetadata
|
||||||
|
|
||||||
|
newMetadata
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
Log.w("MT", "Content Parse Error ${e.localizedMessage} $content")
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun supportedKinds() = tags.filter { it.size > 1 && it[0] == "k" }.mapNotNull {
|
fun supportedKinds() = tags.filter { it.size > 1 && it[0] == "k" }.mapNotNull {
|
||||||
runCatching { it[1].toInt() }.getOrNull()
|
runCatching { it[1].toInt() }.getOrNull()
|
||||||
|
|||||||
@@ -350,6 +350,8 @@ class UserMetadata {
|
|||||||
@Stable
|
@Stable
|
||||||
data class ImmutableListOfLists<T>(val lists: List<List<T>> = emptyList())
|
data class ImmutableListOfLists<T>(val lists: List<List<T>> = emptyList())
|
||||||
|
|
||||||
|
val EmptyTagList = ImmutableListOfLists<String>(emptyList())
|
||||||
|
|
||||||
fun List<List<String>>.toImmutableListOfLists(): ImmutableListOfLists<String> {
|
fun List<List<String>>.toImmutableListOfLists(): ImmutableListOfLists<String> {
|
||||||
return ImmutableListOfLists(this)
|
return ImmutableListOfLists(this)
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user