mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-09-27 22:36:26 +02:00
Switch PFPs to use the robohash proxy
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.components
|
package com.vitorpamplona.amethyst.ui.components
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
@@ -31,45 +32,47 @@ data class ResizeImage(val url: String?, val size: Dp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable fun AsyncUserImageProxy(
|
@Composable fun AsyncUserImageProxy(
|
||||||
pubkeyHex: String,
|
pubkeyHex: String,
|
||||||
model: ResizeImage,
|
model: ResizeImage,
|
||||||
contentDescription: String?,
|
contentDescription: String?,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
alignment: Alignment = Alignment.Center,
|
alignment: Alignment = Alignment.Center,
|
||||||
contentScale: ContentScale = ContentScale.Fit,
|
contentScale: ContentScale = ContentScale.Fit,
|
||||||
alpha: Float = DefaultAlpha,
|
alpha: Float = DefaultAlpha,
|
||||||
colorFilter: ColorFilter? = null,
|
colorFilter: ColorFilter? = null,
|
||||||
filterQuality: FilterQuality = DrawScope.DefaultFilterQuality,
|
filterQuality: FilterQuality = DrawScope.DefaultFilterQuality
|
||||||
) {
|
) {
|
||||||
var loading by remember { mutableStateOf(false) }
|
var loading by remember { mutableStateOf(false) }
|
||||||
var error by remember { mutableStateOf(false) }
|
var error by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
if (model.url == null || loading || error) {
|
Box() {
|
||||||
RoboHashAsyncImage(
|
AsyncImage(
|
||||||
message = pubkeyHex,
|
model = model.proxyUrl(),
|
||||||
contentDescription = contentDescription,
|
contentDescription = contentDescription,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
alignment = alignment,
|
onLoading = { loading = true },
|
||||||
contentScale = contentScale,
|
onSuccess = { loading = false; error = false },
|
||||||
alpha = alpha,
|
onError = { loading = false; error = true },
|
||||||
colorFilter = colorFilter,
|
alignment = alignment,
|
||||||
filterQuality = filterQuality,
|
contentScale = contentScale,
|
||||||
)
|
alpha = alpha,
|
||||||
} else {
|
colorFilter = colorFilter,
|
||||||
AsyncImage(
|
filterQuality = filterQuality
|
||||||
model = model.proxyUrl(),
|
)
|
||||||
contentDescription = contentDescription,
|
|
||||||
modifier = modifier,
|
if (model.url == null || loading || error) {
|
||||||
onLoading = { loading = true },
|
RoboHashAsyncImage(
|
||||||
onSuccess = { loading = false; error = false },
|
message = pubkeyHex,
|
||||||
onError = { loading = false; error = true },
|
contentDescription = contentDescription,
|
||||||
alignment = alignment,
|
modifier = modifier,
|
||||||
contentScale = contentScale,
|
alignment = alignment,
|
||||||
alpha = alpha,
|
contentScale = contentScale,
|
||||||
colorFilter = colorFilter,
|
alpha = alpha,
|
||||||
filterQuality = filterQuality
|
colorFilter = colorFilter,
|
||||||
)
|
filterQuality = filterQuality
|
||||||
}
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
@@ -37,7 +37,7 @@ private fun bytesToRGB(b1: Byte, b2: Byte, b3: Byte): Color {
|
|||||||
|
|
||||||
fun generateRoboHashSvg(msg: String): String {
|
fun generateRoboHashSvg(msg: String): String {
|
||||||
val hash = sha256.digest(msg.toByteArray())
|
val hash = sha256.digest(msg.toByteArray())
|
||||||
val hashHex = hash.joinToString(separator = "") {b -> "%02x".format(b)}
|
val hashHex = hash.joinToString(separator = "") { b -> "%02x".format(b) }
|
||||||
val bgColor1 = bytesToRGB(hash[0], hash[1], hash[2])
|
val bgColor1 = bytesToRGB(hash[0], hash[1], hash[2])
|
||||||
val bgColor2 = bytesToRGB(hash[3], hash[4], hash[5])
|
val bgColor2 = bytesToRGB(hash[3], hash[4], hash[5])
|
||||||
val fgColor = bytesToRGB(hash[6], hash[7], hash[8])
|
val fgColor = bytesToRGB(hash[6], hash[7], hash[8])
|
||||||
@@ -71,9 +71,11 @@ fun generateRoboHashSvg(msg: String): String {
|
|||||||
fun roboHashImageRequest(context: Context, message: String): ImageRequest {
|
fun roboHashImageRequest(context: Context, message: String): ImageRequest {
|
||||||
return ImageRequest
|
return ImageRequest
|
||||||
.Builder(context)
|
.Builder(context)
|
||||||
.data(ByteBuffer.wrap(
|
.data(
|
||||||
generateRoboHashSvg(message).toByteArray()
|
ByteBuffer.wrap(
|
||||||
))
|
generateRoboHashSvg(message).toByteArray()
|
||||||
|
)
|
||||||
|
)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +90,7 @@ fun RoboHashAsyncImage(
|
|||||||
contentScale: ContentScale = ContentScale.Fit,
|
contentScale: ContentScale = ContentScale.Fit,
|
||||||
alpha: Float = DefaultAlpha,
|
alpha: Float = DefaultAlpha,
|
||||||
colorFilter: ColorFilter? = null,
|
colorFilter: ColorFilter? = null,
|
||||||
filterQuality: FilterQuality = DrawScope.DefaultFilterQuality,
|
filterQuality: FilterQuality = DrawScope.DefaultFilterQuality
|
||||||
) {
|
) {
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = roboHashImageRequest(LocalContext.current, message),
|
model = roboHashImageRequest(LocalContext.current, message),
|
||||||
@@ -100,7 +102,7 @@ fun RoboHashAsyncImage(
|
|||||||
contentScale = contentScale,
|
contentScale = contentScale,
|
||||||
alpha = alpha,
|
alpha = alpha,
|
||||||
colorFilter = colorFilter,
|
colorFilter = colorFilter,
|
||||||
filterQuality = filterQuality,
|
filterQuality = filterQuality
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +116,7 @@ private val backgrounds: List<String> = listOf(
|
|||||||
"""<g><rect class="bg-1" width="300" height="300"/><circle class="bg-2" cx="30.3" cy="25.6" r="2.3"/><circle class="bg-2" cx="85" cy="69.2" r="2.3"/><circle class="bg-2" cx="134.7" cy="259.4" r="2.3"/><path class="bg-2" d="M159.2,43.8a2.3,2.3,0,0,1-2.3,2.3,2.3,2.3,0,0,1-2.3-2.3,2.3,2.3,0,0,1,2.3-2.3A2.4,2.4,0,0,1,159.2,43.8Z"/><path class="bg-2" d="M237.7,74.8a2.3,2.3,0,0,1-2.3,2.2,2.3,2.3,0,1,1,0-4.5A2.3,2.3,0,0,1,237.7,74.8Z"/><path class="bg-2" d="M268.6,36.1a2.3,2.3,0,0,1-2.3,2.3,2.4,2.4,0,0,1-2.3-2.3,2.3,2.3,0,0,1,2.3-2.3A2.3,2.3,0,0,1,268.6,36.1Z"/><circle class="bg-2" cx="53" cy="152.1" r="2.3"/><circle class="bg-2" cx="248.6" cy="146.6" r="2.3"/><path class="bg-2" d="M144.8,100.2a2.3,2.3,0,0,1-2.3,2.3,2.4,2.4,0,0,1-2.3-2.3,2.3,2.3,0,0,1,2.3-2.3A2.3,2.3,0,0,1,144.8,100.2Z"/><circle class="bg-2" cx="206.6" cy="222.9" r="2.3"/><circle class="bg-2" cx="100.5" cy="25" r="1.7"/><circle class="bg-2" cx="201.1" cy="30" r="1.7"/><path class="bg-2" d="M194,44.4a1.7,1.7,0,0,1-1.7,1.7,1.6,1.6,0,0,1-1.7-1.7,1.7,1.7,0,0,1,1.7-1.7A1.8,1.8,0,0,1,194,44.4Z"/><circle class="bg-2" cx="238.7" cy="52.2" r="1.7"/><path class="bg-2" d="M44.1,54.9a1.7,1.7,0,0,1-1.7,1.7,1.8,1.8,0,0,1-1.7-1.7,1.7,1.7,0,0,1,1.7-1.7A1.6,1.6,0,0,1,44.1,54.9Z"/><circle class="bg-2" cx="80" cy="57.1" r="1.7"/><circle class="bg-2" cx="98.3" cy="66.4" r="1.7"/><circle class="bg-2" cx="109.9" cy="116.8" r="1.7"/><circle class="bg-2" cx="200.5" cy="96.9" r="1.7"/><circle class="bg-2" cx="271.2" cy="102.4" r="1.7"/><path class="bg-2" d="M163.5,163.2a1.7,1.7,0,0,1-1.7,1.7,1.8,1.8,0,0,1-1.7-1.7,1.7,1.7,0,0,1,1.7-1.7A1.6,1.6,0,0,1,163.5,163.2Z"/><path class="bg-2" d="M182.3,137.8a1.7,1.7,0,0,1-3.4,0,1.7,1.7,0,0,1,3.4,0Z"/><path class="bg-2" d="M77.3,224a1.7,1.7,0,0,1-3.4,0,1.7,1.7,0,0,1,3.4,0Z"/><circle class="bg-2" cx="262.4" cy="275.9" r="1.7"/><circle class="bg-2" cx="216.6" cy="217.9" r="1.7"/><path class="bg-2" d="M118.8,191.4a1.7,1.7,0,1,1-3.4,0,1.7,1.7,0,1,1,3.4,0Z"/><circle class="bg-2" cx="42.4" cy="268.2" r="1.7"/></g>""",
|
"""<g><rect class="bg-1" width="300" height="300"/><circle class="bg-2" cx="30.3" cy="25.6" r="2.3"/><circle class="bg-2" cx="85" cy="69.2" r="2.3"/><circle class="bg-2" cx="134.7" cy="259.4" r="2.3"/><path class="bg-2" d="M159.2,43.8a2.3,2.3,0,0,1-2.3,2.3,2.3,2.3,0,0,1-2.3-2.3,2.3,2.3,0,0,1,2.3-2.3A2.4,2.4,0,0,1,159.2,43.8Z"/><path class="bg-2" d="M237.7,74.8a2.3,2.3,0,0,1-2.3,2.2,2.3,2.3,0,1,1,0-4.5A2.3,2.3,0,0,1,237.7,74.8Z"/><path class="bg-2" d="M268.6,36.1a2.3,2.3,0,0,1-2.3,2.3,2.4,2.4,0,0,1-2.3-2.3,2.3,2.3,0,0,1,2.3-2.3A2.3,2.3,0,0,1,268.6,36.1Z"/><circle class="bg-2" cx="53" cy="152.1" r="2.3"/><circle class="bg-2" cx="248.6" cy="146.6" r="2.3"/><path class="bg-2" d="M144.8,100.2a2.3,2.3,0,0,1-2.3,2.3,2.4,2.4,0,0,1-2.3-2.3,2.3,2.3,0,0,1,2.3-2.3A2.3,2.3,0,0,1,144.8,100.2Z"/><circle class="bg-2" cx="206.6" cy="222.9" r="2.3"/><circle class="bg-2" cx="100.5" cy="25" r="1.7"/><circle class="bg-2" cx="201.1" cy="30" r="1.7"/><path class="bg-2" d="M194,44.4a1.7,1.7,0,0,1-1.7,1.7,1.6,1.6,0,0,1-1.7-1.7,1.7,1.7,0,0,1,1.7-1.7A1.8,1.8,0,0,1,194,44.4Z"/><circle class="bg-2" cx="238.7" cy="52.2" r="1.7"/><path class="bg-2" d="M44.1,54.9a1.7,1.7,0,0,1-1.7,1.7,1.8,1.8,0,0,1-1.7-1.7,1.7,1.7,0,0,1,1.7-1.7A1.6,1.6,0,0,1,44.1,54.9Z"/><circle class="bg-2" cx="80" cy="57.1" r="1.7"/><circle class="bg-2" cx="98.3" cy="66.4" r="1.7"/><circle class="bg-2" cx="109.9" cy="116.8" r="1.7"/><circle class="bg-2" cx="200.5" cy="96.9" r="1.7"/><circle class="bg-2" cx="271.2" cy="102.4" r="1.7"/><path class="bg-2" d="M163.5,163.2a1.7,1.7,0,0,1-1.7,1.7,1.8,1.8,0,0,1-1.7-1.7,1.7,1.7,0,0,1,1.7-1.7A1.6,1.6,0,0,1,163.5,163.2Z"/><path class="bg-2" d="M182.3,137.8a1.7,1.7,0,0,1-3.4,0,1.7,1.7,0,0,1,3.4,0Z"/><path class="bg-2" d="M77.3,224a1.7,1.7,0,0,1-3.4,0,1.7,1.7,0,0,1,3.4,0Z"/><circle class="bg-2" cx="262.4" cy="275.9" r="1.7"/><circle class="bg-2" cx="216.6" cy="217.9" r="1.7"/><path class="bg-2" d="M118.8,191.4a1.7,1.7,0,1,1-3.4,0,1.7,1.7,0,1,1,3.4,0Z"/><circle class="bg-2" cx="42.4" cy="268.2" r="1.7"/></g>""",
|
||||||
"""<g><rect class="bg-1" x="0.2" width="299.8" height="299.81"/><path class="bg-2" d="M278.7,140.9c-5.8-23.9-37.5-36.2-59.5-34.2-28.4,2.5-42,19.3-54.9,42-9.7-12.3-38.1-4.6-34.2,15.5-13-17.5-31.7-29.8-55-27.2-20.6,2-43.3,21.4-45.2,42C20,163.6,8,162.5,0,166.7V299.9H299.8V133.7C292.4,131.9,284.1,134.8,278.7,140.9Z" transform="translate(0 -0.1)"/></g>""",
|
"""<g><rect class="bg-1" x="0.2" width="299.8" height="299.81"/><path class="bg-2" d="M278.7,140.9c-5.8-23.9-37.5-36.2-59.5-34.2-28.4,2.5-42,19.3-54.9,42-9.7-12.3-38.1-4.6-34.2,15.5-13-17.5-31.7-29.8-55-27.2-20.6,2-43.3,21.4-45.2,42C20,163.6,8,162.5,0,166.7V299.9H299.8V133.7C292.4,131.9,284.1,134.8,278.7,140.9Z" transform="translate(0 -0.1)"/></g>""",
|
||||||
"""<rect class="bg-1" width="300" height="300"/>""",
|
"""<rect class="bg-1" width="300" height="300"/>""",
|
||||||
"""<rect class="bg-1" width="300" height="300"/><path class="bg-2" d="M0,248.5V300H300V40.2S195.8,194.2,0,248.5Z"/>""",
|
"""<rect class="bg-1" width="300" height="300"/><path class="bg-2" d="M0,248.5V300H300V40.2S195.8,194.2,0,248.5Z"/>"""
|
||||||
)
|
)
|
||||||
|
|
||||||
private val accessories: List<Part> = listOf(
|
private val accessories: List<Part> = listOf(
|
||||||
@@ -157,7 +159,7 @@ private val accessories: List<Part> = listOf(
|
|||||||
Part(
|
Part(
|
||||||
""".cls-09-2{fill:none;}.cls-09-2,.cls-09-4{stroke:#000;stroke-miterlimit:10;}.cls-09-3,.cls-09-4{fill:#fff;}.cls-09-3{fill-opacity:0.2;}.cls-09-5{fill:#d0d2d3;}.cls-09-6{fill-opacity:0.4;}""",
|
""".cls-09-2{fill:none;}.cls-09-2,.cls-09-4{stroke:#000;stroke-miterlimit:10;}.cls-09-3,.cls-09-4{fill:#fff;}.cls-09-3{fill-opacity:0.2;}.cls-09-5{fill:#d0d2d3;}.cls-09-6{fill-opacity:0.4;}""",
|
||||||
"""<path id="fill_color" data-name="fill color" class="cls-fill-1" d="M122.5,88.5v6s3,4,13,3c12.5-.5,16-5,16-5v-6l-2-3a63.26,63.26,0,0,0-15,0C126.5,84.5,122.5,85.5,122.5,88.5Z"/><path class="cls-09-2" d="M122.5,88.5v6s2,3,13,3,16-5,16-5v-6l-2-3a63.26,63.26,0,0,0-15,0C126.5,84.5,122.5,85.5,122.5,88.5Z"/><path class="cls-09-3" d="M142.5,89.5c.2-.05,1.28-.44,1.5-.5-.63-1.83-4.53-5.64-5.5-5.7-7-.41-11.66,1-13.22,2-1.78,1.16-3.78,2.16,1.22,4.16C129.5,90.5,138.5,90.5,142.5,89.5Z"/><path class="cls-09-2" d="M142.5,89.5c4-1,10.83-4.83,3.92-5.92s-19.36.59-21.14,1.75-3.78,2.16,1.22,4.16C129.5,90.5,138.5,90.5,142.5,89.5Z"/><path class="cls-09-4" d="M130.5,52.5,128.24,84s1.26,3.47,7.26,2.47,7.33-3.44,7.33-3.44L132.5,54.5S131.5,51.5,130.5,52.5Z"/><path class="cls-09-5" d="M131.5,55.5l7.06,30.26s3.94-.26,3.94-2.26-10-29-10-29S130.5,50.5,131.5,55.5Z"/><path class="cls-09-2" d="M130.5,52.5,128.24,84s1.26,3.47,7.26,2.47,7.33-3.44,7.33-3.44L132.5,54.5S131.5,51.5,130.5,52.5Z"/><path class="cls-09-6" d="M144.09,88.72v8l7.41-4.26v-6l-2-3C150,85.88,147.82,87.51,144.09,88.72Z"/>"""
|
"""<path id="fill_color" data-name="fill color" class="cls-fill-1" d="M122.5,88.5v6s3,4,13,3c12.5-.5,16-5,16-5v-6l-2-3a63.26,63.26,0,0,0-15,0C126.5,84.5,122.5,85.5,122.5,88.5Z"/><path class="cls-09-2" d="M122.5,88.5v6s2,3,13,3,16-5,16-5v-6l-2-3a63.26,63.26,0,0,0-15,0C126.5,84.5,122.5,85.5,122.5,88.5Z"/><path class="cls-09-3" d="M142.5,89.5c.2-.05,1.28-.44,1.5-.5-.63-1.83-4.53-5.64-5.5-5.7-7-.41-11.66,1-13.22,2-1.78,1.16-3.78,2.16,1.22,4.16C129.5,90.5,138.5,90.5,142.5,89.5Z"/><path class="cls-09-2" d="M142.5,89.5c4-1,10.83-4.83,3.92-5.92s-19.36.59-21.14,1.75-3.78,2.16,1.22,4.16C129.5,90.5,138.5,90.5,142.5,89.5Z"/><path class="cls-09-4" d="M130.5,52.5,128.24,84s1.26,3.47,7.26,2.47,7.33-3.44,7.33-3.44L132.5,54.5S131.5,51.5,130.5,52.5Z"/><path class="cls-09-5" d="M131.5,55.5l7.06,30.26s3.94-.26,3.94-2.26-10-29-10-29S130.5,50.5,131.5,55.5Z"/><path class="cls-09-2" d="M130.5,52.5,128.24,84s1.26,3.47,7.26,2.47,7.33-3.44,7.33-3.44L132.5,54.5S131.5,51.5,130.5,52.5Z"/><path class="cls-09-6" d="M144.09,88.72v8l7.41-4.26v-6l-2-3C150,85.88,147.82,87.51,144.09,88.72Z"/>"""
|
||||||
),
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val bodies: List<Part> = listOf(
|
private val bodies: List<Part> = listOf(
|
||||||
@@ -200,7 +202,7 @@ private val bodies: List<Part> = listOf(
|
|||||||
Part(
|
Part(
|
||||||
""".cls-19-2{fill-opacity:0.6;}.cls-19-11,.cls-19-13,.cls-19-14,.cls-19-2,.cls-19-3,.cls-19-4,.cls-19-6,.cls-19-8{stroke:#000;}.cls-19-11,.cls-19-13,.cls-19-2,.cls-19-4,.cls-19-6,.cls-19-8{stroke-miterlimit:10;}.cls-19-11,.cls-19-14,.cls-19-3,.cls-19-8{fill:none;}.cls-19-14,.cls-19-3{stroke-linecap:round;stroke-linejoin:round;}.cls-19-10,.cls-19-12,.cls-19-4,.cls-19-5{fill:#fff;}.cls-19-12,.cls-19-4{fill-opacity:0.2;}.cls-19-4{stroke-opacity:0;}.cls-19-5{fill-opacity:0.1;}.cls-19-6{fill:#6d6e70;}.cls-19-7{fill:#58595b;}.cls-19-13,.cls-19-9{fill-opacity:0.4;}.cls-19-10{fill-opacity:0.5;}.cls-19-11,.cls-19-14{stroke-width:0.75px;}""",
|
""".cls-19-2{fill-opacity:0.6;}.cls-19-11,.cls-19-13,.cls-19-14,.cls-19-2,.cls-19-3,.cls-19-4,.cls-19-6,.cls-19-8{stroke:#000;}.cls-19-11,.cls-19-13,.cls-19-2,.cls-19-4,.cls-19-6,.cls-19-8{stroke-miterlimit:10;}.cls-19-11,.cls-19-14,.cls-19-3,.cls-19-8{fill:none;}.cls-19-14,.cls-19-3{stroke-linecap:round;stroke-linejoin:round;}.cls-19-10,.cls-19-12,.cls-19-4,.cls-19-5{fill:#fff;}.cls-19-12,.cls-19-4{fill-opacity:0.2;}.cls-19-4{stroke-opacity:0;}.cls-19-5{fill-opacity:0.1;}.cls-19-6{fill:#6d6e70;}.cls-19-7{fill:#58595b;}.cls-19-13,.cls-19-9{fill-opacity:0.4;}.cls-19-10{fill-opacity:0.5;}.cls-19-11,.cls-19-14{stroke-width:0.75px;}""",
|
||||||
"""<g id="body-10"><g id="fill_color" data-name="fill color"><path class="cls-fill-1" d="M222.5,301.5s-10-35,11-53,58-15,70,2,2,51,2,51Z"/><path class="cls-fill-1" d="M83.5,254.5s-6,28,67,26,77-30,76-36-12.3-10.12-26-13c0,5,1,22,1,22s-8,13-46,17c-29,1-45-9-45-9s-1.5-16-2.5-23.13C96.5,241.75,85.5,247.5,83.5,254.5Z"/><path class="cls-fill-1" d="M110.5,261.5s20,11,44,9,36-7,47-17l-1-24a10.53,10.53,0,0,1-.31,4.41c-.69,1.59-4.63,16.78-42.16,19.68s-47-4.1-50-16.1Z"/><rect class="cls-fill-1" x="83.5" y="250" width="143.5" height="58.5"/><path class="cls-fill-1" d="M87.5,247.5s-19-10-37-5-29,20-32,37c-1,11,1,16,3,20h64s2-5,0-16-3-23-2-29S87.5,247.5,87.5,247.5Z"/><path class="cls-fill-1" d="M108,237s-1,20,45,17,48.5-20.5,47.5-24.5c-.91-3.63-13.68-10.56-39-9.56,0,.56.26,3.3.26,3.3,1.74,9.26.74,15.26-9.26,16.26-3.41.33-10-5-10-5s-1-8-1-13C120.38,224.59,108.41,230,108,237Z"/></g><path class="cls-19-2" d="M108,237s-1,20,45,17,48.5-20.5,47.5-24.5c-.91-3.63-13.68-10.56-39-9.56,0,.56.26,3.3.26,3.3,1.74,9.26.74,15.26-9.26,16.26-3.41.33-10-5-10-5s-1-8-1-13C120.38,224.59,108.41,230,108,237Z"/><path class="cls-19-3" d="M110.5,261.5s20,11,44,9,36-7,47-17l-1-24a10.53,10.53,0,0,1-.31,4.41c-.69,1.59-4.63,16.78-42.16,19.68s-47-4.1-50-16.1Z"/><path class="cls-19-4" d="M193.37,260.15c-6.66,3.83-18.28,8.29-37.87,10.35-29,1-45-9-45-9s-1.5-16-2.5-23.13c-11.5,3.38-22.5,9.13-24.5,16.13,0,0-6,28,67,26,29.58-.81,47.84-5.89,59-12"/><path class="cls-19-5" d="M83.5,254.5s-6,28,67,26c29.58-.81,47.84-5.89,59-12-5.5-2.5-10.5-5.5-16.13-8.35-6.66,3.83-18.28,8.29-37.87,10.35-29,1-45-9-45-9s-1.5-16-2.5-23.13C96.5,241.75,85.5,247.5,83.5,254.5Z"/><path class="cls-19-6" d="M141.5,190.5v29a142.25,142.25,0,0,0,1,15,9.78,9.78,0,0,0,10,5c7-1,11-4,10-11-.36-2.54-.73-5-1-7.56a138.9,138.9,0,0,1-1-17.44v-14A69.37,69.37,0,0,0,141.5,190.5Z"/><path class="cls-19-7" d="M152.5,190.5s0,7,2,12a55.9,55.9,0,0,1,3.13,17.34c-.12,3.66.88,15.66-3.12,17.66s-2,2-2,2,7-1.57,8.48-3.79,1.94-3.24,1.23-9.23a177.33,177.33,0,0,1-1.71-24.86V189.5a37.46,37.46,0,0,0-6.17-.25l-1.83.25Z"/><path class="cls-19-8" d="M141.5,190.5v29a142.25,142.25,0,0,0,1,15,9.78,9.78,0,0,0,10,5c7-1,11-4,10-11-.36-2.54-.73-5-1-7.56a138.9,138.9,0,0,1-1-17.44v-14A69.37,69.37,0,0,0,141.5,190.5Z"/><path class="cls-19-3" d="M161.25,222.25s-2.67,3.25-9.51,3.25-10.13-2-10.13-2"/><path class="cls-19-3" d="M160,208.5s-3,3-9.06,3S142,210,142,210"/><path class="cls-19-3" d="M160,197.5s-2,2-8.06,2A86.48,86.48,0,0,1,142,199"/><path class="cls-19-9" d="M188,246.51,189.52,262s6.63-4,9.06-6l2.42-2s.72.24.36-3.88-.79-17.93-.79-17.93S200,240,188,246.51Z"/><path class="cls-19-10" d="M84,273.63S97,277,97,285s-1,9,0,14,0,4,0,4H84s3.32-3,2.41-11.26S85,279.5,85,279.5Z"/><path class="cls-19-8" d="M87.5,247.5s-19-10-37-5-29,20-32,37c-1,11,1,16,3,20h64s2-5,0-16-3-23-2-29S87.5,247.5,87.5,247.5Z"/><path class="cls-19-9" d="M87.5,247.5a63.65,63.65,0,0,0-25.06-6.39c7.06,2.39,3.06,8.39-8.94,13.39-11,6-23,10-27.5,32.5-.67,7.37.84,13.18,1.5,14.5l58-2s2-5,0-16-3-23-2-29S87.5,247.5,87.5,247.5Z"/><path class="cls-19-11" d="M33.5,299.5s-7-19-3-35a28.63,28.63,0,0,1,17-21.06"/><path class="cls-19-12" d="M62.44,241.12a3.46,3.46,0,0,1,3.06,3.38c0,3,0,4-10,9s-21.45,10-26.22,21-2.62,25-2.62,25H21.5l-3-20S27.38,241.73,62.44,241.12Z"/><path class="cls-19-9" d="M84.26,275.62A31.64,31.64,0,0,1,80.5,290.5a19.71,19.71,0,0,1-11.14,8.83l16.14.17s1.42-2.62.71-10.81A90.57,90.57,0,0,0,84.26,275.62Z"/><path class="cls-19-13" d="M222.5,301.5s-10-35,11-53,58-15,70,2,2,51,2,51Z"/><path class="cls-19-14" d="M292.5,241.5s-12-1-13,15c-1,14,4,41,7,45"/><path class="cls-19-9" d="M226.5,244.5l.74,11a39.65,39.65,0,0,0-7.12,24.19c.38,14.81,2.38,21.81,2.38,21.81h-12s1-9,.5-14.5-1.49-18.55-1.49-18.55S227.5,259.5,226.5,244.5Z"/><path class="cls-19-8" d="M209.51,268.45s18-9,17-24l.74,11a39.65,39.65,0,0,0-7.12,24.19c.38,14.81,2.38,21.81,2.38,21.81h-12"/><path class="cls-19-9" d="M293.9,242.19c-1.9-1.19,6.6,6.31,7.6,15.31s7.11,6.39,7.11,6.39-.11-8.39-5.11-13.39S295.81,243.38,293.9,242.19Z"/><circle cx="154" cy="262" r="1.5"/><circle cx="170.5" cy="259.5" r="1.5"/><circle cx="183.5" cy="255.5" r="1.5"/><circle cx="194.5" cy="250.5" r="1.5"/><circle cx="138.5" cy="261.5" r="1.5"/><circle cx="125.5" cy="259.5" r="1.5"/><circle cx="115.5" cy="255.5" r="1.5"/><path class="cls-19-8" d="M83.5,254.5s-6,28,67,26,77-30,76-36-12.3-10.12-26-13c0,5,1,22,1,22s-8,13-46,17c-29,1-45-9-45-9s-1.5-16-2.5-23.13C96.5,241.75,85.5,247.5,83.5,254.5Z"/></g>"""
|
"""<g id="body-10"><g id="fill_color" data-name="fill color"><path class="cls-fill-1" d="M222.5,301.5s-10-35,11-53,58-15,70,2,2,51,2,51Z"/><path class="cls-fill-1" d="M83.5,254.5s-6,28,67,26,77-30,76-36-12.3-10.12-26-13c0,5,1,22,1,22s-8,13-46,17c-29,1-45-9-45-9s-1.5-16-2.5-23.13C96.5,241.75,85.5,247.5,83.5,254.5Z"/><path class="cls-fill-1" d="M110.5,261.5s20,11,44,9,36-7,47-17l-1-24a10.53,10.53,0,0,1-.31,4.41c-.69,1.59-4.63,16.78-42.16,19.68s-47-4.1-50-16.1Z"/><rect class="cls-fill-1" x="83.5" y="250" width="143.5" height="58.5"/><path class="cls-fill-1" d="M87.5,247.5s-19-10-37-5-29,20-32,37c-1,11,1,16,3,20h64s2-5,0-16-3-23-2-29S87.5,247.5,87.5,247.5Z"/><path class="cls-fill-1" d="M108,237s-1,20,45,17,48.5-20.5,47.5-24.5c-.91-3.63-13.68-10.56-39-9.56,0,.56.26,3.3.26,3.3,1.74,9.26.74,15.26-9.26,16.26-3.41.33-10-5-10-5s-1-8-1-13C120.38,224.59,108.41,230,108,237Z"/></g><path class="cls-19-2" d="M108,237s-1,20,45,17,48.5-20.5,47.5-24.5c-.91-3.63-13.68-10.56-39-9.56,0,.56.26,3.3.26,3.3,1.74,9.26.74,15.26-9.26,16.26-3.41.33-10-5-10-5s-1-8-1-13C120.38,224.59,108.41,230,108,237Z"/><path class="cls-19-3" d="M110.5,261.5s20,11,44,9,36-7,47-17l-1-24a10.53,10.53,0,0,1-.31,4.41c-.69,1.59-4.63,16.78-42.16,19.68s-47-4.1-50-16.1Z"/><path class="cls-19-4" d="M193.37,260.15c-6.66,3.83-18.28,8.29-37.87,10.35-29,1-45-9-45-9s-1.5-16-2.5-23.13c-11.5,3.38-22.5,9.13-24.5,16.13,0,0-6,28,67,26,29.58-.81,47.84-5.89,59-12"/><path class="cls-19-5" d="M83.5,254.5s-6,28,67,26c29.58-.81,47.84-5.89,59-12-5.5-2.5-10.5-5.5-16.13-8.35-6.66,3.83-18.28,8.29-37.87,10.35-29,1-45-9-45-9s-1.5-16-2.5-23.13C96.5,241.75,85.5,247.5,83.5,254.5Z"/><path class="cls-19-6" d="M141.5,190.5v29a142.25,142.25,0,0,0,1,15,9.78,9.78,0,0,0,10,5c7-1,11-4,10-11-.36-2.54-.73-5-1-7.56a138.9,138.9,0,0,1-1-17.44v-14A69.37,69.37,0,0,0,141.5,190.5Z"/><path class="cls-19-7" d="M152.5,190.5s0,7,2,12a55.9,55.9,0,0,1,3.13,17.34c-.12,3.66.88,15.66-3.12,17.66s-2,2-2,2,7-1.57,8.48-3.79,1.94-3.24,1.23-9.23a177.33,177.33,0,0,1-1.71-24.86V189.5a37.46,37.46,0,0,0-6.17-.25l-1.83.25Z"/><path class="cls-19-8" d="M141.5,190.5v29a142.25,142.25,0,0,0,1,15,9.78,9.78,0,0,0,10,5c7-1,11-4,10-11-.36-2.54-.73-5-1-7.56a138.9,138.9,0,0,1-1-17.44v-14A69.37,69.37,0,0,0,141.5,190.5Z"/><path class="cls-19-3" d="M161.25,222.25s-2.67,3.25-9.51,3.25-10.13-2-10.13-2"/><path class="cls-19-3" d="M160,208.5s-3,3-9.06,3S142,210,142,210"/><path class="cls-19-3" d="M160,197.5s-2,2-8.06,2A86.48,86.48,0,0,1,142,199"/><path class="cls-19-9" d="M188,246.51,189.52,262s6.63-4,9.06-6l2.42-2s.72.24.36-3.88-.79-17.93-.79-17.93S200,240,188,246.51Z"/><path class="cls-19-10" d="M84,273.63S97,277,97,285s-1,9,0,14,0,4,0,4H84s3.32-3,2.41-11.26S85,279.5,85,279.5Z"/><path class="cls-19-8" d="M87.5,247.5s-19-10-37-5-29,20-32,37c-1,11,1,16,3,20h64s2-5,0-16-3-23-2-29S87.5,247.5,87.5,247.5Z"/><path class="cls-19-9" d="M87.5,247.5a63.65,63.65,0,0,0-25.06-6.39c7.06,2.39,3.06,8.39-8.94,13.39-11,6-23,10-27.5,32.5-.67,7.37.84,13.18,1.5,14.5l58-2s2-5,0-16-3-23-2-29S87.5,247.5,87.5,247.5Z"/><path class="cls-19-11" d="M33.5,299.5s-7-19-3-35a28.63,28.63,0,0,1,17-21.06"/><path class="cls-19-12" d="M62.44,241.12a3.46,3.46,0,0,1,3.06,3.38c0,3,0,4-10,9s-21.45,10-26.22,21-2.62,25-2.62,25H21.5l-3-20S27.38,241.73,62.44,241.12Z"/><path class="cls-19-9" d="M84.26,275.62A31.64,31.64,0,0,1,80.5,290.5a19.71,19.71,0,0,1-11.14,8.83l16.14.17s1.42-2.62.71-10.81A90.57,90.57,0,0,0,84.26,275.62Z"/><path class="cls-19-13" d="M222.5,301.5s-10-35,11-53,58-15,70,2,2,51,2,51Z"/><path class="cls-19-14" d="M292.5,241.5s-12-1-13,15c-1,14,4,41,7,45"/><path class="cls-19-9" d="M226.5,244.5l.74,11a39.65,39.65,0,0,0-7.12,24.19c.38,14.81,2.38,21.81,2.38,21.81h-12s1-9,.5-14.5-1.49-18.55-1.49-18.55S227.5,259.5,226.5,244.5Z"/><path class="cls-19-8" d="M209.51,268.45s18-9,17-24l.74,11a39.65,39.65,0,0,0-7.12,24.19c.38,14.81,2.38,21.81,2.38,21.81h-12"/><path class="cls-19-9" d="M293.9,242.19c-1.9-1.19,6.6,6.31,7.6,15.31s7.11,6.39,7.11,6.39-.11-8.39-5.11-13.39S295.81,243.38,293.9,242.19Z"/><circle cx="154" cy="262" r="1.5"/><circle cx="170.5" cy="259.5" r="1.5"/><circle cx="183.5" cy="255.5" r="1.5"/><circle cx="194.5" cy="250.5" r="1.5"/><circle cx="138.5" cy="261.5" r="1.5"/><circle cx="125.5" cy="259.5" r="1.5"/><circle cx="115.5" cy="255.5" r="1.5"/><path class="cls-19-8" d="M83.5,254.5s-6,28,67,26,77-30,76-36-12.3-10.12-26-13c0,5,1,22,1,22s-8,13-46,17c-29,1-45-9-45-9s-1.5-16-2.5-23.13C96.5,241.75,85.5,247.5,83.5,254.5Z"/></g>"""
|
||||||
),
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val eyes: List<Part> = listOf(
|
private val eyes: List<Part> = listOf(
|
||||||
@@ -243,7 +245,7 @@ private val eyes: List<Part> = listOf(
|
|||||||
Part(
|
Part(
|
||||||
""".cls-29-2{fill:#fff;}.cls-29-2,.cls-29-4{fill-opacity:0.4;}.cls-29-3{fill:none;}.cls-29-3,.cls-29-4{stroke:#000;stroke-linecap:round;stroke-linejoin:round;}.cls-29-4{stroke-width:0.75px;}""",
|
""".cls-29-2{fill:#fff;}.cls-29-2,.cls-29-4{fill-opacity:0.4;}.cls-29-3{fill:none;}.cls-29-3,.cls-29-4{stroke:#000;stroke-linecap:round;stroke-linejoin:round;}.cls-29-4{stroke-width:0.75px;}""",
|
||||||
"""<path id="fill_color" data-name="fill color" class="cls-fill-1" d="M129.5,123.5s-30,3-31,15,8,13,15,14,20-2,26-3,25,1,27-13-17-14-17-14Z"/><path class="cls-29-2" d="M116.92,125.8s-15.42,2.7-16.42,12.7,15.5,13,24.25,10.5A97.37,97.37,0,0,1,150,145.44c6.5.06,16.78-3.69,16.64-11.31S157.5,122.5,149.5,122.5s-21.12,1.13-21.12,1.13Z"/><path class="cls-29-2" d="M130.5,123.5l-8,25.5c1.6-.06,5.38-.65,9-1.2l7-24.8A47.26,47.26,0,0,1,130.5,123.5Z"/><polygon class="cls-29-2" points="120.77 124.91 113 150 118 150 125.41 124.06 120.77 124.91"/><path class="cls-29-3" d="M129.5,123.5s-30,3-31,15,8,13,15,14,20-2,26-3,25,1,27-13-17-14-17-14Z"/><path class="cls-29-4" d="M106.61,129.46s-6.11,3-6.11,9,5,13,20,11,23-4,28-4,17.29-2.5,18.15-10.25c0,0,.3,10.92-14.42,13.09s-16.25,1.2-21,2.68-28.06,4.23-32.4-7.15C98.84,143.87,95.71,134.43,106.61,129.46Z"/>"""
|
"""<path id="fill_color" data-name="fill color" class="cls-fill-1" d="M129.5,123.5s-30,3-31,15,8,13,15,14,20-2,26-3,25,1,27-13-17-14-17-14Z"/><path class="cls-29-2" d="M116.92,125.8s-15.42,2.7-16.42,12.7,15.5,13,24.25,10.5A97.37,97.37,0,0,1,150,145.44c6.5.06,16.78-3.69,16.64-11.31S157.5,122.5,149.5,122.5s-21.12,1.13-21.12,1.13Z"/><path class="cls-29-2" d="M130.5,123.5l-8,25.5c1.6-.06,5.38-.65,9-1.2l7-24.8A47.26,47.26,0,0,1,130.5,123.5Z"/><polygon class="cls-29-2" points="120.77 124.91 113 150 118 150 125.41 124.06 120.77 124.91"/><path class="cls-29-3" d="M129.5,123.5s-30,3-31,15,8,13,15,14,20-2,26-3,25,1,27-13-17-14-17-14Z"/><path class="cls-29-4" d="M106.61,129.46s-6.11,3-6.11,9,5,13,20,11,23-4,28-4,17.29-2.5,18.15-10.25c0,0,.3,10.92-14.42,13.09s-16.25,1.2-21,2.68-28.06,4.23-32.4-7.15C98.84,143.87,95.71,134.43,106.61,129.46Z"/>"""
|
||||||
),
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val faces: List<Part> = listOf(
|
private val faces: List<Part> = listOf(
|
||||||
@@ -286,7 +288,7 @@ private val faces: List<Part> = listOf(
|
|||||||
Part(
|
Part(
|
||||||
""".cls-39-2{fill:#fff;fill-opacity:0.4;}.cls-39-3{fill:none;}.cls-39-3,.cls-39-4{stroke:#000;stroke-miterlimit:10;}.cls-39-4{fill-opacity:0.2;stroke-width:0.75px;}""",
|
""".cls-39-2{fill:#fff;fill-opacity:0.4;}.cls-39-3{fill:none;}.cls-39-3,.cls-39-4{stroke:#000;stroke-miterlimit:10;}.cls-39-4{fill-opacity:0.2;stroke-width:0.75px;}""",
|
||||||
"""<path id="fill_color" data-name="fill color" class="cls-fill-1" d="M177,71s-73-2-82,51c0,0-4.5,17.5,1.5,40.5s14,50,14,50,6,10,46,6,75-25,75-25-10-100-16-108S203,72,177,71Z"/><path class="cls-39-2" d="M135.5,78.5s1,4-5,9-20,12-25,31,0,29,2,37,7,25,6,35-4.75,16-4.75,16-21.38-60.92-12.82-89S129,81,135.5,78.5Z"/><path class="cls-39-3" d="M177,71s-73-2-82,51c0,0-4.5,17.5,1.5,40.5s14,50,14,50,6,10,46,6,75-25,75-25-10-100-16-108S200.5,70.5,177,71Z"/><path class="cls-39-3" d="M177,70s-73-2-82,51c0,0-4.5,17.5,1.5,40.5s14,50,14,50,6,10,46,6,75-25,75-25-10-100-16-108S200.5,69.5,177,70Z"/><path class="cls-39-4" d="M205.5,86.5s-27,2-29,28,9,73,9,73l5.38,23.67L231.5,193.5s-8-94-15-106C216.48,87.51,208.5,86.5,205.5,86.5Z"/><circle cx="147.5" cy="214.5" r="1.5"/><circle cx="165.5" cy="211.5" r="1.5"/><circle cx="183.5" cy="206.5" r="1.5"/><circle cx="196.5" cy="202.5" r="1.5"/><circle cx="208.5" cy="198.5" r="1.5"/><circle cx="219.5" cy="194.5" r="1.5"/><circle cx="228.5" cy="190.5" r="1.5"/><circle cx="130.5" cy="214.5" r="1.5"/><circle cx="115.5" cy="210.5" r="1.5"/>"""
|
"""<path id="fill_color" data-name="fill color" class="cls-fill-1" d="M177,71s-73-2-82,51c0,0-4.5,17.5,1.5,40.5s14,50,14,50,6,10,46,6,75-25,75-25-10-100-16-108S203,72,177,71Z"/><path class="cls-39-2" d="M135.5,78.5s1,4-5,9-20,12-25,31,0,29,2,37,7,25,6,35-4.75,16-4.75,16-21.38-60.92-12.82-89S129,81,135.5,78.5Z"/><path class="cls-39-3" d="M177,71s-73-2-82,51c0,0-4.5,17.5,1.5,40.5s14,50,14,50,6,10,46,6,75-25,75-25-10-100-16-108S200.5,70.5,177,71Z"/><path class="cls-39-3" d="M177,70s-73-2-82,51c0,0-4.5,17.5,1.5,40.5s14,50,14,50,6,10,46,6,75-25,75-25-10-100-16-108S200.5,69.5,177,70Z"/><path class="cls-39-4" d="M205.5,86.5s-27,2-29,28,9,73,9,73l5.38,23.67L231.5,193.5s-8-94-15-106C216.48,87.51,208.5,86.5,205.5,86.5Z"/><circle cx="147.5" cy="214.5" r="1.5"/><circle cx="165.5" cy="211.5" r="1.5"/><circle cx="183.5" cy="206.5" r="1.5"/><circle cx="196.5" cy="202.5" r="1.5"/><circle cx="208.5" cy="198.5" r="1.5"/><circle cx="219.5" cy="194.5" r="1.5"/><circle cx="228.5" cy="190.5" r="1.5"/><circle cx="130.5" cy="214.5" r="1.5"/><circle cx="115.5" cy="210.5" r="1.5"/>"""
|
||||||
),
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val mouths: List<Part> = listOf(
|
private val mouths: List<Part> = listOf(
|
||||||
@@ -329,5 +331,5 @@ private val mouths: List<Part> = listOf(
|
|||||||
Part(
|
Part(
|
||||||
""".cls-49-2{fill:none;}.cls-49-2,.cls-49-3,.cls-49-5{stroke:#000;}.cls-49-2,.cls-49-3{stroke-linecap:round;stroke-linejoin:round;}.cls-49-3{opacity:0.1;}.cls-49-4{opacity:0.4;}.cls-49-5{fill-opacity:0.4;stroke-miterlimit:10;stroke-width:0.75px;}""",
|
""".cls-49-2{fill:none;}.cls-49-2,.cls-49-3,.cls-49-5{stroke:#000;}.cls-49-2,.cls-49-3{stroke-linecap:round;stroke-linejoin:round;}.cls-49-3{opacity:0.1;}.cls-49-4{opacity:0.4;}.cls-49-5{fill-opacity:0.4;stroke-miterlimit:10;stroke-width:0.75px;}""",
|
||||||
"""<path id="fill_color" data-name="fill color" class="cls-fill-1" d="M105.5,180.5s18,3,32,0,32-11,32-11h1.33a1.13,1.13,0,0,1,.85.65l4.82,17.35v3a3.73,3.73,0,0,1-.94,1.67c-2.53,1.85-9.8,6.88-17.06,9.3a72.67,72.67,0,0,1-25,4c-8.1,0-21.07-4.05-23.57-4.86l-.43-.14-5-19A1,1,0,0,1,105.5,180.5Z"/><path class="cls-49-2" d="M105.5,180.5s18,3,32,0,32-11,32-11h1.33a1.13,1.13,0,0,1,.85.65l4.82,17.35v3a3.73,3.73,0,0,1-.94,1.67c-2.53,1.85-9.8,6.88-17.06,9.3a72.67,72.67,0,0,1-25,4c-8.1,0-21.07-4.05-23.57-4.86l-.43-.14-5-19A1,1,0,0,1,105.5,180.5Z"/><path class="cls-49-3" d="M105.5,180.5s18,3,32,0,32-11,32-11h1.33a1.13,1.13,0,0,1,.85.65l4.82,17.35v3a3.73,3.73,0,0,1-.94,1.67c-2.53,1.85-9.8,6.88-17.06,9.3a72.67,72.67,0,0,1-25,4c-8.1,0-21.07-4.05-23.57-4.86l-.43-.14-5-19A1,1,0,0,1,105.5,180.5Z"/><path class="cls-49-4" d="M108.33,195.83c0-.11-2.8-10.45-3.4-12.94a6.79,6.79,0,0,1-.3-2,2.1,2.1,0,0,1,.46,0,3,3,0,0,1,1.77.84c.32.85,3,8.16,4,11.88a31.56,31.56,0,0,1,1,5.64l-2.35.78Z"/><path d="M105.08,181.25h.09a2.55,2.55,0,0,1,1.36.68c.43,1.16,3,8.16,3.91,11.75a33.25,33.25,0,0,1,.95,5.29l-1.7.57-1-3.8c0-.1-2.8-10.45-3.4-12.93a13.31,13.31,0,0,1-.31-1.55h.1m0-.75c-.92,0-1.11,0-.52,2.48S108,195.93,108,195.93l1.2,4.57,3-1a28,28,0,0,0-1-6c-1-4-4-12-4-12a3.49,3.49,0,0,0-2-1Z"/><path class="cls-49-5" d="M111.5,199.5s17,6,36,2,29-11.87,29-11.87v.88l-.36.94-.44.64L174,193.33l-7,4.33L159.9,201l-10.68,3-4.63.79-5.34.51-5.75.16-5.06-.39L121,203.7,114.57,202l-5.07-1.54-.12-.67Z"/><path class="cls-49-2" d="M116.51,200.51c1-3,3-11,3-11s4,2,13,2,27-7,27-7,7,6,8,10"/>"""
|
"""<path id="fill_color" data-name="fill color" class="cls-fill-1" d="M105.5,180.5s18,3,32,0,32-11,32-11h1.33a1.13,1.13,0,0,1,.85.65l4.82,17.35v3a3.73,3.73,0,0,1-.94,1.67c-2.53,1.85-9.8,6.88-17.06,9.3a72.67,72.67,0,0,1-25,4c-8.1,0-21.07-4.05-23.57-4.86l-.43-.14-5-19A1,1,0,0,1,105.5,180.5Z"/><path class="cls-49-2" d="M105.5,180.5s18,3,32,0,32-11,32-11h1.33a1.13,1.13,0,0,1,.85.65l4.82,17.35v3a3.73,3.73,0,0,1-.94,1.67c-2.53,1.85-9.8,6.88-17.06,9.3a72.67,72.67,0,0,1-25,4c-8.1,0-21.07-4.05-23.57-4.86l-.43-.14-5-19A1,1,0,0,1,105.5,180.5Z"/><path class="cls-49-3" d="M105.5,180.5s18,3,32,0,32-11,32-11h1.33a1.13,1.13,0,0,1,.85.65l4.82,17.35v3a3.73,3.73,0,0,1-.94,1.67c-2.53,1.85-9.8,6.88-17.06,9.3a72.67,72.67,0,0,1-25,4c-8.1,0-21.07-4.05-23.57-4.86l-.43-.14-5-19A1,1,0,0,1,105.5,180.5Z"/><path class="cls-49-4" d="M108.33,195.83c0-.11-2.8-10.45-3.4-12.94a6.79,6.79,0,0,1-.3-2,2.1,2.1,0,0,1,.46,0,3,3,0,0,1,1.77.84c.32.85,3,8.16,4,11.88a31.56,31.56,0,0,1,1,5.64l-2.35.78Z"/><path d="M105.08,181.25h.09a2.55,2.55,0,0,1,1.36.68c.43,1.16,3,8.16,3.91,11.75a33.25,33.25,0,0,1,.95,5.29l-1.7.57-1-3.8c0-.1-2.8-10.45-3.4-12.93a13.31,13.31,0,0,1-.31-1.55h.1m0-.75c-.92,0-1.11,0-.52,2.48S108,195.93,108,195.93l1.2,4.57,3-1a28,28,0,0,0-1-6c-1-4-4-12-4-12a3.49,3.49,0,0,0-2-1Z"/><path class="cls-49-5" d="M111.5,199.5s17,6,36,2,29-11.87,29-11.87v.88l-.36.94-.44.64L174,193.33l-7,4.33L159.9,201l-10.68,3-4.63.79-5.34.51-5.75.16-5.06-.39L121,203.7,114.57,202l-5.07-1.54-.12-.67Z"/><path class="cls-49-2" d="M116.51,200.51c1-3,3-11,3-11s4,2,13,2,27-7,27-7,7,6,8,10"/>"""
|
||||||
),
|
)
|
||||||
)
|
)
|
||||||
|
@@ -1,257 +1,256 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.navigation
|
package com.vitorpamplona.amethyst.ui.navigation
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxHeight
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.material.Divider
|
import androidx.compose.material.Divider
|
||||||
import androidx.compose.material.Icon
|
import androidx.compose.material.Icon
|
||||||
import androidx.compose.material.IconButton
|
import androidx.compose.material.IconButton
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
import androidx.compose.material.ScaffoldState
|
import androidx.compose.material.ScaffoldState
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.material.TopAppBar
|
import androidx.compose.material.TopAppBar
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.ArrowBack
|
import androidx.compose.material.icons.filled.ArrowBack
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
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.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
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.painter.BitmapPainter
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.NavHostController
|
import coil.Coil
|
||||||
import coil.Coil
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.model.LocalCache
|
||||||
import com.vitorpamplona.amethyst.RoboHashCache
|
import com.vitorpamplona.amethyst.service.NostrAccountDataSource
|
||||||
import com.vitorpamplona.amethyst.model.LocalCache
|
import com.vitorpamplona.amethyst.service.NostrChannelDataSource
|
||||||
import com.vitorpamplona.amethyst.service.NostrAccountDataSource
|
import com.vitorpamplona.amethyst.service.NostrChatroomDataSource
|
||||||
import com.vitorpamplona.amethyst.service.NostrChannelDataSource
|
import com.vitorpamplona.amethyst.service.NostrChatroomListDataSource
|
||||||
import com.vitorpamplona.amethyst.service.NostrChatroomDataSource
|
import com.vitorpamplona.amethyst.service.NostrGlobalDataSource
|
||||||
import com.vitorpamplona.amethyst.service.NostrChatroomListDataSource
|
import com.vitorpamplona.amethyst.service.NostrHomeDataSource
|
||||||
import com.vitorpamplona.amethyst.service.NostrGlobalDataSource
|
import com.vitorpamplona.amethyst.service.NostrSearchEventOrUserDataSource
|
||||||
import com.vitorpamplona.amethyst.service.NostrHomeDataSource
|
import com.vitorpamplona.amethyst.service.NostrSingleChannelDataSource
|
||||||
import com.vitorpamplona.amethyst.service.NostrSearchEventOrUserDataSource
|
import com.vitorpamplona.amethyst.service.NostrSingleEventDataSource
|
||||||
import com.vitorpamplona.amethyst.service.NostrSingleChannelDataSource
|
import com.vitorpamplona.amethyst.service.NostrSingleUserDataSource
|
||||||
import com.vitorpamplona.amethyst.service.NostrSingleEventDataSource
|
import com.vitorpamplona.amethyst.service.NostrThreadDataSource
|
||||||
import com.vitorpamplona.amethyst.service.NostrSingleUserDataSource
|
import com.vitorpamplona.amethyst.service.NostrUserProfileDataSource
|
||||||
import com.vitorpamplona.amethyst.service.NostrThreadDataSource
|
import com.vitorpamplona.amethyst.service.relays.Client
|
||||||
import com.vitorpamplona.amethyst.service.NostrUserProfileDataSource
|
import com.vitorpamplona.amethyst.service.relays.RelayPool
|
||||||
import com.vitorpamplona.amethyst.service.relays.Client
|
import com.vitorpamplona.amethyst.ui.actions.NewRelayListView
|
||||||
import com.vitorpamplona.amethyst.service.relays.RelayPool
|
import com.vitorpamplona.amethyst.ui.components.AsyncUserImageProxy
|
||||||
import com.vitorpamplona.amethyst.ui.actions.NewRelayListView
|
import com.vitorpamplona.amethyst.ui.components.ResizeImage
|
||||||
import com.vitorpamplona.amethyst.ui.components.AsyncImageProxy
|
import com.vitorpamplona.amethyst.ui.screen.RelayPoolViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.components.ResizeImage
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.RelayPoolViewModel
|
import kotlinx.coroutines.launch
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
|
||||||
import kotlinx.coroutines.launch
|
@Composable
|
||||||
|
fun AppTopBar(navController: NavHostController, scaffoldState: ScaffoldState, accountViewModel: AccountViewModel) {
|
||||||
@Composable
|
when (currentRoute(navController)) {
|
||||||
fun AppTopBar(navController: NavHostController, scaffoldState: ScaffoldState, accountViewModel: AccountViewModel) {
|
// Route.Profile.route -> TopBarWithBackButton(navController)
|
||||||
when (currentRoute(navController)) {
|
else -> MainTopBar(scaffoldState, accountViewModel)
|
||||||
// Route.Profile.route -> TopBarWithBackButton(navController)
|
}
|
||||||
else -> MainTopBar(scaffoldState, accountViewModel)
|
}
|
||||||
}
|
|
||||||
}
|
@Composable
|
||||||
|
fun MainTopBar(scaffoldState: ScaffoldState, accountViewModel: AccountViewModel) {
|
||||||
@Composable
|
val accountState by accountViewModel.accountLiveData.observeAsState()
|
||||||
fun MainTopBar(scaffoldState: ScaffoldState, accountViewModel: AccountViewModel) {
|
val account = accountState?.account ?: return
|
||||||
val accountState by accountViewModel.accountLiveData.observeAsState()
|
|
||||||
val account = accountState?.account ?: return
|
val accountUserState by account.userProfile().live().metadata.observeAsState()
|
||||||
|
val accountUser = accountUserState?.user ?: return
|
||||||
val accountUserState by account.userProfile().live().metadata.observeAsState()
|
|
||||||
val accountUser = accountUserState?.user ?: return
|
val relayViewModel: RelayPoolViewModel = viewModel { RelayPoolViewModel() }
|
||||||
|
val connectedRelaysLiveData by relayViewModel.connectedRelaysLiveData.observeAsState()
|
||||||
val relayViewModel: RelayPoolViewModel = viewModel { RelayPoolViewModel() }
|
val availableRelaysLiveData by relayViewModel.availableRelaysLiveData.observeAsState()
|
||||||
val connectedRelaysLiveData by relayViewModel.connectedRelaysLiveData.observeAsState()
|
|
||||||
val availableRelaysLiveData by relayViewModel.availableRelaysLiveData.observeAsState()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val context = LocalContext.current
|
||||||
|
val ctx = LocalContext.current.applicationContext
|
||||||
val context = LocalContext.current
|
|
||||||
val ctx = LocalContext.current.applicationContext
|
var wantsToEditRelays by remember {
|
||||||
|
mutableStateOf(false)
|
||||||
var wantsToEditRelays by remember {
|
}
|
||||||
mutableStateOf(false)
|
|
||||||
}
|
if (wantsToEditRelays) {
|
||||||
|
NewRelayListView({ wantsToEditRelays = false }, account)
|
||||||
if (wantsToEditRelays) {
|
}
|
||||||
NewRelayListView({ wantsToEditRelays = false }, account)
|
|
||||||
}
|
Column() {
|
||||||
|
TopAppBar(
|
||||||
Column() {
|
elevation = 0.dp,
|
||||||
TopAppBar(
|
backgroundColor = Color(0xFFFFFF),
|
||||||
elevation = 0.dp,
|
title = {
|
||||||
backgroundColor = Color(0xFFFFFF),
|
Column(
|
||||||
title = {
|
modifier = Modifier.fillMaxWidth(),
|
||||||
Column(
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
modifier = Modifier.fillMaxWidth(),
|
) {
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
Box(Modifier) {
|
||||||
) {
|
Column(
|
||||||
Box(Modifier) {
|
modifier = Modifier
|
||||||
Column(
|
.fillMaxWidth()
|
||||||
modifier = Modifier
|
.fillMaxHeight()
|
||||||
.fillMaxWidth()
|
.padding(start = 0.dp, end = 20.dp),
|
||||||
.fillMaxHeight()
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
.padding(start = 0.dp, end = 20.dp),
|
verticalArrangement = Arrangement.Center
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
) {
|
||||||
verticalArrangement = Arrangement.Center
|
IconButton(
|
||||||
) {
|
onClick = {
|
||||||
IconButton(
|
Client.allSubscriptions().map {
|
||||||
onClick = {
|
"$it ${
|
||||||
Client.allSubscriptions().map {
|
Client.getSubscriptionFilters(it)
|
||||||
"$it ${
|
.joinToString { it.filter.toJson() }
|
||||||
Client.getSubscriptionFilters(it)
|
}"
|
||||||
.joinToString { it.filter.toJson() }
|
}.forEach {
|
||||||
}"
|
Log.d("STATE DUMP", it)
|
||||||
}.forEach {
|
}
|
||||||
Log.d("STATE DUMP", it)
|
|
||||||
}
|
NostrAccountDataSource.printCounter()
|
||||||
|
NostrChannelDataSource.printCounter()
|
||||||
NostrAccountDataSource.printCounter()
|
NostrChatroomDataSource.printCounter()
|
||||||
NostrChannelDataSource.printCounter()
|
NostrChatroomListDataSource.printCounter()
|
||||||
NostrChatroomDataSource.printCounter()
|
|
||||||
NostrChatroomListDataSource.printCounter()
|
NostrGlobalDataSource.printCounter()
|
||||||
|
NostrHomeDataSource.printCounter()
|
||||||
NostrGlobalDataSource.printCounter()
|
|
||||||
NostrHomeDataSource.printCounter()
|
NostrSingleEventDataSource.printCounter()
|
||||||
|
NostrSearchEventOrUserDataSource.printCounter()
|
||||||
NostrSingleEventDataSource.printCounter()
|
NostrSingleChannelDataSource.printCounter()
|
||||||
NostrSearchEventOrUserDataSource.printCounter()
|
NostrSingleUserDataSource.printCounter()
|
||||||
NostrSingleChannelDataSource.printCounter()
|
NostrThreadDataSource.printCounter()
|
||||||
NostrSingleUserDataSource.printCounter()
|
|
||||||
NostrThreadDataSource.printCounter()
|
NostrUserProfileDataSource.printCounter()
|
||||||
|
|
||||||
NostrUserProfileDataSource.printCounter()
|
Log.d("STATE DUMP", "Connected Relays: " + RelayPool.connectedRelays())
|
||||||
|
|
||||||
Log.d("STATE DUMP", "Connected Relays: " + RelayPool.connectedRelays())
|
val imageLoader = Coil.imageLoader(context)
|
||||||
|
Log.d("STATE DUMP", "Image Disk Cache ${(imageLoader.diskCache?.size ?: 0) / (1024 * 1024)}/${(imageLoader.diskCache?.maxSize ?: 0) / (1024 * 1024)} MB")
|
||||||
val imageLoader = Coil.imageLoader(context)
|
Log.d("STATE DUMP", "Image Memory Cache ${(imageLoader.memoryCache?.size ?: 0) / (1024 * 1024)}/${(imageLoader.memoryCache?.maxSize ?: 0) / (1024 * 1024)} MB")
|
||||||
Log.d("STATE DUMP", "Image Disk Cache ${(imageLoader.diskCache?.size ?: 0) / (1024 * 1024)}/${(imageLoader.diskCache?.maxSize ?: 0) / (1024 * 1024)} MB")
|
|
||||||
Log.d("STATE DUMP", "Image Memory Cache ${(imageLoader.memoryCache?.size ?: 0) / (1024 * 1024)}/${(imageLoader.memoryCache?.maxSize ?: 0) / (1024 * 1024)} MB")
|
Log.d("STATE DUMP", "Notes: " + LocalCache.notes.filter { it.value.event != null }.size + "/" + LocalCache.notes.size)
|
||||||
|
Log.d("STATE DUMP", "Users: " + LocalCache.users.filter { it.value.info?.latestMetadata != null }.size + "/" + LocalCache.users.size)
|
||||||
Log.d("STATE DUMP", "Notes: " + LocalCache.notes.filter { it.value.event != null }.size + "/" + LocalCache.notes.size)
|
}
|
||||||
Log.d("STATE DUMP", "Users: " + LocalCache.users.filter { it.value.info?.latestMetadata != null }.size + "/" + LocalCache.users.size)
|
) {
|
||||||
}
|
Icon(
|
||||||
) {
|
painter = painterResource(R.drawable.amethyst),
|
||||||
Icon(
|
null,
|
||||||
painter = painterResource(R.drawable.amethyst),
|
modifier = Modifier.size(40.dp),
|
||||||
null,
|
tint = Color.Unspecified
|
||||||
modifier = Modifier.size(40.dp),
|
)
|
||||||
tint = Color.Unspecified
|
}
|
||||||
)
|
}
|
||||||
}
|
|
||||||
}
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
Column(
|
.fillMaxWidth()
|
||||||
modifier = Modifier
|
.fillMaxHeight(),
|
||||||
.fillMaxWidth()
|
horizontalAlignment = Alignment.End
|
||||||
.fillMaxHeight(),
|
|
||||||
horizontalAlignment = Alignment.End
|
) {
|
||||||
|
Row(
|
||||||
) {
|
modifier = Modifier.fillMaxHeight(),
|
||||||
Row(
|
verticalAlignment = Alignment.CenterVertically
|
||||||
modifier = Modifier.fillMaxHeight(),
|
) {
|
||||||
verticalAlignment = Alignment.CenterVertically
|
Text(
|
||||||
) {
|
"${connectedRelaysLiveData ?: "--"}/${availableRelaysLiveData ?: "--"}",
|
||||||
Text(
|
color = if (connectedRelaysLiveData == 0) Color.Red else MaterialTheme.colors.onSurface.copy(alpha = 0.32f),
|
||||||
"${connectedRelaysLiveData ?: "--"}/${availableRelaysLiveData ?: "--"}",
|
style = MaterialTheme.typography.subtitle1,
|
||||||
color = if (connectedRelaysLiveData == 0) Color.Red else MaterialTheme.colors.onSurface.copy(alpha = 0.32f),
|
modifier = Modifier.clickable(
|
||||||
style = MaterialTheme.typography.subtitle1,
|
onClick = {
|
||||||
modifier = Modifier.clickable(
|
wantsToEditRelays = true
|
||||||
onClick = {
|
}
|
||||||
wantsToEditRelays = true
|
)
|
||||||
}
|
)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
navigationIcon = {
|
||||||
},
|
IconButton(
|
||||||
navigationIcon = {
|
onClick = {
|
||||||
IconButton(
|
coroutineScope.launch {
|
||||||
onClick = {
|
scaffoldState.drawerState.open()
|
||||||
coroutineScope.launch {
|
}
|
||||||
scaffoldState.drawerState.open()
|
},
|
||||||
}
|
modifier = Modifier
|
||||||
},
|
) {
|
||||||
modifier = Modifier
|
AsyncUserImageProxy(
|
||||||
) {
|
pubkeyHex = accountUser.pubkeyHex,
|
||||||
AsyncImageProxy(
|
model = ResizeImage(accountUser.profilePicture(), 34.dp),
|
||||||
model = ResizeImage(accountUser.profilePicture(), 34.dp),
|
// placeholder = BitmapPainter(RoboHashCache.get(ctx, accountUser.pubkeyHex)),
|
||||||
placeholder = BitmapPainter(RoboHashCache.get(ctx, accountUser.pubkeyHex)),
|
// fallback = BitmapPainter(RoboHashCache.get(ctx, accountUser.pubkeyHex)),
|
||||||
fallback = BitmapPainter(RoboHashCache.get(ctx, accountUser.pubkeyHex)),
|
// error = BitmapPainter(RoboHashCache.get(ctx, accountUser.pubkeyHex)),
|
||||||
error = BitmapPainter(RoboHashCache.get(ctx, accountUser.pubkeyHex)),
|
contentDescription = stringResource(id = R.string.profile_image),
|
||||||
contentDescription = stringResource(id = R.string.profile_image),
|
modifier = Modifier
|
||||||
modifier = Modifier
|
.width(34.dp)
|
||||||
.width(34.dp)
|
.height(34.dp)
|
||||||
.height(34.dp)
|
.clip(shape = CircleShape)
|
||||||
.clip(shape = CircleShape)
|
)
|
||||||
)
|
}
|
||||||
}
|
},
|
||||||
},
|
actions = {
|
||||||
actions = {
|
IconButton(
|
||||||
IconButton(
|
onClick = { wantsToEditRelays = true },
|
||||||
onClick = { wantsToEditRelays = true },
|
modifier = Modifier
|
||||||
modifier = Modifier
|
) {
|
||||||
) {
|
Icon(
|
||||||
Icon(
|
painter = painterResource(R.drawable.ic_trends),
|
||||||
painter = painterResource(R.drawable.ic_trends),
|
null,
|
||||||
null,
|
modifier = Modifier.size(24.dp),
|
||||||
modifier = Modifier.size(24.dp),
|
tint = Color.Unspecified
|
||||||
tint = Color.Unspecified
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
)
|
Divider(thickness = 0.25.dp)
|
||||||
Divider(thickness = 0.25.dp)
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@Composable
|
||||||
@Composable
|
fun TopBarWithBackButton(navController: NavHostController) {
|
||||||
fun TopBarWithBackButton(navController: NavHostController) {
|
Column() {
|
||||||
Column() {
|
TopAppBar(
|
||||||
TopAppBar(
|
elevation = 0.dp,
|
||||||
elevation = 0.dp,
|
backgroundColor = Color(0xFFFFFF),
|
||||||
backgroundColor = Color(0xFFFFFF),
|
title = {},
|
||||||
title = {},
|
navigationIcon = {
|
||||||
navigationIcon = {
|
IconButton(
|
||||||
IconButton(
|
onClick = {
|
||||||
onClick = {
|
navController.popBackStack()
|
||||||
navController.popBackStack()
|
},
|
||||||
},
|
modifier = Modifier
|
||||||
modifier = Modifier
|
) {
|
||||||
) {
|
Icon(
|
||||||
Icon(
|
imageVector = Icons.Filled.ArrowBack,
|
||||||
imageVector = Icons.Filled.ArrowBack,
|
null,
|
||||||
null,
|
modifier = Modifier.size(28.dp),
|
||||||
modifier = Modifier.size(28.dp),
|
tint = MaterialTheme.colors.primary
|
||||||
tint = MaterialTheme.colors.primary
|
)
|
||||||
)
|
}
|
||||||
}
|
},
|
||||||
},
|
actions = {}
|
||||||
actions = {}
|
)
|
||||||
)
|
Divider(thickness = 0.25.dp)
|
||||||
Divider(thickness = 0.25.dp)
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@@ -35,7 +35,6 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.painter.BitmapPainter
|
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
@@ -48,10 +47,9 @@ import androidx.navigation.NavHostController
|
|||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import com.vitorpamplona.amethyst.BuildConfig
|
import com.vitorpamplona.amethyst.BuildConfig
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.RoboHashCache
|
|
||||||
import com.vitorpamplona.amethyst.model.Account
|
import com.vitorpamplona.amethyst.model.Account
|
||||||
import com.vitorpamplona.amethyst.model.User
|
import com.vitorpamplona.amethyst.model.User
|
||||||
import com.vitorpamplona.amethyst.ui.components.AsyncImageProxy
|
import com.vitorpamplona.amethyst.ui.components.AsyncUserImageProxy
|
||||||
import com.vitorpamplona.amethyst.ui.components.ResizeImage
|
import com.vitorpamplona.amethyst.ui.components.ResizeImage
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountBackupDialog
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountBackupDialog
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
@@ -137,12 +135,13 @@ fun ProfileContent(baseAccountUser: User, modifier: Modifier = Modifier, scaffol
|
|||||||
}
|
}
|
||||||
|
|
||||||
Column(modifier = modifier) {
|
Column(modifier = modifier) {
|
||||||
AsyncImageProxy(
|
AsyncUserImageProxy(
|
||||||
|
pubkeyHex = accountUser.pubkeyHex,
|
||||||
model = ResizeImage(accountUser.profilePicture(), 100.dp),
|
model = ResizeImage(accountUser.profilePicture(), 100.dp),
|
||||||
contentDescription = stringResource(id = R.string.profile_image),
|
contentDescription = stringResource(id = R.string.profile_image),
|
||||||
placeholder = BitmapPainter(RoboHashCache.get(ctx, accountUser.pubkeyHex)),
|
// placeholder = BitmapPainter(RoboHashCache.get(ctx, accountUser.pubkeyHex)),
|
||||||
fallback = BitmapPainter(RoboHashCache.get(ctx, accountUser.pubkeyHex)),
|
// fallback = BitmapPainter(RoboHashCache.get(ctx, accountUser.pubkeyHex)),
|
||||||
error = BitmapPainter(RoboHashCache.get(ctx, accountUser.pubkeyHex)),
|
// error = BitmapPainter(RoboHashCache.get(ctx, accountUser.pubkeyHex)),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(100.dp)
|
.width(100.dp)
|
||||||
.height(100.dp)
|
.height(100.dp)
|
||||||
|
@@ -60,7 +60,7 @@ import com.vitorpamplona.amethyst.model.Note
|
|||||||
import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent
|
import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent
|
||||||
import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent
|
import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent
|
||||||
import com.vitorpamplona.amethyst.service.model.ChannelMetadataEvent
|
import com.vitorpamplona.amethyst.service.model.ChannelMetadataEvent
|
||||||
import com.vitorpamplona.amethyst.ui.components.AsyncImageProxy
|
import com.vitorpamplona.amethyst.ui.components.AsyncUserImageProxy
|
||||||
import com.vitorpamplona.amethyst.ui.components.ResizeImage
|
import com.vitorpamplona.amethyst.ui.components.ResizeImage
|
||||||
import com.vitorpamplona.amethyst.ui.components.TranslateableRichTextViewer
|
import com.vitorpamplona.amethyst.ui.components.TranslateableRichTextViewer
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
@@ -195,11 +195,12 @@ fun ChatroomMessageCompose(
|
|||||||
horizontalArrangement = alignment,
|
horizontalArrangement = alignment,
|
||||||
modifier = Modifier.padding(top = 5.dp)
|
modifier = Modifier.padding(top = 5.dp)
|
||||||
) {
|
) {
|
||||||
AsyncImageProxy(
|
AsyncUserImageProxy(
|
||||||
|
pubkeyHex = author.pubkeyHex,
|
||||||
model = ResizeImage(author.profilePicture(), 25.dp),
|
model = ResizeImage(author.profilePicture(), 25.dp),
|
||||||
placeholder = BitmapPainter(RoboHashCache.get(context, author.pubkeyHex)),
|
// placeholder = BitmapPainter(RoboHashCache.get(context, author.pubkeyHex)),
|
||||||
fallback = BitmapPainter(RoboHashCache.get(context, author.pubkeyHex)),
|
// fallback = BitmapPainter(RoboHashCache.get(context, author.pubkeyHex)),
|
||||||
error = BitmapPainter(RoboHashCache.get(context, author.pubkeyHex)),
|
// error = BitmapPainter(RoboHashCache.get(context, author.pubkeyHex)),
|
||||||
contentDescription = stringResource(id = R.string.profile_image),
|
contentDescription = stringResource(id = R.string.profile_image),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(25.dp)
|
.width(25.dp)
|
||||||
|
@@ -53,7 +53,7 @@ import com.vitorpamplona.amethyst.service.model.ReactionEvent
|
|||||||
import com.vitorpamplona.amethyst.service.model.ReportEvent
|
import com.vitorpamplona.amethyst.service.model.ReportEvent
|
||||||
import com.vitorpamplona.amethyst.service.model.RepostEvent
|
import com.vitorpamplona.amethyst.service.model.RepostEvent
|
||||||
import com.vitorpamplona.amethyst.service.model.TextNoteEvent
|
import com.vitorpamplona.amethyst.service.model.TextNoteEvent
|
||||||
import com.vitorpamplona.amethyst.ui.components.AsyncImageProxy
|
import com.vitorpamplona.amethyst.ui.components.AsyncUserImageProxy
|
||||||
import com.vitorpamplona.amethyst.ui.components.ObserveDisplayNip05Status
|
import com.vitorpamplona.amethyst.ui.components.ObserveDisplayNip05Status
|
||||||
import com.vitorpamplona.amethyst.ui.components.ResizeImage
|
import com.vitorpamplona.amethyst.ui.components.ResizeImage
|
||||||
import com.vitorpamplona.amethyst.ui.components.TranslateableRichTextViewer
|
import com.vitorpamplona.amethyst.ui.components.TranslateableRichTextViewer
|
||||||
@@ -217,11 +217,12 @@ fun NoteCompose(
|
|||||||
.height(30.dp)
|
.height(30.dp)
|
||||||
.align(Alignment.BottomEnd)
|
.align(Alignment.BottomEnd)
|
||||||
) {
|
) {
|
||||||
AsyncImageProxy(
|
AsyncUserImageProxy(
|
||||||
|
pubkeyHex = channel.idHex,
|
||||||
model = ResizeImage(channel.profilePicture(), 30.dp),
|
model = ResizeImage(channel.profilePicture(), 30.dp),
|
||||||
placeholder = BitmapPainter(RoboHashCache.get(context, channel.idHex)),
|
// placeholder = BitmapPainter(RoboHashCache.get(context, channel.idHex)),
|
||||||
fallback = BitmapPainter(RoboHashCache.get(context, channel.idHex)),
|
// fallback = BitmapPainter(RoboHashCache.get(context, channel.idHex)),
|
||||||
error = BitmapPainter(RoboHashCache.get(context, channel.idHex)),
|
// error = BitmapPainter(RoboHashCache.get(context, channel.idHex)),
|
||||||
contentDescription = stringResource(R.string.group_picture),
|
contentDescription = stringResource(R.string.group_picture),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(30.dp)
|
.width(30.dp)
|
||||||
@@ -723,12 +724,10 @@ fun UserPicture(
|
|||||||
.width(size)
|
.width(size)
|
||||||
.height(size)
|
.height(size)
|
||||||
) {
|
) {
|
||||||
AsyncImageProxy(
|
AsyncUserImageProxy(
|
||||||
|
pubkeyHex = user.pubkeyHex,
|
||||||
model = ResizeImage(user.profilePicture(), size),
|
model = ResizeImage(user.profilePicture(), size),
|
||||||
contentDescription = stringResource(id = R.string.profile_image),
|
contentDescription = stringResource(id = R.string.profile_image),
|
||||||
placeholder = BitmapPainter(RoboHashCache.get(ctx, user.pubkeyHex)),
|
|
||||||
fallback = BitmapPainter(RoboHashCache.get(ctx, user.pubkeyHex)),
|
|
||||||
error = BitmapPainter(RoboHashCache.get(ctx, user.pubkeyHex)),
|
|
||||||
modifier = pictureModifier
|
modifier = pictureModifier
|
||||||
.fillMaxSize(1f)
|
.fillMaxSize(1f)
|
||||||
.clip(shape = CircleShape)
|
.clip(shape = CircleShape)
|
||||||
|
@@ -1,157 +1,153 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.navigation
|
package com.vitorpamplona.amethyst.ui.navigation
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.Button
|
import androidx.compose.material.Button
|
||||||
import androidx.compose.material.ButtonDefaults
|
import androidx.compose.material.ButtonDefaults
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
import androidx.compose.material.Surface
|
import androidx.compose.material.Surface
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
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
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.painter.BitmapPainter
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.window.Dialog
|
||||||
import androidx.compose.ui.window.Dialog
|
import androidx.compose.ui.window.DialogProperties
|
||||||
import androidx.compose.ui.window.DialogProperties
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.model.User
|
||||||
import com.vitorpamplona.amethyst.RoboHashCache
|
import com.vitorpamplona.amethyst.ui.actions.CloseButton
|
||||||
import com.vitorpamplona.amethyst.model.User
|
import com.vitorpamplona.amethyst.ui.components.ResizeImage
|
||||||
import com.vitorpamplona.amethyst.ui.actions.CloseButton
|
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy
|
||||||
import com.vitorpamplona.amethyst.ui.components.AsyncImageProxy
|
import com.vitorpamplona.amethyst.ui.qrcode.QrCodeScanner
|
||||||
import com.vitorpamplona.amethyst.ui.components.ResizeImage
|
|
||||||
import com.vitorpamplona.amethyst.ui.qrcode.QrCodeScanner
|
@Composable
|
||||||
|
fun ShowQRDialog(user: User, onScan: (String) -> Unit, onClose: () -> Unit) {
|
||||||
@Composable
|
var presenting by remember { mutableStateOf(true) }
|
||||||
fun ShowQRDialog(user: User, onScan: (String) -> Unit, onClose: () -> Unit) {
|
|
||||||
var presenting by remember { mutableStateOf(true) }
|
val ctx = LocalContext.current.applicationContext
|
||||||
|
|
||||||
val ctx = LocalContext.current.applicationContext
|
Dialog(
|
||||||
|
onDismissRequest = onClose,
|
||||||
Dialog(
|
properties = DialogProperties(usePlatformDefaultWidth = false)
|
||||||
onDismissRequest = onClose,
|
) {
|
||||||
properties = DialogProperties(usePlatformDefaultWidth = false)
|
Surface(modifier = Modifier.fillMaxSize()) {
|
||||||
) {
|
Column(
|
||||||
Surface(modifier = Modifier.fillMaxSize()) {
|
modifier = Modifier
|
||||||
Column(
|
.background(MaterialTheme.colors.background)
|
||||||
modifier = Modifier
|
.fillMaxSize()
|
||||||
.background(MaterialTheme.colors.background)
|
) {
|
||||||
.fillMaxSize()
|
Row(
|
||||||
) {
|
modifier = Modifier
|
||||||
Row(
|
.fillMaxWidth()
|
||||||
modifier = Modifier
|
.padding(10.dp),
|
||||||
.fillMaxWidth()
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
.padding(10.dp),
|
verticalAlignment = Alignment.CenterVertically
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
) {
|
||||||
verticalAlignment = Alignment.CenterVertically
|
CloseButton(onCancel = onClose)
|
||||||
) {
|
}
|
||||||
CloseButton(onCancel = onClose)
|
|
||||||
}
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
Column(
|
.fillMaxSize()
|
||||||
modifier = Modifier
|
.padding(horizontal = 10.dp),
|
||||||
.fillMaxSize()
|
verticalArrangement = Arrangement.SpaceBetween
|
||||||
.padding(horizontal = 10.dp),
|
) {
|
||||||
verticalArrangement = Arrangement.SpaceBetween
|
if (presenting) {
|
||||||
) {
|
Row(
|
||||||
if (presenting) {
|
horizontalArrangement = Arrangement.Center,
|
||||||
Row(
|
modifier = Modifier
|
||||||
horizontalArrangement = Arrangement.Center,
|
.fillMaxWidth()
|
||||||
modifier = Modifier
|
.padding(horizontal = 30.dp, vertical = 10.dp)
|
||||||
.fillMaxWidth()
|
) {
|
||||||
.padding(horizontal = 30.dp, vertical = 10.dp)
|
}
|
||||||
) {
|
|
||||||
}
|
Column(modifier = Modifier.fillMaxWidth()) {
|
||||||
|
Row(horizontalArrangement = Arrangement.Center, modifier = Modifier.fillMaxWidth()) {
|
||||||
Column(modifier = Modifier.fillMaxWidth()) {
|
RobohashAsyncImageProxy(
|
||||||
Row(horizontalArrangement = Arrangement.Center, modifier = Modifier.fillMaxWidth()) {
|
robot = user.pubkeyHex,
|
||||||
AsyncImageProxy(
|
model = ResizeImage(user.profilePicture(), 100.dp),
|
||||||
model = ResizeImage(user.profilePicture(), 100.dp),
|
contentDescription = stringResource(R.string.profile_image),
|
||||||
placeholder = BitmapPainter(RoboHashCache.get(ctx, user.pubkeyHex)),
|
modifier = Modifier
|
||||||
fallback = BitmapPainter(RoboHashCache.get(ctx, user.pubkeyHex)),
|
.width(100.dp)
|
||||||
error = BitmapPainter(RoboHashCache.get(ctx, user.pubkeyHex)),
|
.height(100.dp)
|
||||||
contentDescription = stringResource(R.string.profile_image),
|
.clip(shape = CircleShape)
|
||||||
modifier = Modifier
|
.border(3.dp, MaterialTheme.colors.background, CircleShape)
|
||||||
.width(100.dp)
|
.background(MaterialTheme.colors.background)
|
||||||
.height(100.dp)
|
)
|
||||||
.clip(shape = CircleShape)
|
}
|
||||||
.border(3.dp, MaterialTheme.colors.background, CircleShape)
|
Row(horizontalArrangement = Arrangement.Center, modifier = Modifier.fillMaxWidth()) {
|
||||||
.background(MaterialTheme.colors.background)
|
Text(
|
||||||
)
|
user.bestDisplayName() ?: "",
|
||||||
}
|
modifier = Modifier.padding(top = 7.dp),
|
||||||
Row(horizontalArrangement = Arrangement.Center, modifier = Modifier.fillMaxWidth()) {
|
fontWeight = FontWeight.Bold,
|
||||||
Text(
|
fontSize = 18.sp
|
||||||
user.bestDisplayName() ?: "",
|
)
|
||||||
modifier = Modifier.padding(top = 7.dp),
|
}
|
||||||
fontWeight = FontWeight.Bold,
|
Row(horizontalArrangement = Arrangement.Center, modifier = Modifier.fillMaxWidth()) {
|
||||||
fontSize = 18.sp
|
Text(" @${user.bestUsername()}", color = Color.LightGray)
|
||||||
)
|
}
|
||||||
}
|
|
||||||
Row(horizontalArrangement = Arrangement.Center, modifier = Modifier.fillMaxWidth()) {
|
Row(
|
||||||
Text(" @${user.bestUsername()}", color = Color.LightGray)
|
horizontalArrangement = Arrangement.Center,
|
||||||
}
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
Row(
|
.padding(horizontal = 35.dp, vertical = 10.dp)
|
||||||
horizontalArrangement = Arrangement.Center,
|
) {
|
||||||
modifier = Modifier
|
QrCodeDrawer("nostr:${user.pubkeyNpub()}")
|
||||||
.fillMaxWidth()
|
}
|
||||||
.padding(horizontal = 35.dp, vertical = 10.dp)
|
}
|
||||||
) {
|
|
||||||
QrCodeDrawer("nostr:${user.pubkeyNpub()}")
|
Row(
|
||||||
}
|
horizontalArrangement = Arrangement.Center,
|
||||||
}
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
Row(
|
.padding(horizontal = 30.dp, vertical = 10.dp)
|
||||||
horizontalArrangement = Arrangement.Center,
|
) {
|
||||||
modifier = Modifier
|
Button(
|
||||||
.fillMaxWidth()
|
onClick = { presenting = false },
|
||||||
.padding(horizontal = 30.dp, vertical = 10.dp)
|
shape = RoundedCornerShape(35.dp),
|
||||||
) {
|
modifier = Modifier
|
||||||
Button(
|
.fillMaxWidth()
|
||||||
onClick = { presenting = false },
|
.height(50.dp),
|
||||||
shape = RoundedCornerShape(35.dp),
|
colors = ButtonDefaults
|
||||||
modifier = Modifier
|
.buttonColors(
|
||||||
.fillMaxWidth()
|
backgroundColor = MaterialTheme.colors.primary
|
||||||
.height(50.dp),
|
)
|
||||||
colors = ButtonDefaults
|
) {
|
||||||
.buttonColors(
|
Text(text = stringResource(R.string.scan_qr))
|
||||||
backgroundColor = MaterialTheme.colors.primary
|
}
|
||||||
)
|
}
|
||||||
) {
|
} else {
|
||||||
Text(text = stringResource(R.string.scan_qr))
|
QrCodeScanner {
|
||||||
}
|
if (it.isNullOrEmpty()) {
|
||||||
}
|
presenting = true
|
||||||
} else {
|
} else {
|
||||||
QrCodeScanner {
|
onScan(it)
|
||||||
if (it.isNullOrEmpty()) {
|
}
|
||||||
presenting = true
|
}
|
||||||
} else {
|
}
|
||||||
onScan(it)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@@ -43,7 +43,6 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.painter.BitmapPainter
|
|
||||||
import androidx.compose.ui.platform.LocalClipboardManager
|
import androidx.compose.ui.platform.LocalClipboardManager
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||||
@@ -61,14 +60,13 @@ import androidx.lifecycle.LifecycleEventObserver
|
|||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.RoboHashCache
|
|
||||||
import com.vitorpamplona.amethyst.model.Account
|
import com.vitorpamplona.amethyst.model.Account
|
||||||
import com.vitorpamplona.amethyst.model.Channel
|
import com.vitorpamplona.amethyst.model.Channel
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.service.NostrChannelDataSource
|
import com.vitorpamplona.amethyst.service.NostrChannelDataSource
|
||||||
import com.vitorpamplona.amethyst.ui.actions.NewChannelView
|
import com.vitorpamplona.amethyst.ui.actions.NewChannelView
|
||||||
import com.vitorpamplona.amethyst.ui.actions.PostButton
|
import com.vitorpamplona.amethyst.ui.actions.PostButton
|
||||||
import com.vitorpamplona.amethyst.ui.components.AsyncImageProxy
|
import com.vitorpamplona.amethyst.ui.components.AsyncUserImageProxy
|
||||||
import com.vitorpamplona.amethyst.ui.components.ResizeImage
|
import com.vitorpamplona.amethyst.ui.components.ResizeImage
|
||||||
import com.vitorpamplona.amethyst.ui.dal.ChannelFeedFilter
|
import com.vitorpamplona.amethyst.ui.dal.ChannelFeedFilter
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.Route
|
import com.vitorpamplona.amethyst.ui.navigation.Route
|
||||||
@@ -228,11 +226,9 @@ fun ChannelHeader(baseChannel: Channel, account: Account, navController: NavCont
|
|||||||
Column() {
|
Column() {
|
||||||
Column(modifier = Modifier.padding(12.dp)) {
|
Column(modifier = Modifier.padding(12.dp)) {
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
AsyncImageProxy(
|
AsyncUserImageProxy(
|
||||||
|
pubkeyHex = channel.idHex,
|
||||||
model = ResizeImage(channel.profilePicture(), 35.dp),
|
model = ResizeImage(channel.profilePicture(), 35.dp),
|
||||||
placeholder = BitmapPainter(RoboHashCache.get(context, channel.idHex)),
|
|
||||||
fallback = BitmapPainter(RoboHashCache.get(context, channel.idHex)),
|
|
||||||
error = BitmapPainter(RoboHashCache.get(context, channel.idHex)),
|
|
||||||
contentDescription = context.getString(R.string.profile_image),
|
contentDescription = context.getString(R.string.profile_image),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(35.dp)
|
.width(35.dp)
|
||||||
|
@@ -1,245 +1,244 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn
|
||||||
|
|
||||||
import androidx.compose.animation.animateContentSize
|
import androidx.compose.animation.animateContentSize
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxHeight
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.material.Divider
|
import androidx.compose.material.Divider
|
||||||
import androidx.compose.material.Icon
|
import androidx.compose.material.Icon
|
||||||
import androidx.compose.material.IconButton
|
import androidx.compose.material.IconButton
|
||||||
import androidx.compose.material.LocalTextStyle
|
import androidx.compose.material.LocalTextStyle
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.material.TextField
|
import androidx.compose.material.TextField
|
||||||
import androidx.compose.material.TextFieldDefaults
|
import androidx.compose.material.TextFieldDefaults
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Cancel
|
import androidx.compose.material.icons.filled.Cancel
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.DisposableEffect
|
import androidx.compose.runtime.DisposableEffect
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
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.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.painter.BitmapPainter
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.text.input.KeyboardCapitalization
|
||||||
import androidx.compose.ui.text.input.KeyboardCapitalization
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.text.style.TextDirection
|
||||||
import androidx.compose.ui.text.style.TextDirection
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.LifecycleEventObserver
|
||||||
import androidx.lifecycle.LifecycleEventObserver
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.navigation.NavController
|
||||||
import androidx.navigation.NavController
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.RoboHashCache
|
import com.vitorpamplona.amethyst.model.User
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.service.NostrChatroomDataSource
|
||||||
import com.vitorpamplona.amethyst.model.User
|
import com.vitorpamplona.amethyst.ui.actions.PostButton
|
||||||
import com.vitorpamplona.amethyst.service.NostrChatroomDataSource
|
import com.vitorpamplona.amethyst.ui.components.AsyncUserImageProxy
|
||||||
import com.vitorpamplona.amethyst.ui.actions.PostButton
|
import com.vitorpamplona.amethyst.ui.components.ObserveDisplayNip05Status
|
||||||
import com.vitorpamplona.amethyst.ui.components.AsyncImageProxy
|
import com.vitorpamplona.amethyst.ui.components.ResizeImage
|
||||||
import com.vitorpamplona.amethyst.ui.components.ObserveDisplayNip05Status
|
import com.vitorpamplona.amethyst.ui.dal.ChatroomFeedFilter
|
||||||
import com.vitorpamplona.amethyst.ui.components.ResizeImage
|
import com.vitorpamplona.amethyst.ui.note.ChatroomMessageCompose
|
||||||
import com.vitorpamplona.amethyst.ui.dal.ChatroomFeedFilter
|
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
|
||||||
import com.vitorpamplona.amethyst.ui.note.ChatroomMessageCompose
|
import com.vitorpamplona.amethyst.ui.screen.ChatroomFeedView
|
||||||
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
|
import com.vitorpamplona.amethyst.ui.screen.NostrChatRoomFeedViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.ChatroomFeedView
|
|
||||||
import com.vitorpamplona.amethyst.ui.screen.NostrChatRoomFeedViewModel
|
@Composable
|
||||||
|
fun ChatroomScreen(userId: String?, accountViewModel: AccountViewModel, navController: NavController) {
|
||||||
@Composable
|
val accountState by accountViewModel.accountLiveData.observeAsState()
|
||||||
fun ChatroomScreen(userId: String?, accountViewModel: AccountViewModel, navController: NavController) {
|
val account = accountState?.account
|
||||||
val accountState by accountViewModel.accountLiveData.observeAsState()
|
|
||||||
val account = accountState?.account
|
if (account != null && userId != null) {
|
||||||
|
val newPost = remember { mutableStateOf(TextFieldValue("")) }
|
||||||
if (account != null && userId != null) {
|
val replyTo = remember { mutableStateOf<Note?>(null) }
|
||||||
val newPost = remember { mutableStateOf(TextFieldValue("")) }
|
|
||||||
val replyTo = remember { mutableStateOf<Note?>(null) }
|
ChatroomFeedFilter.loadMessagesBetween(account, userId)
|
||||||
|
NostrChatroomDataSource.loadMessagesBetween(account, userId)
|
||||||
ChatroomFeedFilter.loadMessagesBetween(account, userId)
|
|
||||||
NostrChatroomDataSource.loadMessagesBetween(account, userId)
|
val feedViewModel: NostrChatRoomFeedViewModel = viewModel()
|
||||||
|
val lifeCycleOwner = LocalLifecycleOwner.current
|
||||||
val feedViewModel: NostrChatRoomFeedViewModel = viewModel()
|
|
||||||
val lifeCycleOwner = LocalLifecycleOwner.current
|
LaunchedEffect(userId) {
|
||||||
|
feedViewModel.refresh()
|
||||||
LaunchedEffect(userId) {
|
}
|
||||||
feedViewModel.refresh()
|
|
||||||
}
|
DisposableEffect(userId) {
|
||||||
|
val observer = LifecycleEventObserver { source, event ->
|
||||||
DisposableEffect(userId) {
|
if (event == Lifecycle.Event.ON_RESUME) {
|
||||||
val observer = LifecycleEventObserver { source, event ->
|
println("Private Message Start")
|
||||||
if (event == Lifecycle.Event.ON_RESUME) {
|
NostrChatroomDataSource.start()
|
||||||
println("Private Message Start")
|
feedViewModel.refresh()
|
||||||
NostrChatroomDataSource.start()
|
}
|
||||||
feedViewModel.refresh()
|
if (event == Lifecycle.Event.ON_PAUSE) {
|
||||||
}
|
println("Private Message Stop")
|
||||||
if (event == Lifecycle.Event.ON_PAUSE) {
|
NostrChatroomDataSource.stop()
|
||||||
println("Private Message Stop")
|
}
|
||||||
NostrChatroomDataSource.stop()
|
}
|
||||||
}
|
|
||||||
}
|
lifeCycleOwner.lifecycle.addObserver(observer)
|
||||||
|
onDispose {
|
||||||
lifeCycleOwner.lifecycle.addObserver(observer)
|
lifeCycleOwner.lifecycle.removeObserver(observer)
|
||||||
onDispose {
|
}
|
||||||
lifeCycleOwner.lifecycle.removeObserver(observer)
|
}
|
||||||
}
|
|
||||||
}
|
Column(Modifier.fillMaxHeight()) {
|
||||||
|
NostrChatroomDataSource.withUser?.let {
|
||||||
Column(Modifier.fillMaxHeight()) {
|
ChatroomHeader(
|
||||||
NostrChatroomDataSource.withUser?.let {
|
it,
|
||||||
ChatroomHeader(
|
accountViewModel = accountViewModel,
|
||||||
it,
|
navController = navController
|
||||||
accountViewModel = accountViewModel,
|
)
|
||||||
navController = navController
|
}
|
||||||
)
|
|
||||||
}
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
Column(
|
.fillMaxHeight()
|
||||||
modifier = Modifier
|
.padding(vertical = 0.dp)
|
||||||
.fillMaxHeight()
|
.weight(1f, true)
|
||||||
.padding(vertical = 0.dp)
|
) {
|
||||||
.weight(1f, true)
|
ChatroomFeedView(feedViewModel, accountViewModel, navController, "Room/$userId") {
|
||||||
) {
|
replyTo.value = it
|
||||||
ChatroomFeedView(feedViewModel, accountViewModel, navController, "Room/$userId") {
|
}
|
||||||
replyTo.value = it
|
}
|
||||||
}
|
|
||||||
}
|
Spacer(modifier = Modifier.height(10.dp))
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(10.dp))
|
Row(Modifier.padding(horizontal = 10.dp).animateContentSize(), verticalAlignment = Alignment.CenterVertically) {
|
||||||
|
val replyingNote = replyTo.value
|
||||||
Row(Modifier.padding(horizontal = 10.dp).animateContentSize(), verticalAlignment = Alignment.CenterVertically) {
|
if (replyingNote != null) {
|
||||||
val replyingNote = replyTo.value
|
Column(Modifier.weight(1f)) {
|
||||||
if (replyingNote != null) {
|
ChatroomMessageCompose(
|
||||||
Column(Modifier.weight(1f)) {
|
baseNote = replyingNote,
|
||||||
ChatroomMessageCompose(
|
null,
|
||||||
baseNote = replyingNote,
|
innerQuote = true,
|
||||||
null,
|
accountViewModel = accountViewModel,
|
||||||
innerQuote = true,
|
navController = navController,
|
||||||
accountViewModel = accountViewModel,
|
onWantsToReply = {
|
||||||
navController = navController,
|
replyTo.value = it
|
||||||
onWantsToReply = {
|
}
|
||||||
replyTo.value = it
|
)
|
||||||
}
|
}
|
||||||
)
|
|
||||||
}
|
Column(Modifier.padding(end = 10.dp)) {
|
||||||
|
IconButton(
|
||||||
Column(Modifier.padding(end = 10.dp)) {
|
modifier = Modifier.size(30.dp),
|
||||||
IconButton(
|
onClick = { replyTo.value = null }
|
||||||
modifier = Modifier.size(30.dp),
|
) {
|
||||||
onClick = { replyTo.value = null }
|
Icon(
|
||||||
) {
|
imageVector = Icons.Default.Cancel,
|
||||||
Icon(
|
null,
|
||||||
imageVector = Icons.Default.Cancel,
|
modifier = Modifier.padding(end = 5.dp).size(30.dp),
|
||||||
null,
|
tint = MaterialTheme.colors.onSurface.copy(alpha = 0.32f)
|
||||||
modifier = Modifier.padding(end = 5.dp).size(30.dp),
|
)
|
||||||
tint = MaterialTheme.colors.onSurface.copy(alpha = 0.32f)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
// LAST ROW
|
||||||
|
Row(
|
||||||
// LAST ROW
|
modifier = Modifier.padding(start = 10.dp, end = 10.dp, bottom = 10.dp, top = 5.dp)
|
||||||
Row(
|
.fillMaxWidth(),
|
||||||
modifier = Modifier.padding(start = 10.dp, end = 10.dp, bottom = 10.dp, top = 5.dp)
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
.fillMaxWidth(),
|
verticalAlignment = Alignment.CenterVertically
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
) {
|
||||||
verticalAlignment = Alignment.CenterVertically
|
TextField(
|
||||||
) {
|
value = newPost.value,
|
||||||
TextField(
|
onValueChange = { newPost.value = it },
|
||||||
value = newPost.value,
|
keyboardOptions = KeyboardOptions.Default.copy(
|
||||||
onValueChange = { newPost.value = it },
|
capitalization = KeyboardCapitalization.Sentences
|
||||||
keyboardOptions = KeyboardOptions.Default.copy(
|
),
|
||||||
capitalization = KeyboardCapitalization.Sentences
|
modifier = Modifier.weight(1f, true),
|
||||||
),
|
shape = RoundedCornerShape(25.dp),
|
||||||
modifier = Modifier.weight(1f, true),
|
placeholder = {
|
||||||
shape = RoundedCornerShape(25.dp),
|
Text(
|
||||||
placeholder = {
|
text = stringResource(id = R.string.reply_here),
|
||||||
Text(
|
color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f)
|
||||||
text = stringResource(id = R.string.reply_here),
|
)
|
||||||
color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f)
|
},
|
||||||
)
|
textStyle = LocalTextStyle.current.copy(textDirection = TextDirection.Content),
|
||||||
},
|
trailingIcon = {
|
||||||
textStyle = LocalTextStyle.current.copy(textDirection = TextDirection.Content),
|
PostButton(
|
||||||
trailingIcon = {
|
onPost = {
|
||||||
PostButton(
|
account.sendPrivateMeesage(newPost.value.text, userId, replyTo.value)
|
||||||
onPost = {
|
newPost.value = TextFieldValue("")
|
||||||
account.sendPrivateMeesage(newPost.value.text, userId, replyTo.value)
|
replyTo.value = null
|
||||||
newPost.value = TextFieldValue("")
|
feedViewModel.refresh() // Don't wait a full second before updating
|
||||||
replyTo.value = null
|
},
|
||||||
feedViewModel.refresh() // Don't wait a full second before updating
|
newPost.value.text.isNotBlank(),
|
||||||
},
|
modifier = Modifier.padding(end = 10.dp)
|
||||||
newPost.value.text.isNotBlank(),
|
)
|
||||||
modifier = Modifier.padding(end = 10.dp)
|
},
|
||||||
)
|
colors = TextFieldDefaults.textFieldColors(
|
||||||
},
|
focusedIndicatorColor = Color.Transparent,
|
||||||
colors = TextFieldDefaults.textFieldColors(
|
unfocusedIndicatorColor = Color.Transparent
|
||||||
focusedIndicatorColor = Color.Transparent,
|
)
|
||||||
unfocusedIndicatorColor = Color.Transparent
|
)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
@Composable
|
||||||
|
fun ChatroomHeader(baseUser: User, accountViewModel: AccountViewModel, navController: NavController) {
|
||||||
@Composable
|
val ctx = LocalContext.current.applicationContext
|
||||||
fun ChatroomHeader(baseUser: User, accountViewModel: AccountViewModel, navController: NavController) {
|
|
||||||
val ctx = LocalContext.current.applicationContext
|
Column(
|
||||||
|
modifier = Modifier.clickable(
|
||||||
Column(
|
onClick = { navController.navigate("User/${baseUser.pubkeyHex}") }
|
||||||
modifier = Modifier.clickable(
|
)
|
||||||
onClick = { navController.navigate("User/${baseUser.pubkeyHex}") }
|
) {
|
||||||
)
|
Column(modifier = Modifier.padding(12.dp)) {
|
||||||
) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
Column(modifier = Modifier.padding(12.dp)) {
|
val authorState by baseUser.live().metadata.observeAsState()
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
val author = authorState?.user!!
|
||||||
val authorState by baseUser.live().metadata.observeAsState()
|
|
||||||
val author = authorState?.user!!
|
AsyncUserImageProxy(
|
||||||
|
pubkeyHex = author.pubkeyHex,
|
||||||
AsyncImageProxy(
|
model = ResizeImage(author.profilePicture(), 35.dp),
|
||||||
model = ResizeImage(author.profilePicture(), 35.dp),
|
// placeholder = BitmapPainter(RoboHashCache.get(ctx, author.pubkeyHex)),
|
||||||
placeholder = BitmapPainter(RoboHashCache.get(ctx, author.pubkeyHex)),
|
// fallback = BitmapPainter(RoboHashCache.get(ctx, author.pubkeyHex)),
|
||||||
fallback = BitmapPainter(RoboHashCache.get(ctx, author.pubkeyHex)),
|
// error = BitmapPainter(RoboHashCache.get(ctx, author.pubkeyHex)),
|
||||||
error = BitmapPainter(RoboHashCache.get(ctx, author.pubkeyHex)),
|
contentDescription = stringResource(id = R.string.profile_image),
|
||||||
contentDescription = stringResource(id = R.string.profile_image),
|
modifier = Modifier
|
||||||
modifier = Modifier
|
.width(35.dp)
|
||||||
.width(35.dp)
|
.height(35.dp)
|
||||||
.height(35.dp)
|
.clip(shape = CircleShape)
|
||||||
.clip(shape = CircleShape)
|
)
|
||||||
)
|
|
||||||
|
Column(modifier = Modifier.padding(start = 10.dp)) {
|
||||||
Column(modifier = Modifier.padding(start = 10.dp)) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
UsernameDisplay(baseUser)
|
||||||
UsernameDisplay(baseUser)
|
}
|
||||||
}
|
|
||||||
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
ObserveDisplayNip05Status(baseUser)
|
||||||
ObserveDisplayNip05Status(baseUser)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
Divider(
|
||||||
Divider(
|
modifier = Modifier.padding(start = 12.dp, end = 12.dp),
|
||||||
modifier = Modifier.padding(start = 12.dp, end = 12.dp),
|
thickness = 0.25.dp
|
||||||
thickness = 0.25.dp
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user