remove text preview from images

This commit is contained in:
Believethehype 2024-06-28 23:38:41 +02:00
parent f331398316
commit 45df7713ce
11 changed files with 358 additions and 74 deletions

View File

@ -2203,6 +2203,7 @@ class Account(
url: String,
) {
if (!isWriteable()) return
GalleryListEvent.addEvent(
userProfile().latestGalleryList,
idHex,
@ -2226,6 +2227,7 @@ class Account(
GalleryListEvent.removeReplaceable(
galleryentries,
note.address,
url,
signer,
) {
Client.send(it)
@ -2235,6 +2237,7 @@ class Account(
GalleryListEvent.removeEvent(
galleryentries,
note.idHex,
url,
signer,
) {
Client.send(it)

View File

@ -142,7 +142,6 @@ fun LoadThumbAndThenVideoView(
roundedCorner: Boolean,
isFiniteHeight: Boolean,
nostrUriCallback: String? = null,
nostrIdCallback: String? = null,
accountViewModel: AccountViewModel,
onDialog: ((Boolean) -> Unit)? = null,
) {
@ -177,7 +176,6 @@ fun LoadThumbAndThenVideoView(
artworkUri = thumbUri,
authorName = authorName,
nostrUriCallback = nostrUriCallback,
nostrIdCallback = nostrIdCallback,
accountViewModel = accountViewModel,
onDialog = onDialog,
)
@ -192,7 +190,6 @@ fun LoadThumbAndThenVideoView(
artworkUri = thumbUri,
authorName = authorName,
nostrUriCallback = nostrUriCallback,
nostrIdCallback = nostrIdCallback,
accountViewModel = accountViewModel,
onDialog = onDialog,
)
@ -214,7 +211,6 @@ fun VideoView(
dimensions: String? = null,
blurhash: String? = null,
nostrUriCallback: String? = null,
nostrIdCallback: String? = null,
onDialog: ((Boolean) -> Unit)? = null,
onControllerVisibilityChanged: ((Boolean) -> Unit)? = null,
accountViewModel: AccountViewModel,
@ -256,7 +252,6 @@ fun VideoView(
artworkUri = artworkUri,
authorName = authorName,
nostrUriCallback = nostrUriCallback,
nostrIDCallback = nostrIdCallback,
automaticallyStartPlayback = automaticallyStartPlayback,
onControllerVisibilityChanged = onControllerVisibilityChanged,
onDialog = onDialog,
@ -310,7 +305,6 @@ fun VideoView(
artworkUri = artworkUri,
authorName = authorName,
nostrUriCallback = nostrUriCallback,
nostrIDCallback = nostrIdCallback,
automaticallyStartPlayback = automaticallyStartPlayback,
onControllerVisibilityChanged = onControllerVisibilityChanged,
onDialog = onDialog,
@ -335,7 +329,6 @@ fun VideoViewInner(
artworkUri: String? = null,
authorName: String? = null,
nostrUriCallback: String? = null,
nostrIDCallback: String? = null,
automaticallyStartPlayback: State<Boolean>,
onControllerVisibilityChanged: ((Boolean) -> Unit)? = null,
onDialog: ((Boolean) -> Unit)? = null,
@ -357,7 +350,6 @@ fun VideoViewInner(
roundedCorner = roundedCorner,
isFiniteHeight = isFiniteHeight,
nostrUriCallback = nostrUriCallback,
nostrIDCallback = nostrIDCallback,
waveform = waveform,
keepPlaying = keepPlaying,
automaticallyStartPlayback = automaticallyStartPlayback,
@ -705,7 +697,6 @@ private fun RenderVideoPlayer(
roundedCorner: Boolean,
isFiniteHeight: Boolean,
nostrUriCallback: String?,
nostrIDCallback: String?,
waveform: ImmutableList<Int>? = null,
keepPlaying: MutableState<Boolean>,
automaticallyStartPlayback: State<Boolean>,
@ -819,7 +810,7 @@ private fun RenderVideoPlayer(
}
AnimatedShareButton(controllerVisible, Modifier.align(Alignment.TopEnd).padding(end = Size165dp)) { popupExpanded, toggle ->
ShareImageAction(accountViewModel = accountViewModel, popupExpanded, videoUri, nostrUriCallback, nostrIDCallback, toggle)
ShareImageAction(accountViewModel = accountViewModel, popupExpanded, videoUri, nostrUriCallback, toggle)
}
}
}

View File

@ -95,6 +95,7 @@ import com.vitorpamplona.amethyst.ui.theme.Size75dp
import com.vitorpamplona.amethyst.ui.theme.hashVerifierMark
import com.vitorpamplona.amethyst.ui.theme.imageModifier
import com.vitorpamplona.quartz.crypto.CryptoUtils
import com.vitorpamplona.quartz.encoders.Nip19Bech32
import com.vitorpamplona.quartz.encoders.toHexKey
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
@ -138,7 +139,6 @@ fun ZoomableContentView(
roundedCorner = roundedCorner,
isFiniteHeight = isFiniteHeight,
nostrUriCallback = content.uri,
nostrIdCallback = content.id,
onDialog = { dialogOpen = true },
accountViewModel = accountViewModel,
)
@ -163,7 +163,6 @@ fun ZoomableContentView(
roundedCorner = roundedCorner,
isFiniteHeight = isFiniteHeight,
nostrUriCallback = content.uri,
nostrIdCallback = content.id,
onDialog = { dialogOpen = true },
accountViewModel = accountViewModel,
)
@ -609,7 +608,6 @@ fun ShareImageAction(
popupExpanded = popupExpanded,
videoUri = content.url,
postNostrUri = content.uri,
postNostrid = content.id,
onDismiss = onDismiss,
)
} else if (content is MediaPreloadedContent) {
@ -618,7 +616,6 @@ fun ShareImageAction(
popupExpanded = popupExpanded,
videoUri = content.localFile?.toUri().toString(),
postNostrUri = content.uri,
postNostrid = content.id,
onDismiss = onDismiss,
)
}
@ -631,7 +628,6 @@ fun ShareImageAction(
popupExpanded: MutableState<Boolean>,
videoUri: String?,
postNostrUri: String?,
postNostrid: String?,
onDismiss: () -> Unit,
) {
DropdownMenu(
@ -665,13 +661,13 @@ fun ShareImageAction(
text = { Text(stringRes(R.string.add_media_to_gallery)) },
onClick = {
if (videoUri != null) {
if (postNostrid != null) {
print("TODO")
print(postNostrid)
// TODO this still crashes
accountViewModel.account.addToGallery(postNostrid, videoUri)
var n19 = Nip19Bech32.uriToRoute(postNostrUri)?.entity as? Nip19Bech32.NEvent
if (n19 != null) {
accountViewModel.addMediaToGallery(n19.hex, videoUri)
accountViewModel.toast(R.string.image_saved_to_the_gallery, R.string.image_saved_to_the_gallery)
}
}
onDismiss()
},
)

View File

@ -154,6 +154,38 @@ fun LongPressToQuickAction(
}
}
@Composable
fun LongPressToQuickActionGallery(
baseNote: Note,
accountViewModel: AccountViewModel,
content: @Composable (() -> Unit) -> Unit,
) {
val popupExpanded = remember { mutableStateOf(false) }
content { popupExpanded.value = true }
if (popupExpanded.value) {
NoteQuickActionMenuGallery(
note = baseNote,
onDismiss = { popupExpanded.value = false },
accountViewModel = accountViewModel,
nav = {},
)
}
}
@Composable
fun NoteQuickActionMenuGallery(
note: Note,
onDismiss: () -> Unit,
accountViewModel: AccountViewModel,
nav: (String) -> Unit,
) {
DeleteFromGalleryDialog(note, accountViewModel) {
onDismiss()
}
}
@Composable
fun NoteQuickActionMenu(
note: Note,
@ -435,6 +467,169 @@ private fun RenderMainPopup(
}
}
@Composable
private fun RenderDeleteFromGalleryPopup(
accountViewModel: AccountViewModel,
note: Note,
showDeleteAlertDialog: MutableState<Boolean>,
onDismiss: () -> Unit,
) {
val context = LocalContext.current
val primaryLight = lightenColor(MaterialTheme.colorScheme.primary, 0.1f)
val cardShape = RoundedCornerShape(5.dp)
val clipboardManager = LocalClipboardManager.current
val scope = rememberCoroutineScope()
val backgroundColor =
if (MaterialTheme.colorScheme.isLight) {
MaterialTheme.colorScheme.primary
} else {
MaterialTheme.colorScheme.secondaryButtonBackground
}
val showToast = { stringRes: Int ->
scope.launch {
Toast
.makeText(
context,
stringRes(context, stringRes),
Toast.LENGTH_SHORT,
).show()
}
}
val isOwnNote = accountViewModel.isLoggedUser(note.author)
val isFollowingUser = !isOwnNote && accountViewModel.isFollowing(note.author)
Popup(onDismissRequest = onDismiss, alignment = Alignment.Center) {
Card(
modifier = Modifier.shadow(elevation = 6.dp, shape = cardShape),
shape = cardShape,
colors = CardDefaults.cardColors(containerColor = backgroundColor),
) {
Column(modifier = Modifier.width(IntrinsicSize.Min)) {
Row(modifier = Modifier.height(IntrinsicSize.Min)) {
NoteQuickActionItem(
icon = Icons.Default.ContentCopy,
label = stringRes(R.string.quick_action_copy_text),
) {
accountViewModel.decrypt(note) {
clipboardManager.setText(AnnotatedString(it))
showToast(R.string.copied_note_text_to_clipboard)
}
onDismiss()
}
VerticalDivider(color = primaryLight)
NoteQuickActionItem(
Icons.Default.AlternateEmail,
stringRes(R.string.quick_action_copy_user_id),
) {
note.author?.let {
scope.launch {
clipboardManager.setText(AnnotatedString(it.toNostrUri()))
showToast(R.string.copied_user_id_to_clipboard)
onDismiss()
}
}
}
VerticalDivider(color = primaryLight)
NoteQuickActionItem(
Icons.Default.FormatQuote,
stringRes(R.string.quick_action_copy_note_id),
) {
scope.launch {
clipboardManager.setText(AnnotatedString(note.toNostrUri()))
showToast(R.string.copied_note_id_to_clipboard)
onDismiss()
}
}
}
HorizontalDivider(
color = primaryLight,
)
Row(modifier = Modifier.height(IntrinsicSize.Min)) {
if (isOwnNote) {
NoteQuickActionItem(
Icons.Default.Delete,
stringRes(R.string.quick_action_delete),
) {
if (accountViewModel.hideDeleteRequestDialog) {
accountViewModel.delete(note)
onDismiss()
} else {
showDeleteAlertDialog.value = true
}
}
} else if (isFollowingUser) {
NoteQuickActionItem(
Icons.Default.PersonRemove,
stringRes(R.string.quick_action_unfollow),
) {
accountViewModel.unfollow(note.author!!)
onDismiss()
}
} else {
NoteQuickActionItem(
Icons.Default.PersonAdd,
stringRes(R.string.quick_action_follow),
) {
accountViewModel.follow(note.author!!)
onDismiss()
}
}
VerticalDivider(color = primaryLight)
NoteQuickActionItem(
icon = ImageVector.vectorResource(id = R.drawable.relays),
label = stringRes(R.string.broadcast),
) {
accountViewModel.broadcast(note)
// showSelectTextDialog = true
onDismiss()
}
VerticalDivider(color = primaryLight)
if (isOwnNote && note.isDraft()) {
NoteQuickActionItem(
Icons.Default.Edit,
stringRes(R.string.edit_draft),
) {
onDismiss()
}
} else {
NoteQuickActionItem(
icon = Icons.Default.Share,
label = stringRes(R.string.quick_action_share),
) {
val sendIntent =
Intent().apply {
action = Intent.ACTION_SEND
type = "text/plain"
putExtra(
Intent.EXTRA_TEXT,
externalLinkForNote(note),
)
putExtra(
Intent.EXTRA_TITLE,
stringRes(context, R.string.quick_action_share_browser_link),
)
}
val shareIntent =
Intent.createChooser(
sendIntent,
stringRes(context, R.string.quick_action_share),
)
ContextCompat.startActivity(context, shareIntent, null)
onDismiss()
}
}
}
}
}
}
}
@Composable
fun NoteQuickActionItem(
icon: ImageVector,
@ -462,6 +657,25 @@ fun NoteQuickActionItem(
}
}
@Composable
fun DeleteFromGalleryDialog(
note: Note,
accountViewModel: AccountViewModel,
onDismiss: () -> Unit,
) {
QuickActionAlertDialogOneButton(
title = stringRes(R.string.quick_action_request_deletion_gallery_title),
textContent = stringRes(R.string.quick_action_request_deletion_gallery_alert_body),
buttonIcon = Icons.Default.Delete,
buttonText = stringRes(R.string.quick_action_delete_dialog_btn),
onClickDoOnce = {
note.event?.firstTaggedUrl()?.let { accountViewModel.removefromMediaGallery(note, it) }
onDismiss()
},
onDismiss = onDismiss,
)
}
@Composable
fun DeleteAlertDialog(
note: Note,
@ -612,3 +826,95 @@ fun QuickActionAlertDialog(
},
)
}
@Composable
fun QuickActionAlertDialogOneButton(
title: String,
textContent: String,
buttonIcon: ImageVector,
buttonText: String,
buttonColors: ButtonColors = ButtonDefaults.buttonColors(),
onClickDoOnce: () -> Unit,
onDismiss: () -> Unit,
) {
QuickActionAlertDialogOneButton(
title = title,
textContent = textContent,
icon = {
Icon(
imageVector = buttonIcon,
contentDescription = null,
)
},
buttonText = buttonText,
buttonColors = buttonColors,
onClickDoOnce = onClickDoOnce,
onDismiss = onDismiss,
)
}
@Composable
fun QuickActionAlertDialogOneButton(
title: String,
textContent: String,
buttonIconResource: Int,
buttonText: String,
buttonColors: ButtonColors = ButtonDefaults.buttonColors(),
onClickDoOnce: () -> Unit,
onDismiss: () -> Unit,
) {
QuickActionAlertDialogOneButton(
title = title,
textContent = textContent,
icon = {
Icon(
painter = painterResource(buttonIconResource),
contentDescription = null,
)
},
buttonText = buttonText,
buttonColors = buttonColors,
onClickDoOnce = onClickDoOnce,
onDismiss = onDismiss,
)
}
@Composable
fun QuickActionAlertDialogOneButton(
title: String,
textContent: String,
icon: @Composable () -> Unit,
buttonText: String,
buttonColors: ButtonColors = ButtonDefaults.buttonColors(),
onClickDoOnce: () -> Unit,
onDismiss: () -> Unit,
) {
AlertDialog(
onDismissRequest = onDismiss,
title = { Text(title) },
text = { Text(textContent) },
confirmButton = {
Row(
modifier =
Modifier
.padding(all = 8.dp)
.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
) {
Button(
onClick = onClickDoOnce,
colors = buttonColors,
contentPadding = PaddingValues(horizontal = 16.dp),
) {
Row(
verticalAlignment = Alignment.CenterVertically,
) {
icon()
Spacer(Modifier.width(8.dp))
Text(buttonText)
}
}
}
},
)
}

View File

@ -212,7 +212,6 @@ fun AudioHeader(
isFiniteHeight = isFiniteHeight,
accountViewModel = accountViewModel,
nostrUriCallback = note.toNostrUri(),
nostrIdCallback = note.idHex,
)
}
}

View File

@ -160,7 +160,6 @@ fun RenderLiveActivityEventInner(
isFiniteHeight = false,
accountViewModel = accountViewModel,
nostrUriCallback = "nostr:${baseNote.toNEvent()}",
nostrIdCallback = baseNote.idHex,
)
}
} else {

View File

@ -669,6 +669,20 @@ class AccountViewModel(
viewModelScope.launch(Dispatchers.IO) { account.addEmojiPack(usersEmojiList, emojiList) }
}
fun addMediaToGallery(
hex: String,
url: String,
) {
viewModelScope.launch(Dispatchers.IO) { account.addToGallery(hex, url) }
}
fun removefromMediaGallery(
note: Note,
url: String,
) {
viewModelScope.launch(Dispatchers.IO) { account.removeFromGallery(note, url) }
}
fun addPrivateBookmark(note: Note) {
viewModelScope.launch(Dispatchers.IO) { account.addBookmark(note, true) }
}

View File

@ -22,15 +22,12 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn
import androidx.compose.animation.core.tween
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyGridState
@ -39,7 +36,6 @@ import androidx.compose.foundation.lazy.grid.itemsIndexed
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.MutableState
@ -51,8 +47,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@ -64,7 +58,7 @@ import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled
import com.vitorpamplona.amethyst.ui.components.SensitivityWarning
import com.vitorpamplona.amethyst.ui.note.CheckHiddenFeedWatchBlockAndReport
import com.vitorpamplona.amethyst.ui.note.ClickableNote
import com.vitorpamplona.amethyst.ui.note.LongPressToQuickAction
import com.vitorpamplona.amethyst.ui.note.LongPressToQuickActionGallery
import com.vitorpamplona.amethyst.ui.note.WatchAuthor
import com.vitorpamplona.amethyst.ui.note.WatchNoteEvent
import com.vitorpamplona.amethyst.ui.note.calculateBackgroundColor
@ -78,7 +72,6 @@ import com.vitorpamplona.amethyst.ui.theme.DividerThickness
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
import com.vitorpamplona.amethyst.ui.theme.HalfPadding
import com.vitorpamplona.amethyst.ui.theme.QuoteBorder
import com.vitorpamplona.amethyst.ui.theme.Size5dp
import com.vitorpamplona.quartz.events.TextNoteEvent
@Composable
@ -247,8 +240,7 @@ fun GalleryCard(
nav: (String) -> Unit,
) {
// baseNote.event?.let { Text(text = it.pubKey()) }
LongPressToQuickAction(baseNote = baseNote, accountViewModel = accountViewModel) { showPopup ->
LongPressToQuickActionGallery(baseNote = baseNote, accountViewModel = accountViewModel) { showPopup ->
CheckNewAndRenderChannelCard(
baseNote,
modifier,
@ -400,7 +392,7 @@ fun InnerRenderGalleryThumb(
)
} ?: run { DisplayGalleryAuthorBanner(note) }
Row(
/* Row(
Modifier
.fillMaxWidth()
.background(Color.Black.copy(0.6f))
@ -417,7 +409,7 @@ fun InnerRenderGalleryThumb(
modifier = Modifier.weight(1f),
)
}
/*
card.price?.let {
val priceTag =
remember(card) {
@ -438,8 +430,8 @@ fun InnerRenderGalleryThumb(
overflow = TextOverflow.Ellipsis,
color = Color.White,
)
}*/
}
}
}*/
}
}

View File

@ -157,6 +157,7 @@ import com.vitorpamplona.amethyst.ui.screen.RefresheableFeedView
import com.vitorpamplona.amethyst.ui.screen.RefreshingFeedUserFeedView
import com.vitorpamplona.amethyst.ui.screen.RelayFeedView
import com.vitorpamplona.amethyst.ui.screen.RelayFeedViewModel
import com.vitorpamplona.amethyst.ui.screen.SaveableGridFeedState
import com.vitorpamplona.amethyst.ui.screen.UserFeedViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
@ -1571,14 +1572,17 @@ fun TabGallery(
modifier = Modifier.padding(vertical = 0.dp),
) {
var state = LazyGridState()
RenderGalleryFeed(
feedViewModel,
null,
0,
state,
accountViewModel = accountViewModel,
nav = nav,
)
SaveableGridFeedState(feedViewModel, scrollStateKey = "gallery") { listState ->
RenderGalleryFeed(
feedViewModel,
null,
0,
state,
accountViewModel = accountViewModel,
nav = nav,
)
}
}
}
}

View File

@ -270,6 +270,8 @@
<string name="quick_action_delete">Delete</string>
<string name="quick_action_unfollow">Unfollow</string>
<string name="quick_action_follow">Follow</string>
<string name="quick_action_request_deletion_gallery_title">Delete from Gallery</string>
<string name="quick_action_request_deletion_gallery_alert_body">Remove this media from your Gallery, you can readd it later</string>
<string name="quick_action_request_deletion_alert_title">Request Deletion</string>
<string name="quick_action_request_deletion_alert_body">Amethyst will request that your note be deleted from the relays you are currently connected to. There is no guarantee that your note will be permanently deleted from those relays, or from other relays where it may be stored.</string>
<string name="quick_action_block_dialog_btn">Block</string>

View File

@ -60,7 +60,7 @@ class GalleryListEvent(
) {
add(
earlierVersion,
arrayOf(arrayOf(tagName, url, tagValue)),
arrayOf(arrayOf(tagName, tagValue, url)),
signer,
createdAt,
onReady,
@ -76,7 +76,7 @@ class GalleryListEvent(
) {
create(
content = earlierVersion?.content ?: "",
tags = (earlierVersion?.tags ?: arrayOf(arrayOf("d", DEFAULT_D_TAG_GALLERY))).plus(listNewTags),
tags = listNewTags.plus(earlierVersion?.tags ?: arrayOf(arrayOf("d", DEFAULT_D_TAG_GALLERY))),
signer = signer,
createdAt = createdAt,
onReady = onReady,
@ -86,23 +86,26 @@ class GalleryListEvent(
fun removeEvent(
earlierVersion: GalleryListEvent,
eventId: HexKey,
url: String,
signer: NostrSigner,
createdAt: Long = TimeUtils.now(),
onReady: (GalleryListEvent) -> Unit,
) = removeTag(earlierVersion, "e", eventId, signer, createdAt, onReady)
) = removeTag(earlierVersion, "g", eventId, url, signer, createdAt, onReady)
fun removeReplaceable(
earlierVersion: GalleryListEvent,
aTag: ATag,
url: String,
signer: NostrSigner,
createdAt: Long = TimeUtils.now(),
onReady: (GalleryListEvent) -> Unit,
) = removeTag(earlierVersion, "a", aTag.toTag(), signer, createdAt, onReady)
) = removeTag(earlierVersion, "g", aTag.toTag(), url, signer, createdAt, onReady)
private fun removeTag(
earlierVersion: GalleryListEvent,
tagName: String,
tagValue: HexKey,
url: String,
signer: NostrSigner,
createdAt: Long = TimeUtils.now(),
onReady: (GalleryListEvent) -> Unit,
@ -111,7 +114,7 @@ class GalleryListEvent(
content = earlierVersion.content,
tags =
earlierVersion.tags
.filter { it.size <= 1 || !(it[0] == tagName && it[1] == tagValue) }
.filter { it.size <= 1 || !(it[0] == tagName && it[1] == tagValue && it[2] == url) }
.toTypedArray(),
signer = signer,
createdAt = createdAt,
@ -135,30 +138,5 @@ class GalleryListEvent(
signer.sign(createdAt, KIND, newTags, content, onReady)
}
fun create(
name: String = "",
images: List<String>? = null,
videos: List<String>? = null,
audios: List<String>? = null,
privEvents: List<String>? = null,
privUsers: List<String>? = null,
privAddresses: List<ATag>? = null,
signer: NostrSigner,
createdAt: Long = TimeUtils.now(),
onReady: (GalleryListEvent) -> Unit,
) {
val tags = mutableListOf<Array<String>>()
tags.add(arrayOf("d", name))
images?.forEach { tags.add(arrayOf("g", it)) }
videos?.forEach { tags.add(arrayOf("g", it)) }
audios?.forEach { tags.add(arrayOf("g", it)) }
tags.add(arrayOf("alt", ALT))
createPrivateTags(privEvents, privUsers, privAddresses, signer) { content ->
signer.sign(createdAt, KIND, tags.toTypedArray(), content, onReady)
}
}
}
}