Revert "refactor: redesign NIP-5A rendering as website preview card"
This reverts commit 07f16c2efe.
This commit is contained in:
@@ -20,29 +20,38 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.note.types
|
package com.vitorpamplona.amethyst.ui.note.types
|
||||||
|
|
||||||
|
import androidx.compose.foundation.border
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||||
|
import androidx.compose.foundation.layout.FlowRow
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.HorizontalDivider
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.platform.LocalUriHandler
|
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import coil3.compose.AsyncImage
|
import androidx.compose.ui.unit.dp
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
|
import com.vitorpamplona.amethyst.ui.components.ClickableUrl
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.stringRes
|
import com.vitorpamplona.amethyst.ui.stringRes
|
||||||
import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer
|
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
||||||
import com.vitorpamplona.amethyst.ui.theme.MaxWidthWithHorzPadding
|
import com.vitorpamplona.amethyst.ui.theme.QuoteBorder
|
||||||
import com.vitorpamplona.amethyst.ui.theme.innerPostModifier
|
import com.vitorpamplona.amethyst.ui.theme.Size10dp
|
||||||
import com.vitorpamplona.amethyst.ui.theme.previewCardImageModifier
|
import com.vitorpamplona.amethyst.ui.theme.Size5dp
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray
|
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||||
import com.vitorpamplona.quartz.nip19Bech32.toNpub
|
import com.vitorpamplona.amethyst.ui.theme.subtleBorder
|
||||||
import com.vitorpamplona.quartz.nip5aStaticWebsites.NamedSiteEvent
|
import com.vitorpamplona.quartz.nip5aStaticWebsites.NamedSiteEvent
|
||||||
import com.vitorpamplona.quartz.nip5aStaticWebsites.RootSiteEvent
|
import com.vitorpamplona.quartz.nip5aStaticWebsites.RootSiteEvent
|
||||||
|
import com.vitorpamplona.quartz.nip5aStaticWebsites.tags.PathTag
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun RenderRootSiteEvent(
|
fun RenderRootSiteEvent(
|
||||||
@@ -52,18 +61,13 @@ fun RenderRootSiteEvent(
|
|||||||
) {
|
) {
|
||||||
val event = baseNote.event as? RootSiteEvent ?: return
|
val event = baseNote.event as? RootSiteEvent ?: return
|
||||||
|
|
||||||
val npub =
|
RenderStaticWebsite(
|
||||||
remember(event.pubKey) {
|
|
||||||
event.pubKey.hexToByteArray().toNpub()
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderStaticWebsitePreview(
|
|
||||||
title = event.title(),
|
title = event.title(),
|
||||||
description = event.description(),
|
description = event.description(),
|
||||||
npub = npub,
|
source = event.source(),
|
||||||
identifier = null,
|
|
||||||
faviconHash = event.paths().firstOrNull { it.path == "/favicon.ico" }?.hash,
|
|
||||||
servers = event.servers(),
|
servers = event.servers(),
|
||||||
|
paths = event.paths(),
|
||||||
|
identifier = null,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,87 +79,129 @@ fun RenderNamedSiteEvent(
|
|||||||
) {
|
) {
|
||||||
val event = baseNote.event as? NamedSiteEvent ?: return
|
val event = baseNote.event as? NamedSiteEvent ?: return
|
||||||
|
|
||||||
val npub =
|
RenderStaticWebsite(
|
||||||
remember(event.pubKey) {
|
|
||||||
event.pubKey.hexToByteArray().toNpub()
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderStaticWebsitePreview(
|
|
||||||
title = event.title(),
|
title = event.title(),
|
||||||
description = event.description(),
|
description = event.description(),
|
||||||
npub = npub,
|
source = event.source(),
|
||||||
identifier = event.identifier(),
|
|
||||||
faviconHash = event.paths().firstOrNull { it.path == "/favicon.ico" }?.hash,
|
|
||||||
servers = event.servers(),
|
servers = event.servers(),
|
||||||
|
paths = event.paths(),
|
||||||
|
identifier = event.identifier(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalLayoutApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun RenderStaticWebsitePreview(
|
private fun RenderStaticWebsite(
|
||||||
title: String?,
|
title: String?,
|
||||||
description: String?,
|
description: String?,
|
||||||
npub: String,
|
source: String?,
|
||||||
identifier: String?,
|
|
||||||
faviconHash: String?,
|
|
||||||
servers: List<String>,
|
servers: List<String>,
|
||||||
|
paths: List<PathTag>,
|
||||||
|
identifier: String?,
|
||||||
) {
|
) {
|
||||||
val nsiteHost =
|
Row(
|
||||||
if (identifier != null) {
|
modifier =
|
||||||
"$npub.$identifier.nsite.lol"
|
Modifier
|
||||||
} else {
|
.clip(shape = QuoteBorder)
|
||||||
"$npub.nsite.lol"
|
.border(
|
||||||
}
|
1.dp,
|
||||||
|
MaterialTheme.colorScheme.subtleBorder,
|
||||||
val nsiteUrl = "https://$nsiteHost"
|
QuoteBorder,
|
||||||
|
).padding(Size10dp),
|
||||||
val faviconUrl =
|
|
||||||
if (faviconHash != null && servers.isNotEmpty()) {
|
|
||||||
"${servers.first()}/$faviconHash"
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
val uri = LocalUriHandler.current
|
|
||||||
|
|
||||||
Column(
|
|
||||||
modifier = MaterialTheme.colorScheme.innerPostModifier,
|
|
||||||
) {
|
) {
|
||||||
faviconUrl?.let {
|
Column {
|
||||||
AsyncImage(
|
val displayTitle =
|
||||||
model = it,
|
title
|
||||||
contentDescription = title,
|
?: identifier
|
||||||
modifier = previewCardImageModifier,
|
?: stringRes(id = R.string.nsite_root_site)
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = nsiteHost,
|
|
||||||
style = MaterialTheme.typography.bodySmall,
|
|
||||||
modifier = MaxWidthWithHorzPadding,
|
|
||||||
color = Color.Gray,
|
|
||||||
maxLines = 1,
|
|
||||||
overflow = TextOverflow.Ellipsis,
|
|
||||||
)
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = title ?: identifier ?: stringRes(id = R.string.nsite_root_site),
|
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
|
||||||
modifier = MaxWidthWithHorzPadding,
|
|
||||||
maxLines = 1,
|
|
||||||
overflow = TextOverflow.Ellipsis,
|
|
||||||
)
|
|
||||||
|
|
||||||
description?.let {
|
|
||||||
Text(
|
Text(
|
||||||
text = it,
|
text = stringRes(id = R.string.nsite_title, displayTitle),
|
||||||
style = MaterialTheme.typography.bodySmall,
|
style = MaterialTheme.typography.titleMedium,
|
||||||
modifier = MaxWidthWithHorzPadding,
|
maxLines = 1,
|
||||||
color = Color.Gray,
|
|
||||||
maxLines = 3,
|
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
Spacer(modifier = DoubleVertSpacer)
|
description?.let {
|
||||||
|
Text(
|
||||||
|
text = it,
|
||||||
|
modifier = Modifier.fillMaxWidth().padding(vertical = Size5dp),
|
||||||
|
maxLines = 3,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
HorizontalDivider(thickness = DividerThickness)
|
||||||
|
|
||||||
|
source?.let {
|
||||||
|
Row(Modifier.fillMaxWidth().padding(top = Size5dp)) {
|
||||||
|
Text(
|
||||||
|
text = stringRes(id = R.string.nsite_source),
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
)
|
||||||
|
Spacer(modifier = StdHorzSpacer)
|
||||||
|
ClickableUrl(
|
||||||
|
url = it,
|
||||||
|
urlText = it.removePrefix("https://").removePrefix("http://"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (servers.isNotEmpty()) {
|
||||||
|
Row(Modifier.fillMaxWidth().padding(top = Size5dp)) {
|
||||||
|
Text(
|
||||||
|
text = stringRes(id = R.string.nsite_servers),
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
)
|
||||||
|
Spacer(modifier = StdHorzSpacer)
|
||||||
|
Column {
|
||||||
|
servers.forEach { server ->
|
||||||
|
ClickableUrl(
|
||||||
|
url = server,
|
||||||
|
urlText = server.removePrefix("https://").removePrefix("http://"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (paths.isNotEmpty()) {
|
||||||
|
Row(Modifier.fillMaxWidth().padding(top = Size5dp)) {
|
||||||
|
Text(
|
||||||
|
text = stringRes(id = R.string.nsite_files, paths.size),
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
FlowRow(
|
||||||
|
modifier = Modifier.fillMaxWidth().padding(top = Size5dp),
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(Size5dp),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(Size5dp),
|
||||||
|
) {
|
||||||
|
paths.take(10).forEach { path ->
|
||||||
|
Text(
|
||||||
|
text = path.path,
|
||||||
|
style = MaterialTheme.typography.bodySmall,
|
||||||
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (paths.size > 10) {
|
||||||
|
Text(
|
||||||
|
text = stringRes(id = R.string.nsite_more_files, paths.size - 10),
|
||||||
|
style = MaterialTheme.typography.bodySmall,
|
||||||
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
|
maxLines = 1,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1488,7 +1488,12 @@
|
|||||||
<string name="git_repository">Git Repository: %1$s</string>
|
<string name="git_repository">Git Repository: %1$s</string>
|
||||||
<string name="git_web_address">Web:</string>
|
<string name="git_web_address">Web:</string>
|
||||||
<string name="git_clone_address">Clone:</string>
|
<string name="git_clone_address">Clone:</string>
|
||||||
|
<string name="nsite_title">Static Website: %1$s</string>
|
||||||
<string name="nsite_root_site">Root Site</string>
|
<string name="nsite_root_site">Root Site</string>
|
||||||
|
<string name="nsite_source">Source:</string>
|
||||||
|
<string name="nsite_servers">Servers:</string>
|
||||||
|
<string name="nsite_files">%1$d files</string>
|
||||||
|
<string name="nsite_more_files">+%1$d more</string>
|
||||||
<string name="existed_since">OTS: %1$s</string>
|
<string name="existed_since">OTS: %1$s</string>
|
||||||
|
|
||||||
<string name="ots_info_title">Timestamp Proof</string>
|
<string name="ots_info_title">Timestamp Proof</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user