refactor(sonar): merge chained if-else into when

Sonar — convert 'if (A) {…} else if (B) {…} else {…}' chains into
'when { A -> …; B -> …; else -> … }' across 33 files (~44 sites).
The change is mechanically equivalent: same conditions, same branch
order, same short-circuit evaluation, no public-signature impact.

The 70-branch event-type dispatch in ThreadFeedView.kt:594 is intentionally
left as if-else for now — the conversion would balloon to a 280-line diff
with no behavioural change, making review impractical.
This commit is contained in:
davotoula
2026-05-13 10:40:38 +02:00
parent 5e179326d4
commit 8ed7e63427
33 changed files with 1399 additions and 1104 deletions
@@ -2859,14 +2859,11 @@ class Account(
if (event == null) return null
return if (isWriteable()) {
if (event is PrivateDmEvent) {
privateDMDecryptionCache.cachedDM(event)
} else if (event is LnZapRequestEvent && event.isPrivateZap()) {
privateZapsDecryptionCache.cachedPrivateZap(event)?.content
} else if (event is DraftWrapEvent) {
draftsDecryptionCache.preCachedDraft(event)?.content
} else {
event.content
when {
event is PrivateDmEvent -> privateDMDecryptionCache.cachedDM(event)
event is LnZapRequestEvent && event.isPrivateZap() -> privateZapsDecryptionCache.cachedPrivateZap(event)?.content
event is DraftWrapEvent -> draftsDecryptionCache.preCachedDraft(event)?.content
else -> event.content
}
} else {
event.content
@@ -2875,9 +2872,12 @@ class Account(
suspend fun decryptContent(note: Note): String? {
val event = note.event
return if (event is PrivateDmEvent && isWriteable()) {
return when {
event is PrivateDmEvent && isWriteable() -> {
privateDMDecryptionCache.decryptDM(event)
} else if (event is LnZapRequestEvent && isWriteable()) {
}
event is LnZapRequestEvent && isWriteable() -> {
if (event.isPrivateZap()) {
if (isWriteable()) {
privateZapsDecryptionCache.decryptPrivateZap(event)?.content
@@ -2887,12 +2887,17 @@ class Account(
} else {
event.content
}
} else if (event is DraftWrapEvent && isWriteable()) {
}
event is DraftWrapEvent && isWriteable() -> {
draftsDecryptionCache.cachedDraft(event)?.content
} else {
}
else -> {
event?.content
}
}
}
suspend fun decryptZapOrNull(event: LnZapRequestEvent): LnZapPrivateEvent? = if (event.isPrivateZap() && isWriteable()) privateZapsDecryptionCache.decryptPrivateZap(event) else null
@@ -88,7 +88,8 @@ class ZapPaymentHandler(
val zapSplitSetup = noteEvent?.zapSplitSetup()
val unverifiedZapsToSend =
if (!zapSplitSetup.isNullOrEmpty()) {
when {
!zapSplitSetup.isNullOrEmpty() -> {
zapSplitSetup.map { setup ->
when (setup) {
is ZapSplitSetupLnAddress -> {
@@ -109,13 +110,17 @@ class ZapPaymentHandler(
}
}
}
} else if (noteEvent is LiveActivitiesEvent && noteEvent.hasHost()) {
}
noteEvent is LiveActivitiesEvent && noteEvent.hasHost() -> {
noteEvent.hosts().map {
val user = LocalCache.checkGetOrCreateUser(it.pubKey)
val lnAddress = user?.lnAddress()
UnverifiedZapSplitSetup(lnAddress, relay = it.relayHint, user = user)
}
} else if (noteEvent is AppDefinitionEvent) {
}
noteEvent is AppDefinitionEvent -> {
val appLud16 = noteEvent.appMetaData()?.lnAddress()
if (appLud16 != null) {
listOf(UnverifiedZapSplitSetup(appLud16))
@@ -124,13 +129,16 @@ class ZapPaymentHandler(
note.author?.lnAddress()
listOf(UnverifiedZapSplitSetup(lud16))
}
} else {
}
else -> {
listOf(
UnverifiedZapSplitSetup(
note.author?.lnAddress(),
),
)
}
}
if (showErrorIfNoLnAddress) {
val errors = unverifiedZapsToSend.filter { it.lnAddress.isNullOrBlank() }
@@ -63,19 +63,29 @@ class UrlPreview {
val mimeType =
response.headers["Content-Type"]?.toMediaType()
?: throw IllegalArgumentException("Website returned unknown mimetype: ${response.headers["Content-Type"]}")
if (mimeType.type == "text" && mimeType.subtype == "html") {
when {
mimeType.type == "text" && mimeType.subtype == "html" -> {
val metaTags = HtmlParser().parseHtml(response.body.source(), mimeType.charset())
val data = OpenGraphParser().extractUrlInfo(metaTags)
UrlInfoItem(url, data.title, data.description, data.image, mimeType.toString())
} else if (mimeType.type == "image") {
}
mimeType.type == "image" -> {
UrlInfoItem(url, image = url, mimeType = mimeType.toString())
} else if (mimeType.type == "video") {
}
mimeType.type == "video" -> {
UrlInfoItem(url, image = url, mimeType = mimeType.toString())
} else if (mimeType.type == "application" && mimeType.subtype == "pdf") {
}
mimeType.type == "application" && mimeType.subtype == "pdf" -> {
UrlInfoItem(url, image = url, mimeType = mimeType.toString())
} else {
}
else -> {
throw IllegalArgumentException("Website returned unknown encoding for previews: $mimeType")
}
}
} else {
throw IllegalArgumentException("Website returned: " + response.code)
}
@@ -70,9 +70,12 @@ class RelayProxyClientConnector(
RelayServiceInfra(torSettings, torConnection, clearConnection, connectivity, torStatus)
}.debounce(100)
.onEach {
if (it.connectivity is ConnectivityStatus.StartingService) {
when {
it.connectivity is ConnectivityStatus.StartingService -> {
// ignore
} else if (it.connectivity is ConnectivityStatus.Off) {
}
it.connectivity is ConnectivityStatus.Off -> {
Log.d("ManageRelayServices") { "Connectivity Off: Pausing Relay Services ${it.connectivity}" }
if (client.isActive()) {
client.disconnect()
@@ -80,7 +83,9 @@ class RelayProxyClientConnector(
if (it.torStatus is TorServiceStatus.Active) {
Log.d("ManageRelayServices", "Connectivity off, Tor idle")
}
} else if (it.connectivity is ConnectivityStatus.Active && !client.isActive()) {
}
it.connectivity is ConnectivityStatus.Active && !client.isActive() -> {
Log.d("ManageRelayServices", "Connectivity On: Resuming Relay Services")
if (it.torStatus is TorServiceStatus.Active) {
@@ -89,13 +94,16 @@ class RelayProxyClientConnector(
// only calls this if the client is not active. Otherwise goes to the else below
client.connect()
} else {
}
else -> {
Log.d("ManageRelayServices", "Relay Services have changed, reconnecting relays that need to")
client.reconnect(
onlyIfChanged = true,
ignoreRetryDelays = true,
)
}
}
}.onStart {
Log.d("ManageRelayServices", "Resuming Relay Services")
client.connect()
@@ -136,14 +136,11 @@ class BlossomServerResolver(
url: String,
mimeType: String?,
): OkHttpClient =
if (mimeType == null) {
httpClientBuilder.okHttpClientForPreview(url)
} else if (mimeType.startsWith("audio/") || mimeType.startsWith("video/")) {
httpClientBuilder.okHttpClientForVideo(url)
} else if (mimeType.startsWith("image/")) {
httpClientBuilder.okHttpClientForImage(url)
} else {
httpClientBuilder.okHttpClientForPreview(url)
when {
mimeType == null -> httpClientBuilder.okHttpClientForPreview(url)
mimeType.startsWith("audio/") || mimeType.startsWith("video/") -> httpClientBuilder.okHttpClientForVideo(url)
mimeType.startsWith("image/") -> httpClientBuilder.okHttpClientForImage(url)
else -> httpClientBuilder.okHttpClientForPreview(url)
}
fun canResolve(scheme: String) = scheme == SCHEME
@@ -212,7 +212,8 @@ fun EditPostView(
if (myUrlPreview != null) {
Row(modifier = Modifier.padding(vertical = Size5dp, horizontal = Size10dp)) {
if (RichTextParser.isValidURL(myUrlPreview)) {
if (RichTextParser.isImageUrl(myUrlPreview)) {
when {
RichTextParser.isImageUrl(myUrlPreview) -> {
AsyncImage(
model = myUrlPreview,
contentDescription = myUrlPreview,
@@ -228,7 +229,9 @@ fun EditPostView(
QuoteBorder,
),
)
} else if (RichTextParser.isVideoUrl(myUrlPreview)) {
}
RichTextParser.isVideoUrl(myUrlPreview) -> {
VideoView(
myUrlPreview,
mimeType = null,
@@ -236,9 +239,12 @@ fun EditPostView(
contentScale = ContentScale.FillWidth,
accountViewModel = accountViewModel,
)
} else {
}
else -> {
LoadUrlPreview(myUrlPreview, myUrlPreview, null, accountViewModel)
}
}
} else if (RichTextParser.startsWithNIP19Scheme(myUrlPreview)) {
val bgColor = MaterialTheme.colorScheme.background
val backgroundColor = remember { mutableStateOf(bgColor) }
@@ -188,7 +188,8 @@ class NewMessageTagger(
key = key.removePrefix("@")
try {
if (key.startsWith("nsec1", true)) {
when {
key.startsWith("nsec1", true) -> {
if (key.length < 63) {
return null
}
@@ -200,7 +201,9 @@ class NewMessageTagger(
Nip19Parser.uriToRoute(Nip01Crypto.pubKeyCreate(keyB32.bechToBytes()).toNpub()) ?: return null
return DirtyKeyInfo(pubkey, restOfWord.ifEmpty { null })
} else if (key.startsWith("npub1", true)) {
}
key.startsWith("npub1", true) -> {
if (key.length < 63) {
return null
}
@@ -211,7 +214,9 @@ class NewMessageTagger(
val pubkey = Nip19Parser.uriToRoute(keyB32) ?: return null
return DirtyKeyInfo(pubkey, restOfWord.ifEmpty { null })
} else if (key.startsWith("note1", true)) {
}
key.startsWith("note1", true) -> {
if (key.length < 63) {
return null
}
@@ -222,15 +227,21 @@ class NewMessageTagger(
val noteId = Nip19Parser.uriToRoute(keyB32) ?: return null
return DirtyKeyInfo(noteId, restOfWord.ifEmpty { null })
} else if (key.startsWith("nprofile", true)) {
}
key.startsWith("nprofile", true) -> {
val pubkeyRelay = Nip19Parser.uriToRoute(key) ?: return null
return DirtyKeyInfo(pubkeyRelay, pubkeyRelay.additionalChars)
} else if (key.startsWith("nevent1", true)) {
}
key.startsWith("nevent1", true) -> {
val noteRelayId = Nip19Parser.uriToRoute(key) ?: return null
return DirtyKeyInfo(noteRelayId, noteRelayId.additionalChars)
} else if (key.startsWith("naddr1", true)) {
}
key.startsWith("naddr1", true) -> {
val address = Nip19Parser.uriToRoute(key) ?: return null
return DirtyKeyInfo(
@@ -238,6 +249,7 @@ class NewMessageTagger(
address.additionalChars,
) // no way to know when they address ends and dirt begins
}
}
} catch (e: Exception) {
if (e is CancellationException) throw e
e.printStackTrace()
@@ -113,7 +113,8 @@ fun ShowImageGallery(
media: SelectedMedia,
accountViewModel: AccountViewModel,
) {
if (media.isImage() == true) {
when {
media.isImage() == true -> {
AsyncImage(
model = media.uri.toString(),
contentDescription = media.uri.toString(),
@@ -123,17 +124,23 @@ fun ShowImageGallery(
.fillMaxWidth()
.windowInsetsPadding(WindowInsets(0.dp, 0.dp, 0.dp, 0.dp)),
)
} else if (media.isAudio() == true) {
}
media.isAudio() == true -> {
FilePreviewPlaceholder(
icon = MaterialSymbols.AudioFile,
label = media.mimeType ?: "audio/*",
)
} else if (media.isDocument()) {
}
media.isDocument() -> {
FilePreviewPlaceholder(
icon = MaterialSymbols.PictureAsPdf,
label = media.mimeType ?: "application/pdf",
)
} else if (media.isVideo() == true && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
}
media.isVideo() == true && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> {
var bitmap by remember { mutableStateOf<Bitmap?>(null) }
val context = LocalContext.current
@@ -166,7 +173,9 @@ fun ShowImageGallery(
accountViewModel = accountViewModel,
)
}
} else {
}
else -> {
VideoView(
videoUri = media.uri.toString(),
mimeType = media.mimeType,
@@ -176,6 +185,7 @@ fun ShowImageGallery(
)
}
}
}
@Composable
fun ShowImageUploadItem(
@@ -95,7 +95,8 @@ fun RenderLoaded(
callbackUri: String? = null,
accountViewModel: AccountViewModel,
) {
if (state.previewInfo.mimeType.startsWith("image")) {
when {
state.previewInfo.mimeType.startsWith("image") -> {
Box(modifier = HalfVertPadding) {
ZoomableContentView(
content = MediaUrlImage(url, uri = callbackUri),
@@ -104,7 +105,9 @@ fun RenderLoaded(
accountViewModel = accountViewModel,
)
}
} else if (state.previewInfo.mimeType.startsWith("video")) {
}
state.previewInfo.mimeType.startsWith("video") -> {
Box(modifier = HalfVertPadding) {
ZoomableContentView(
content = MediaUrlVideo(url, uri = callbackUri),
@@ -113,7 +116,9 @@ fun RenderLoaded(
accountViewModel = accountViewModel,
)
}
} else if (state.previewInfo.mimeType.startsWith("application/pdf")) {
}
state.previewInfo.mimeType.startsWith("application/pdf") -> {
Box(modifier = HalfVertPadding) {
ZoomableContentView(
content = MediaUrlPdf(url, uri = callbackUri, mimeType = state.previewInfo.mimeType),
@@ -122,7 +127,10 @@ fun RenderLoaded(
accountViewModel = accountViewModel,
)
}
} else {
}
else -> {
UrlPreviewCard(url, state.previewInfo)
}
}
}
@@ -293,17 +293,22 @@ private fun handleZapClick(
val choices = zapAmountChoices ?: accountViewModel.zapAmountChoices()
if (choices.isEmpty()) {
when {
choices.isEmpty() -> {
accountViewModel.toastManager.toast(
stringRes(context, R.string.error_dialog_zap_error),
stringRes(context, R.string.no_zap_amount_setup_long_press_to_change),
)
} else if (!accountViewModel.isWriteable()) {
}
!accountViewModel.isWriteable() -> {
accountViewModel.toastManager.toast(
stringRes(context, R.string.error_dialog_zap_error),
stringRes(context, R.string.login_with_a_private_key_to_be_able_to_send_zaps),
)
} else if (choices.size == 1) {
}
choices.size == 1 -> {
val amount = choices.first()
if (amount > 1100 || zapAmountChoices != null) {
@@ -322,7 +327,9 @@ private fun handleZapClick(
} else {
onMultipleChoices(listOf(1000L, 5_000L, 10_000L))
}
} else {
}
else -> {
if (choices.any { it > 1100 } || zapAmountChoices != null) {
onMultipleChoices(choices)
} else {
@@ -330,3 +337,4 @@ private fun handleZapClick(
}
}
}
}
@@ -67,9 +67,12 @@ fun WatchBlockAndReport(
mutableStateOf(false)
}
if (showAnyway.value) {
when {
showAnyway.value -> {
normalNote(true)
} else if (!isHidden.isPostHidden) {
}
!isHidden.isPostHidden -> {
if (isHidden.isAcceptable) {
normalNote(isHidden.canPreview)
} else {
@@ -82,10 +85,13 @@ fun WatchBlockAndReport(
onClick = { showAnyway.value = true },
)
}
} else if (showHiddenWarning) {
}
showHiddenWarning -> {
// if it is a quoted or boosted note, how the hidden warning.
HiddenNoteByMe {
showAnyway.value = true
}
}
}
}
@@ -293,7 +293,8 @@ fun DisplayStatusInner(
)
}
if (url != null) {
when {
url != null -> {
val uri = LocalUriHandler.current
Spacer(modifier = StdHorzSpacer)
IconButton(
@@ -307,7 +308,9 @@ fun DisplayStatusInner(
tint = MaterialTheme.colorScheme.lessImportantLink,
)
}
} else if (nostrATag != null) {
}
nostrATag != null -> {
LoadAddressableNote(nostrATag, accountViewModel) { note ->
if (note != null) {
Spacer(modifier = StdHorzSpacer)
@@ -329,7 +332,9 @@ fun DisplayStatusInner(
}
}
}
} else if (nostrETag != null) {
}
nostrETag != null -> {
LoadNote(baseNoteHex = nostrETag.eventId, accountViewModel) {
if (it != null) {
Spacer(modifier = StdHorzSpacer)
@@ -351,7 +356,9 @@ fun DisplayStatusInner(
}
}
}
} else if (nostrPTag != null) {
}
nostrPTag != null -> {
LoadUser(baseUserHex = nostrPTag, accountViewModel) { user ->
if (user != null) {
Spacer(modifier = StdHorzSpacer)
@@ -370,6 +377,7 @@ fun DisplayStatusInner(
}
}
}
}
@Composable
fun ObserveAndDisplayNIP05(
@@ -116,14 +116,11 @@ val graspLink = { graspNumber: String ->
val externalLinkForNote = { note: Note ->
if (note is AddressableNote) {
if (note.event?.bountyBaseReward() != null) {
"https://nostrbounties.com/b/${note.toNAddr()}"
} else if (note.event is PeopleListEvent) {
"https://listr.lol/a/${note.toNAddr()}"
} else if (note.event is FollowListEvent) {
"https://following.space/d/${note.address.dTag}?p=${note.address.pubKeyHex}"
} else {
njumpLink(note.toNAddr())
when {
note.event?.bountyBaseReward() != null -> "https://nostrbounties.com/b/${note.toNAddr()}"
note.event is PeopleListEvent -> "https://listr.lol/a/${note.toNAddr()}"
note.event is FollowListEvent -> "https://following.space/d/${note.address.dTag}?p=${note.address.pubKeyHex}"
else -> njumpLink(note.toNAddr())
}
} else {
njumpLink(note.toNEvent())
@@ -1146,22 +1146,30 @@ private fun likeClick(
}
val choices = accountViewModel.reactionChoices()
if (choices.isEmpty()) {
when {
choices.isEmpty() -> {
accountViewModel.toastManager.toast(
R.string.no_reactions_setup,
R.string.no_reaction_type_setup_long_press_to_change,
)
} else if (!accountViewModel.isWriteable()) {
}
!accountViewModel.isWriteable() -> {
accountViewModel.toastManager.toast(
R.string.read_only_user,
R.string.login_with_a_private_key_to_like_posts,
)
} else if (choices.size == 1) {
}
choices.size == 1 -> {
onWantsToSignReaction()
} else if (choices.size > 1) {
}
choices.size > 1 -> {
onMultipleChoices()
}
}
}
@Composable
@OptIn(ExperimentalFoundationApi::class, ExperimentalUuidApi::class)
@@ -1369,14 +1377,19 @@ fun zapClick(
val choices = accountViewModel.zapAmountChoices()
if (choices.isEmpty()) {
when {
choices.isEmpty() -> {
onCustomAmount()
} else if (!accountViewModel.isWriteable()) {
}
!accountViewModel.isWriteable() -> {
accountViewModel.toastManager.toast(
R.string.error_dialog_zap_error,
R.string.login_with_a_private_key_to_be_able_to_send_zaps,
)
} else if (choices.size == 1) {
}
choices.size == 1 -> {
onZapStarts()
accountViewModel.zap(
baseNote,
@@ -1388,10 +1401,13 @@ fun zapClick(
onProgress = { onZappingProgress(it) },
onPayViaIntent = onPayViaIntent,
)
} else if (choices.size > 1) {
}
choices.size > 1 -> {
onMultipleChoices()
}
}
}
@Composable
private fun TwoStageZapProgressIcon(
@@ -56,7 +56,8 @@ fun timeAgo(
val timeDifference = TimeUtils.now() - time
return if (timeDifference > TimeUtils.ONE_YEAR) {
return when {
timeDifference > TimeUtils.ONE_YEAR -> {
// Dec 12, 2022
if (locale != Locale.getDefault()) {
@@ -66,7 +67,9 @@ fun timeAgo(
}
prefix + yearFormatter.format(time * 1000)
} else if (timeDifference > TimeUtils.ONE_MONTH) {
}
timeDifference > TimeUtils.ONE_MONTH -> {
// Dec 12
if (locale != Locale.getDefault()) {
locale = Locale.getDefault()
@@ -75,17 +78,25 @@ fun timeAgo(
}
prefix + monthFormatter.format(time * 1000)
} else if (timeDifference > TimeUtils.ONE_DAY) {
// 2 days
}
timeDifference > TimeUtils.ONE_DAY -> {
prefix + (timeDifference / TimeUtils.ONE_DAY).toString() + stringRes(context, days)
} else if (timeDifference > TimeUtils.ONE_HOUR) {
}
timeDifference > TimeUtils.ONE_HOUR -> {
prefix + (timeDifference / TimeUtils.ONE_HOUR).toString() + stringRes(context, hours)
} else if (timeDifference > TimeUtils.ONE_MINUTE) {
}
timeDifference > TimeUtils.ONE_MINUTE -> {
prefix + (timeDifference / TimeUtils.ONE_MINUTE).toString() + stringRes(context, minutes)
} else {
}
else -> {
prefix + stringRes(context, seconds)
}
}
}
fun timeAgoNoDot(
time: Long?,
@@ -96,7 +107,8 @@ fun timeAgoNoDot(
val timeDifference = TimeUtils.now() - time
return if (timeDifference > TimeUtils.ONE_YEAR) {
return when {
timeDifference > TimeUtils.ONE_YEAR -> {
// Dec 12, 2022
if (locale != Locale.getDefault()) {
@@ -106,7 +118,9 @@ fun timeAgoNoDot(
}
yearFormatter.format(time * 1000)
} else if (timeDifference > TimeUtils.ONE_MONTH) {
}
timeDifference > TimeUtils.ONE_MONTH -> {
// Dec 12
if (locale != Locale.getDefault()) {
locale = Locale.getDefault()
@@ -115,17 +129,25 @@ fun timeAgoNoDot(
}
monthFormatter.format(time * 1000)
} else if (timeDifference > TimeUtils.ONE_DAY) {
// 2 days
}
timeDifference > TimeUtils.ONE_DAY -> {
(timeDifference / TimeUtils.ONE_DAY).toString() + stringRes(context, R.string.d)
} else if (timeDifference > TimeUtils.ONE_HOUR) {
}
timeDifference > TimeUtils.ONE_HOUR -> {
(timeDifference / TimeUtils.ONE_HOUR).toString() + stringRes(context, R.string.h)
} else if (timeDifference > TimeUtils.ONE_MINUTE) {
}
timeDifference > TimeUtils.ONE_MINUTE -> {
(timeDifference / TimeUtils.ONE_MINUTE).toString() + stringRes(context, R.string.m)
} else {
}
else -> {
stringRes(context, R.string.now)
}
}
}
fun timeAgoNoDotNoDay(
time: Long?,
@@ -136,7 +158,8 @@ fun timeAgoNoDotNoDay(
val timeDifference = TimeUtils.now() - time
return if (timeDifference > TimeUtils.ONE_YEAR) {
return when {
timeDifference > TimeUtils.ONE_YEAR -> {
// Dec 12, 2022
if (locale != Locale.getDefault()) {
@@ -146,7 +169,9 @@ fun timeAgoNoDotNoDay(
}
yearNoDayFormatter.format(time * 1000)
} else if (timeDifference > TimeUtils.ONE_MONTH) {
}
timeDifference > TimeUtils.ONE_MONTH -> {
// Dec 12
if (locale != Locale.getDefault()) {
locale = Locale.getDefault()
@@ -155,17 +180,25 @@ fun timeAgoNoDotNoDay(
}
monthNoDayFormatter.format(time * 1000)
} else if (timeDifference > TimeUtils.ONE_DAY) {
// 2 days
}
timeDifference > TimeUtils.ONE_DAY -> {
(timeDifference / TimeUtils.ONE_DAY).toString() + stringRes(context, R.string.d)
} else if (timeDifference > TimeUtils.ONE_HOUR) {
}
timeDifference > TimeUtils.ONE_HOUR -> {
(timeDifference / TimeUtils.ONE_HOUR).toString() + stringRes(context, R.string.h)
} else if (timeDifference > TimeUtils.ONE_MINUTE) {
}
timeDifference > TimeUtils.ONE_MINUTE -> {
(timeDifference / TimeUtils.ONE_MINUTE).toString() + stringRes(context, R.string.m)
} else {
}
else -> {
stringRes(context, R.string.now)
}
}
}
fun timeAheadNoDot(
time: Long?,
@@ -176,7 +209,8 @@ fun timeAheadNoDot(
val timeDifference = time - TimeUtils.now()
return if (timeDifference > TimeUtils.ONE_YEAR) {
return when {
timeDifference > TimeUtils.ONE_YEAR -> {
// Dec 12, 2022
if (locale != Locale.getDefault()) {
@@ -186,7 +220,9 @@ fun timeAheadNoDot(
}
yearFormatter.format(time * 1000)
} else if (timeDifference > TimeUtils.ONE_MONTH) {
}
timeDifference > TimeUtils.ONE_MONTH -> {
// Dec 12
if (locale != Locale.getDefault()) {
locale = Locale.getDefault()
@@ -195,17 +231,25 @@ fun timeAheadNoDot(
}
monthFormatter.format(time * 1000)
} else if (timeDifference > TimeUtils.ONE_DAY) {
// 2 days
}
timeDifference > TimeUtils.ONE_DAY -> {
round(timeDifference / TimeUtils.ONE_DAY.toFloat()).toInt().toString() + stringRes(context, R.string.d)
} else if (timeDifference > TimeUtils.ONE_HOUR) {
}
timeDifference > TimeUtils.ONE_HOUR -> {
round(timeDifference / TimeUtils.ONE_HOUR.toFloat()).toInt().toString() + stringRes(context, R.string.h)
} else if (timeDifference > TimeUtils.ONE_MINUTE) {
}
timeDifference > TimeUtils.ONE_MINUTE -> {
round(timeDifference / TimeUtils.ONE_MINUTE.toFloat()).toInt().toString() + stringRes(context, R.string.m)
} else {
}
else -> {
stringRes(context, R.string.now)
}
}
}
fun dateFormatter(
time: Long?,
@@ -547,32 +547,39 @@ fun ZapVote(
interactionSource = remember { MutableInteractionSource() },
indication = ripple24dp,
onClick = {
if (!accountViewModel.isWriteable()) {
when {
!accountViewModel.isWriteable() -> {
accountViewModel.toastManager.toast(
R.string.read_only_user,
R.string.login_with_a_private_key_to_be_able_to_send_zaps,
)
} else if (pollViewModel.isPollClosed()) {
}
pollViewModel.isPollClosed() -> {
accountViewModel.toastManager.toast(
R.string.poll_unable_to_vote,
R.string.poll_is_closed_explainer,
)
} else if (isLoggedUser) {
}
isLoggedUser -> {
accountViewModel.toastManager.toast(
R.string.poll_unable_to_vote,
R.string.poll_author_no_vote,
)
} else if (pollViewModel.isVoteAmountAtomic() && poolOption.zappedByLoggedIn.value) {
}
pollViewModel.isVoteAmountAtomic() && poolOption.zappedByLoggedIn.value -> {
// only allow one vote per option when min==max, i.e. atomic vote amount specified
accountViewModel.toastManager.toast(
R.string.poll_unable_to_vote,
R.string.one_vote_per_user_on_atomic_votes,
)
return@combinedClickable
} else if (
}
accountViewModel.zapAmountChoices().size == 1 &&
pollViewModel.isValidInputVoteAmount(accountViewModel.zapAmountChoices().first())
) {
pollViewModel.isValidInputVoteAmount(accountViewModel.zapAmountChoices().first()) -> {
accountViewModel.zap(
baseNote,
accountViewModel.zapAmountChoices().first() * 1000,
@@ -598,9 +605,12 @@ fun ZapVote(
}
},
)
} else {
}
else -> {
wantsToZap = true
}
}
},
),
) {
@@ -138,14 +138,11 @@ class PollNoteViewModel : ViewModel() {
} == true
fun voteAmountPlaceHolderText(sats: String): String =
if (valueMinimum == null && valueMaximum == null) {
sats
} else if (valueMinimum == null) {
"1—$valueMaximum $sats"
} else if (valueMaximum == null) {
">$valueMinimum $sats"
} else {
"$valueMinimum$valueMaximum $sats"
when {
valueMinimum == null && valueMaximum == null -> sats
valueMinimum == null -> "1—$valueMaximum $sats"
valueMaximum == null -> ">$valueMinimum $sats"
else -> "$valueMinimum$valueMaximum $sats"
}
fun inputVoteAmountLong(textAmount: String) =
@@ -160,48 +157,68 @@ class PollNoteViewModel : ViewModel() {
}
fun isValidInputVoteAmount(amount: BigDecimal?): Boolean {
if (amount == null) {
when {
amount == null -> {
return false
} else if (valueMinimum == null && valueMaximum == null) {
}
valueMinimum == null && valueMaximum == null -> {
if (amount > BigDecimal.ZERO) {
return true
}
} else if (valueMinimum == null) {
}
valueMinimum == null -> {
if (amount > BigDecimal.ZERO && amount <= valueMaximumBD!!) {
return true
}
} else if (valueMaximum == null) {
}
valueMaximum == null -> {
if (amount >= valueMinimumBD!!) {
return true
}
} else {
}
else -> {
if ((valueMinimumBD!! <= amount) && (amount <= valueMaximumBD!!)) {
return true
}
}
}
return false
}
fun isValidInputVoteAmount(amount: Long?): Boolean {
if (amount == null) {
when {
amount == null -> {
return false
} else if (valueMinimum == null && valueMaximum == null) {
}
valueMinimum == null && valueMaximum == null -> {
if (amount > 0) {
return true
}
} else if (valueMinimum == null) {
}
valueMinimum == null -> {
if (amount > 0 && amount <= valueMaximum!!) {
return true
}
} else if (valueMaximum == null) {
}
valueMaximum == null -> {
if (amount >= valueMinimum!!) {
return true
}
} else {
}
else -> {
if ((valueMinimum!! <= amount) && (amount <= valueMaximum!!)) {
return true
}
}
}
return false
}
@@ -60,15 +60,19 @@ fun PreviewUrl(
accountViewModel: AccountViewModel,
nav: INav,
) {
if (RichTextParser.isValidURL(myUrlPreview)) {
if (RichTextParser.isImageUrl(myUrlPreview)) {
when {
RichTextParser.isValidURL(myUrlPreview) -> {
when {
RichTextParser.isImageUrl(myUrlPreview) -> {
AsyncImage(
model = myUrlPreview,
contentDescription = myUrlPreview,
contentScale = ContentScale.FillHeight,
modifier = Modifier.fillMaxHeight().aspectRatio(1f),
)
} else if (RichTextParser.isVideoUrl(myUrlPreview)) {
}
RichTextParser.isVideoUrl(myUrlPreview) -> {
VideoView(
myUrlPreview,
mimeType = null,
@@ -77,10 +81,15 @@ fun PreviewUrl(
contentScale = ContentScale.FillHeight,
accountViewModel = accountViewModel,
)
} else {
}
else -> {
MyLoadUrlPreviewDirect(myUrlPreview, myUrlPreview, accountViewModel)
}
} else if (RichTextParser.startsWithNIP19Scheme(myUrlPreview)) {
}
}
RichTextParser.startsWithNIP19Scheme(myUrlPreview) -> {
val bgColor = MaterialTheme.colorScheme.background
val backgroundColor = remember { mutableStateOf(bgColor) }
@@ -92,10 +101,13 @@ fun PreviewUrl(
accountViewModel = accountViewModel,
nav = nav,
)
} else if (RichTextParser.isUrlWithoutScheme(myUrlPreview)) {
}
RichTextParser.isUrlWithoutScheme(myUrlPreview) -> {
MyLoadUrlPreviewDirect("https://$myUrlPreview", myUrlPreview, accountViewModel)
}
}
}
@Composable
fun PreviewUrlFillWidth(
@@ -104,14 +116,17 @@ fun PreviewUrlFillWidth(
nav: INav,
) {
if (RichTextParser.isValidURL(myUrlPreview)) {
if (RichTextParser.isImageUrl(myUrlPreview)) {
when {
RichTextParser.isImageUrl(myUrlPreview) -> {
AsyncImage(
model = myUrlPreview,
contentDescription = myUrlPreview,
contentScale = ContentScale.FillWidth,
modifier = Modifier.fillMaxHeight().aspectRatio(1f),
)
} else if (RichTextParser.isVideoUrl(myUrlPreview)) {
}
RichTextParser.isVideoUrl(myUrlPreview) -> {
VideoView(
myUrlPreview,
mimeType = null,
@@ -120,9 +135,12 @@ fun PreviewUrlFillWidth(
contentScale = ContentScale.FillWidth,
accountViewModel = accountViewModel,
)
} else {
}
else -> {
MyLoadUrlPreviewDirectFillWidth(myUrlPreview, myUrlPreview, accountViewModel)
}
}
} else if (RichTextParser.startsWithNIP19Scheme(myUrlPreview)) {
val bgColor = MaterialTheme.colorScheme.background
val backgroundColor = remember { mutableStateOf(bgColor) }
@@ -92,7 +92,8 @@ class UserSuggestionState(
} else {
null
}
if (nip05 != null) {
when {
nip05 != null -> {
runCatching {
nip05Client.get(nip05)?.let { info ->
val user = account.cache.checkGetOrCreateUser(info.pubkey)
@@ -106,7 +107,9 @@ class UserSuggestionState(
user
}
}.getOrNull()
} else if (prefix.startsWithAny(userUriPrefixes)) {
}
prefix.startsWithAny(userUriPrefixes) -> {
runCatching {
Nip19Parser.uriToRoute(prefix)?.entity?.let { parsed ->
when (parsed) {
@@ -132,11 +135,16 @@ class UserSuggestionState(
}
}
}.getOrNull()
} else if (prefix.length == 64 && Hex.isHex64(prefix)) {
}
prefix.length == 64 && Hex.isHex64(prefix) -> {
account.cache.getOrCreateUser(prefix)
} else {
}
else -> {
null
}
}
} else {
null
}
@@ -331,7 +331,8 @@ fun RenderAttestationRequest(
}
if (quotesLeft > 0) {
if (aboutAddress != null) {
when {
aboutAddress != null -> {
LoadAddressableNote(aboutAddress, accountViewModel) {
if (it != null) {
Spacer(modifier = DoubleVertSpacer)
@@ -353,7 +354,9 @@ fun RenderAttestationRequest(
)
}
}
} else if (aboutEvent != null) {
}
aboutEvent != null -> {
LoadNote(aboutEvent, accountViewModel) {
if (it != null) {
Spacer(modifier = DoubleVertSpacer)
@@ -375,7 +378,9 @@ fun RenderAttestationRequest(
)
}
}
} else if (aboutPubkey != null) {
}
aboutPubkey != null -> {
LoadUser(aboutPubkey, accountViewModel) {
if (it != null) {
Spacer(modifier = DoubleVertSpacer)
@@ -390,6 +395,7 @@ fun RenderAttestationRequest(
}
}
}
}
@OptIn(ExperimentalLayoutApi::class)
@Composable
@@ -278,24 +278,32 @@ private fun DisplayQuoteAuthor(
}
}
if (addressable != null) {
when {
addressable != null -> {
addressable?.let {
DisplayEntryForNote(it, userBase, accountViewModel, nav)
}
} else if (version != null) {
}
version != null -> {
version?.let {
DisplayEntryForNote(it, userBase, accountViewModel, nav)
}
} else if (baseUrl != null) {
}
baseUrl != null -> {
val url = "$baseUrl${if (baseUrl.contains("#")) "&" else "#"}:~:text=${Uri.encode(highlightQuote)}"
DisplayEntryForAUrl(url, userBase, accountViewModel, nav)
} else if (userBase != null) {
}
userBase != null -> {
userBase?.let {
DisplayEntryForUser(it, accountViewModel, nav)
}
}
}
}
@Composable
fun DisplayEntryForUser(
@@ -233,14 +233,11 @@ fun RenderEyeGlassesPrescription(
val isContacts = contactsRightEye != null || contactsLeftEye != null
Text(
if (isGlasses && isContacts) {
"Vision Prescription"
} else if (isGlasses) {
"Glasses Prescription"
} else if (isContacts) {
"Contact Lenses Prescription"
} else {
"Empty Prescription"
when {
isGlasses && isContacts -> "Vision Prescription"
isGlasses -> "Glasses Prescription"
isContacts -> "Contact Lenses Prescription"
else -> "Empty Prescription"
},
modifier = Modifier.padding(4.dp).fillMaxWidth(),
textAlign = TextAlign.Center,
@@ -134,13 +134,16 @@ class AccountSessionManager(
}
val accountSettings =
if (loginWithExternalSigner) {
when {
loginWithExternalSigner -> {
AccountSettings(
keyPair = KeyPair(pubKey = pubKeyParsed),
transientAccount = transientAccount,
externalSignerPackageName = packageName.ifBlank { "com.greenart7c3.nostrsigner" },
)
} else if (key.startsWith("nsec")) {
}
key.startsWith("nsec") -> {
val privHex =
decodePrivateKeyAsHexOrNull(key)
?: throw Exception("Invalid nsec key")
@@ -148,22 +151,29 @@ class AccountSessionManager(
keyPair = KeyPair(privKey = privHex.hexToByteArray()),
transientAccount = transientAccount,
)
} else if (key.contains(" ") && Nip06().isValidMnemonic(key)) {
}
key.contains(" ") && Nip06().isValidMnemonic(key) -> {
AccountSettings(
keyPair = KeyPair(privKey = Nip06().privateKeyFromMnemonic(key)),
transientAccount = transientAccount,
)
} else if (pubKeyParsed != null) {
}
pubKeyParsed != null -> {
AccountSettings(
keyPair = KeyPair(pubKey = pubKeyParsed),
transientAccount = transientAccount,
)
} else {
}
else -> {
AccountSettings(
keyPair = KeyPair(Hex.decode(key)),
transientAccount = transientAccount,
)
}
}
localPreferences.setDefaultAccount(accountSettings)
@@ -1404,11 +1404,16 @@ class AccountViewModel(
viewModelScope.launch(Dispatchers.IO) {
for (note in notes) {
val noteEvent = note.event
if (noteEvent is IsInPublicChatChannel) {
when {
noteEvent is IsInPublicChatChannel -> {
account.markAsRead("Channel/${noteEvent.channelId()}", noteEvent.createdAt)
} else if (noteEvent is ChatroomKeyable) {
}
noteEvent is ChatroomKeyable -> {
account.markAsRead("Room/${noteEvent.chatroomKey(account.signer.pubKey).hashCode()}", noteEvent.createdAt)
} else if (noteEvent is DraftWrapEvent) {
}
noteEvent is DraftWrapEvent -> {
val innerEvent = account.draftsDecryptionCache.preCachedDraft(noteEvent)
if (innerEvent is IsInPublicChatChannel) {
account.markAsRead("Channel/${innerEvent.channelId()}", noteEvent.createdAt)
@@ -1417,6 +1422,7 @@ class AccountViewModel(
}
}
}
}
markHiddenChatroomsAsRead()
}
@@ -172,15 +172,17 @@ fun NormalChatNote(
remember(note) {
derivedStateOf {
val noteEvent = note.event
if (accountViewModel.isLoggedUser(note.author)) {
false // never shows the user's pictures
} else if (noteEvent is PrivateDmEvent) {
false // one-on-one, never shows it.
} else if (noteEvent is ChatroomKeyable) {
when {
accountViewModel.isLoggedUser(note.author) -> false
// never shows the user's pictures
noteEvent is PrivateDmEvent -> false
// one-on-one, never shows it.
// only shows in a group chat.
noteEvent.chatroomKey(accountViewModel.userProfile().pubkeyHex).users.size > 1
} else {
true
noteEvent is ChatroomKeyable -> noteEvent.chatroomKey(accountViewModel.userProfile().pubkeyHex).users.size > 1
else -> true
}
}
}
@@ -735,19 +735,27 @@ class ChatNewMessageViewModel :
fun autocompleteWithUser(item: User) {
userSuggestions?.let { userSuggestions ->
if (userSuggestionsMainMessage == UserSuggestionAnchor.MAIN_MESSAGE) {
when (userSuggestionsMainMessage) {
UserSuggestionAnchor.MAIN_MESSAGE -> {
val lastWord = message.currentWord()
userSuggestions.replaceCurrentWord(message, lastWord, item)
urlPreviews.update(message.text.toString())
} else if (userSuggestionsMainMessage == UserSuggestionAnchor.FORWARD_ZAPS) {
}
UserSuggestionAnchor.FORWARD_ZAPS -> {
forwardZapTo.value.addItem(item)
forwardZapToEditting.value = TextFieldValue("")
} else if (userSuggestionsMainMessage == UserSuggestionAnchor.TO_USERS) {
}
UserSuggestionAnchor.TO_USERS -> {
val lastWord = toUsers.currentWord()
userSuggestions.replaceCurrentWord(toUsers, lastWord, item)
updateRoomFromUsersInput()
}
else -> {}
}
userSuggestionsMainMessage = null
userSuggestions.reset()
}
@@ -415,7 +415,8 @@ open class ChannelNewMessageViewModel :
val contentWarningReason = if (wantsToMarkAsSensitive) contentWarningDescription else null
val localExpirationDate = if (wantsExpirationDate) expirationDate else null
return if (channel is PublicChatChannel) {
return when {
channel is PublicChatChannel -> {
val replyingToEvent = replyTo.value?.toEventHint<ChannelMessageEvent>()
val channelEvent = channel.event
@@ -462,7 +463,9 @@ open class ChannelNewMessageViewModel :
imetas(usedAttachments)
}
}
} else if (channel is LiveActivitiesChannel) {
}
channel is LiveActivitiesChannel -> {
val replyingToEvent = replyTo.value?.toEventHint<LiveActivitiesChatMessageEvent>()
val activity = channel.info
@@ -504,7 +507,9 @@ open class ChannelNewMessageViewModel :
imetas(usedAttachments)
}
}
} else if (channel is EphemeralChatChannel) {
}
channel is EphemeralChatChannel -> {
EphemeralChatEvent.build(
tagger.message,
channel.roomId.relayUrl,
@@ -519,10 +524,13 @@ open class ChannelNewMessageViewModel :
emojis(emojis)
imetas(usedAttachments)
}
} else {
}
else -> {
null
}
}
}
fun findEmoji(
message: String,
@@ -140,19 +140,27 @@ fun RenderContentDVMThumb(
card.amount?.let {
var color = Color.DarkGray
var amount = it
if (card.amount == "free" || card.amount == "0") {
when {
card.amount == "free" || card.amount == "0" -> {
color = MaterialTheme.colorScheme.secondary
amount = "Free"
} else if (card.amount == "flexible") {
}
card.amount == "flexible" -> {
color = MaterialTheme.colorScheme.primaryContainer
amount = "Flexible"
} else if (card.amount == "") {
}
card.amount == "" -> {
color = MaterialTheme.colorScheme.grayText
amount = "Unknown"
} else {
}
else -> {
color = MaterialTheme.colorScheme.primary
amount = card.amount + " Sats"
}
}
Text(
textAlign = TextAlign.End,
text = " $amount ",
@@ -98,29 +98,35 @@ class NotificationSummaryState(
LocalCache.notes.forEach { _, it ->
val noteEvent = it.event
if (noteEvent != null && !takenIntoAccount.contains(noteEvent.id)) {
if (noteEvent is ReactionEvent) {
when {
noteEvent is ReactionEvent -> {
if (noteEvent.isTaggedUser(currentUser) && noteEvent.pubKey != currentUser) {
val netDate = formatDate(noteEvent.createdAt)
reactions[netDate] = (reactions[netDate] ?: 0) + 1
takenIntoAccount.add(noteEvent.id)
}
} else if (noteEvent is RepostEvent || noteEvent is GenericRepostEvent) {
}
noteEvent is RepostEvent || noteEvent is GenericRepostEvent -> {
if (noteEvent.isTaggedUser(currentUser) && noteEvent.pubKey != currentUser) {
val netDate = formatDate(noteEvent.createdAt)
boosts[netDate] = (boosts[netDate] ?: 0) + 1
takenIntoAccount.add(noteEvent.id)
}
} else if (noteEvent is LnZapEvent) {
}
noteEvent is LnZapEvent -> {
// the user might be sending his own receipts noteEvent.pubKey != currentUser
if (noteEvent.isTaggedUser(currentUser)) {
val netDate = formatDate(noteEvent.createdAt)
zaps[netDate] = (zaps[netDate] ?: BigDecimal.ZERO) + (noteEvent.amount ?: BigDecimal.ZERO)
takenIntoAccount.add(noteEvent.id)
}
} else if (noteEvent is BaseThreadedEvent &&
}
noteEvent is BaseThreadedEvent &&
noteEvent.isTaggedUser(currentUser) &&
noteEvent.pubKey != currentUser
) {
noteEvent.pubKey != currentUser -> {
val isCitation =
noteEvent.findCitations().any {
LocalCache.getNoteIfExists(it)?.author?.pubkeyHex == currentUser
@@ -136,6 +142,7 @@ class NotificationSummaryState(
}
}
}
}
this.takenIntoAccount = takenIntoAccount
this.reactions.emit(reactions)
@@ -162,21 +169,26 @@ class NotificationSummaryState(
newNotes.forEach {
val noteEvent = it.event
if (noteEvent != null && !takenIntoAccount.contains(noteEvent.id)) {
if (noteEvent is ReactionEvent) {
when {
noteEvent is ReactionEvent -> {
if (noteEvent.isTaggedUser(currentUser) && noteEvent.pubKey != currentUser) {
val netDate = formatDate(noteEvent.createdAt)
reactions[netDate] = (reactions[netDate] ?: 0) + 1
takenIntoAccount.add(noteEvent.id)
hasNewElements = true
}
} else if (noteEvent is RepostEvent || noteEvent is GenericRepostEvent) {
}
noteEvent is RepostEvent || noteEvent is GenericRepostEvent -> {
if (noteEvent.isTaggedUser(currentUser) && noteEvent.pubKey != currentUser) {
val netDate = formatDate(noteEvent.createdAt)
boosts[netDate] = (boosts[netDate] ?: 0) + 1
takenIntoAccount.add(noteEvent.id)
hasNewElements = true
}
} else if (noteEvent is LnZapEvent) {
}
noteEvent is LnZapEvent -> {
if (noteEvent.isTaggedUser(currentUser)) {
// && noteEvent.pubKey != currentUser User might be sending his own receipts
val netDate = formatDate(noteEvent.createdAt)
@@ -184,10 +196,11 @@ class NotificationSummaryState(
takenIntoAccount.add(noteEvent.id)
hasNewElements = true
}
} else if (noteEvent is BaseThreadedEvent &&
}
noteEvent is BaseThreadedEvent &&
noteEvent.isTaggedUser(currentUser) &&
noteEvent.pubKey != currentUser
) {
noteEvent.pubKey != currentUser -> {
val isCitation =
noteEvent.findCitations().any {
LocalCache.getNoteIfExists(it)?.author?.pubkeyHex == currentUser
@@ -205,6 +218,7 @@ class NotificationSummaryState(
}
}
}
}
if (hasNewElements) {
this.takenIntoAccount = takenIntoAccount
@@ -598,18 +598,26 @@ class NewPublicMessageViewModel :
fun autocompleteWithUser(item: User) {
userSuggestions?.let { userSuggestions ->
if (userSuggestionsMainMessage == UserSuggestionAnchor.MAIN_MESSAGE) {
when (userSuggestionsMainMessage) {
UserSuggestionAnchor.MAIN_MESSAGE -> {
val lastWord = message.currentWord()
userSuggestions.replaceCurrentWord(message, lastWord, item)
urlPreviews.update(message.text.toString())
} else if (userSuggestionsMainMessage == UserSuggestionAnchor.FORWARD_ZAPS) {
}
UserSuggestionAnchor.FORWARD_ZAPS -> {
forwardZapTo.value.addItem(item)
forwardZapToEditting.value = TextFieldValue("")
} else if (userSuggestionsMainMessage == UserSuggestionAnchor.TO_USERS) {
}
UserSuggestionAnchor.TO_USERS -> {
val lastWord = toUsers.currentWord()
userSuggestions.replaceCurrentWord(toUsers, lastWord, item)
}
else -> {}
}
userSuggestionsMainMessage = null
userSuggestions.reset()
}
@@ -79,7 +79,8 @@ fun GalleryThumbnail(
val noteEvent = noteState.note.event ?: return
val content =
if (noteEvent is ProfileGalleryEntryEvent) {
when {
noteEvent is ProfileGalleryEntryEvent -> {
noteEvent.urls().map { url ->
if (isVideoUrl(url)) {
MediaUrlVideo(
@@ -107,7 +108,9 @@ fun GalleryThumbnail(
)
}
}
} else if (noteEvent is PictureEvent) {
}
noteEvent is PictureEvent -> {
noteEvent.imetaTags().map { imeta ->
MediaUrlImage(
url = imeta.url,
@@ -121,7 +124,9 @@ fun GalleryThumbnail(
thumbhash = imeta.thumbhash,
)
}
} else if (noteEvent is VideoEvent) {
}
noteEvent is VideoEvent -> {
// An HLS publish writes one imeta per rendition (master + each variant) on the same
// NIP-71 event. Rendering them all expands a single video into a sub-grid of black
// tiles inside one gallery card — the .m3u8 playlist is a text manifest Coil can't
@@ -156,7 +161,9 @@ fun GalleryThumbnail(
artworkUri = imeta.image.firstOrNull(),
)
}
} else if (noteEvent is LiveActivitiesClipEvent) {
}
noteEvent is LiveActivitiesClipEvent -> {
noteEvent.videoUrl()?.let { url ->
listOf(
MediaUrlVideo(
@@ -171,9 +178,12 @@ fun GalleryThumbnail(
),
)
} ?: emptyList()
} else {
}
else -> {
emptyList()
}
}
InnerRenderGalleryThumb(content, baseNote, accountViewModel)
}
@@ -125,7 +125,8 @@ class SearchBarViewModel(
} else {
null
}
if (nip05 != null) {
when {
nip05 != null -> {
runCatching {
nip05Client.get(nip05)?.let { info ->
val user = account.cache.checkGetOrCreateUser(info.pubkey)
@@ -139,7 +140,9 @@ class SearchBarViewModel(
user
}
}.getOrNull()
} else if (term.startsWithAny(userUriPrefixes)) {
}
term.startsWithAny(userUriPrefixes) -> {
runCatching {
Nip19Parser.uriToRoute(term)?.entity?.let { parsed ->
when (parsed) {
@@ -165,11 +168,16 @@ class SearchBarViewModel(
}
}
}.getOrNull()
} else if (term.length == 64 && Hex.isHex64(term)) {
}
term.length == 64 && Hex.isHex64(term) -> {
account.cache.getOrCreateUser(term)
} else {
}
else -> {
null
}
}
}.flowOn(Dispatchers.IO)
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
@@ -168,7 +168,8 @@ fun VideoFeedLoaded(
key = { _, item -> item.idHex },
contentType = { _, item -> item.event?.kind ?: -1 },
) { _, item ->
if (item.event is PictureEvent) {
when {
item.event is PictureEvent -> {
PictureCardCompose(
baseNote = item,
accountViewModel = accountViewModel,
@@ -180,7 +181,9 @@ fun VideoFeedLoaded(
)
Spacer(modifier = Modifier.height(8.dp))
} else if (item.event is VideoEvent) {
}
item.event is VideoEvent -> {
VideoCardCompose(item, accountViewModel, nav)
HorizontalDivider(
@@ -188,7 +191,9 @@ fun VideoFeedLoaded(
)
Spacer(modifier = Modifier.height(8.dp))
} else if (item.event is FileHeaderEvent) {
}
item.event is FileHeaderEvent -> {
FileHeaderCardCompose(item, accountViewModel, nav)
HorizontalDivider(
@@ -200,3 +205,4 @@ fun VideoFeedLoaded(
}
}
}
}