Implements contextual rounded corners for images and videos

This commit is contained in:
Vitor Pamplona
2023-08-19 11:08:55 -04:00
parent d8ce3b9d37
commit 63f3a6cdf9
10 changed files with 92 additions and 52 deletions
@@ -241,6 +241,7 @@ fun ImageVideoPost(postViewModel: NewMediaModel, accountViewModel: AccountViewMo
postViewModel.galleryUri?.let { postViewModel.galleryUri?.let {
VideoView( VideoView(
videoUri = it.toString(), videoUri = it.toString(),
roundedCorner = false,
accountViewModel = accountViewModel accountViewModel = accountViewModel
) )
} }
@@ -385,7 +385,7 @@ fun NewPostView(
) )
) )
} else if (videoExtensions.any { removedParamsFromUrl.endsWith(it) }) { } else if (videoExtensions.any { removedParamsFromUrl.endsWith(it) }) {
VideoView(myUrlPreview, accountViewModel = accountViewModel) VideoView(myUrlPreview, roundedCorner = true, accountViewModel = accountViewModel)
} else { } else {
UrlPreview(myUrlPreview, myUrlPreview, accountViewModel) UrlPreview(myUrlPreview, myUrlPreview, accountViewModel)
} }
@@ -1365,7 +1365,7 @@ fun ImageVideoDescription(
) )
} }
} else { } else {
VideoView(uri.toString(), accountViewModel = accountViewModel) VideoView(uri.toString(), roundedCorner = true, accountViewModel = accountViewModel)
} }
} }
@@ -287,7 +287,7 @@ private fun ZoomableContentView(
) { ) {
state.imagesForPager[word]?.let { state.imagesForPager[word]?.let {
Box(modifier = HalfVertPadding) { Box(modifier = HalfVertPadding) {
ZoomableContentView(it, state.imageList, accountViewModel) ZoomableContentView(it, state.imageList, roundedCorner = true, accountViewModel)
} }
} }
} }
@@ -19,6 +19,7 @@ import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.defaultMinSize
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.padding
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.IconButton import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme import androidx.compose.material.MaterialTheme
@@ -71,6 +72,7 @@ import com.vitorpamplona.amethyst.ui.theme.PinBottomIconSize
import com.vitorpamplona.amethyst.ui.theme.Size22Modifier import com.vitorpamplona.amethyst.ui.theme.Size22Modifier
import com.vitorpamplona.amethyst.ui.theme.Size50Modifier import com.vitorpamplona.amethyst.ui.theme.Size50Modifier
import com.vitorpamplona.amethyst.ui.theme.VolumeBottomIconSize import com.vitorpamplona.amethyst.ui.theme.VolumeBottomIconSize
import com.vitorpamplona.amethyst.ui.theme.imageModifier
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
@@ -88,6 +90,7 @@ fun LoadThumbAndThenVideoView(
title: String? = null, title: String? = null,
thumbUri: String, thumbUri: String,
authorName: String? = null, authorName: String? = null,
roundedCorner: Boolean,
nostrUriCallback: String? = null, nostrUriCallback: String? = null,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
onDialog: ((Boolean) -> Unit)? = null onDialog: ((Boolean) -> Unit)? = null
@@ -119,6 +122,7 @@ fun LoadThumbAndThenVideoView(
videoUri = videoUri, videoUri = videoUri,
title = title, title = title,
thumb = VideoThumb(loadingFinished.second), thumb = VideoThumb(loadingFinished.second),
roundedCorner = roundedCorner,
artworkUri = thumbUri, artworkUri = thumbUri,
authorName = authorName, authorName = authorName,
nostrUriCallback = nostrUriCallback, nostrUriCallback = nostrUriCallback,
@@ -130,6 +134,7 @@ fun LoadThumbAndThenVideoView(
videoUri = videoUri, videoUri = videoUri,
title = title, title = title,
thumb = null, thumb = null,
roundedCorner = roundedCorner,
artworkUri = thumbUri, artworkUri = thumbUri,
authorName = authorName, authorName = authorName,
nostrUriCallback = nostrUriCallback, nostrUriCallback = nostrUriCallback,
@@ -145,6 +150,7 @@ fun VideoView(
videoUri: String, videoUri: String,
title: String? = null, title: String? = null,
thumb: VideoThumb? = null, thumb: VideoThumb? = null,
roundedCorner: Boolean,
waveform: ImmutableList<Int>? = null, waveform: ImmutableList<Int>? = null,
artworkUri: String? = null, artworkUri: String? = null,
authorName: String? = null, authorName: String? = null,
@@ -160,6 +166,7 @@ fun VideoView(
defaultToStart, defaultToStart,
title, title,
thumb, thumb,
roundedCorner,
waveform, waveform,
artworkUri, artworkUri,
authorName, authorName,
@@ -177,6 +184,7 @@ fun VideoViewInner(
defaultToStart: Boolean = false, defaultToStart: Boolean = false,
title: String? = null, title: String? = null,
thumb: VideoThumb? = null, thumb: VideoThumb? = null,
roundedCorner: Boolean,
waveform: ImmutableList<Int>? = null, waveform: ImmutableList<Int>? = null,
artworkUri: String? = null, artworkUri: String? = null,
authorName: String? = null, authorName: String? = null,
@@ -231,7 +239,16 @@ fun VideoViewInner(
defaultToStart = defaultToStart, defaultToStart = defaultToStart,
nostrUriCallback = nostrUriCallback nostrUriCallback = nostrUriCallback
) { controller, keepPlaying -> ) { controller, keepPlaying ->
RenderVideoPlayer(controller, thumb, waveform, keepPlaying, automaticallyStartPlayback, activeOnScreen, onDialog) RenderVideoPlayer(
controller = controller,
thumbData = thumb,
roundedCorner = roundedCorner,
waveform = waveform,
keepPlaying = keepPlaying,
automaticallyStartPlayback = automaticallyStartPlayback,
activeOnScreen = activeOnScreen,
onDialog = onDialog
)
} }
} }
} }
@@ -483,6 +500,7 @@ data class VideoThumb(
private fun RenderVideoPlayer( private fun RenderVideoPlayer(
controller: MediaController, controller: MediaController,
thumbData: VideoThumb?, thumbData: VideoThumb?,
roundedCorner: Boolean,
waveform: ImmutableList<Int>? = null, waveform: ImmutableList<Int>? = null,
keepPlaying: MutableState<Boolean>, keepPlaying: MutableState<Boolean>,
automaticallyStartPlayback: MutableState<Boolean>, automaticallyStartPlayback: MutableState<Boolean>,
@@ -499,10 +517,15 @@ private fun RenderVideoPlayer(
BoxWithConstraints() { BoxWithConstraints() {
AndroidView( AndroidView(
modifier = Modifier modifier = if (roundedCorner) {
.fillMaxWidth() MaterialTheme.colors.imageModifier
.defaultMinSize(minHeight = 100.dp) .defaultMinSize(minHeight = 100.dp)
.align(Alignment.Center), .align(Alignment.Center)
} else {
Modifier.fillMaxWidth()
.defaultMinSize(minHeight = 100.dp)
.align(Alignment.Center)
},
factory = { factory = {
PlayerView(context).apply { PlayerView(context).apply {
player = controller player = controller
@@ -620,7 +643,7 @@ fun Waveform(
@Composable @Composable
fun DrawWaveform(waveform: ImmutableList<Int>, waveformProgress: MutableState<Float>, align: Modifier) { fun DrawWaveform(waveform: ImmutableList<Int>, waveformProgress: MutableState<Float>, align: Modifier) {
AudioWaveformReadOnly( AudioWaveformReadOnly(
modifier = align, modifier = align.padding(start = 10.dp, end = 10.dp),
amplitudes = waveform, amplitudes = waveform,
progress = waveformProgress.value, progress = waveformProgress.value,
progressBrush = Brush.infiniteLinearGradient( progressBrush = Brush.infiniteLinearGradient(
@@ -181,6 +181,7 @@ fun figureOutMimeType(fullUrl: String): ZoomableContent {
fun ZoomableContentView( fun ZoomableContentView(
content: ZoomableContent, content: ZoomableContent,
images: ImmutableList<ZoomableContent> = listOf(content).toImmutableList(), images: ImmutableList<ZoomableContent> = listOf(content).toImmutableList(),
roundedCorner: Boolean,
accountViewModel: AccountViewModel accountViewModel: AccountViewModel
) { ) {
val clipboardManager = LocalClipboardManager.current val clipboardManager = LocalClipboardManager.current
@@ -190,7 +191,11 @@ fun ZoomableContentView(
mutableStateOf(false) mutableStateOf(false)
} }
var mainImageModifier = MaterialTheme.colors.imageModifier var mainImageModifier = if (roundedCorner) {
MaterialTheme.colors.imageModifier
} else {
Modifier.fillMaxWidth()
}
if (content is ZoomableUrlContent) { if (content is ZoomableUrlContent) {
mainImageModifier = mainImageModifier.combinedClickable( mainImageModifier = mainImageModifier.combinedClickable(
@@ -215,6 +220,7 @@ fun ZoomableContentView(
title = content.description, title = content.description,
artworkUri = content.artworkUri, artworkUri = content.artworkUri,
authorName = content.authorName, authorName = content.authorName,
roundedCorner = roundedCorner,
nostrUriCallback = content.uri, nostrUriCallback = content.uri,
onDialog = { dialogOpen = true }, onDialog = { dialogOpen = true },
accountViewModel = accountViewModel accountViewModel = accountViewModel
@@ -228,6 +234,7 @@ fun ZoomableContentView(
title = content.description, title = content.description,
artworkUri = content.artworkUri, artworkUri = content.artworkUri,
authorName = content.authorName, authorName = content.authorName,
roundedCorner = roundedCorner,
nostrUriCallback = content.uri, nostrUriCallback = content.uri,
onDialog = { dialogOpen = true }, onDialog = { dialogOpen = true },
accountViewModel = accountViewModel accountViewModel = accountViewModel
@@ -624,11 +631,11 @@ fun ZoomableImageDialog(
pagerState = pagerState, pagerState = pagerState,
itemsCount = allImages.size, itemsCount = allImages.size,
itemContent = { index -> itemContent = { index ->
RenderImageOrVideo(allImages[index], accountViewModel) RenderImageOrVideo(allImages[index], false, accountViewModel)
} }
) )
} else { } else {
RenderImageOrVideo(imageUrl, accountViewModel) RenderImageOrVideo(imageUrl, false, accountViewModel)
} }
Row( Row(
@@ -656,7 +663,7 @@ fun ZoomableImageDialog(
} }
@Composable @Composable
private fun RenderImageOrVideo(content: ZoomableContent, accountViewModel: AccountViewModel) { private fun RenderImageOrVideo(content: ZoomableContent, roundedCorner: Boolean, accountViewModel: AccountViewModel) {
val mainModifier = Modifier val mainModifier = Modifier
.fillMaxSize() .fillMaxSize()
.zoomable(rememberZoomState()) .zoomable(rememberZoomState())
@@ -670,6 +677,7 @@ private fun RenderImageOrVideo(content: ZoomableContent, accountViewModel: Accou
title = content.description, title = content.description,
artworkUri = content.artworkUri, artworkUri = content.artworkUri,
authorName = content.authorName, authorName = content.authorName,
roundedCorner = roundedCorner,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
alwaysShowVideo = true alwaysShowVideo = true
) )
@@ -684,6 +692,7 @@ private fun RenderImageOrVideo(content: ZoomableContent, accountViewModel: Accou
title = content.description, title = content.description,
artworkUri = content.artworkUri, artworkUri = content.artworkUri,
authorName = content.authorName, authorName = content.authorName,
roundedCorner = roundedCorner,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
alwaysShowVideo = true alwaysShowVideo = true
) )
@@ -40,7 +40,7 @@ class NotificationFeedFilter(val account: Account) : AdditiveFeedFilter<Note>()
it.event !is BadgeDefinitionEvent && it.event !is BadgeDefinitionEvent &&
it.event !is BadgeProfilesEvent && it.event !is BadgeProfilesEvent &&
it.event !is GiftWrapEvent && it.event !is GiftWrapEvent &&
it.author !== loggedInUser && (it.event is LnZapEvent || it.author !== loggedInUser) &&
(isGlobal || it.author?.pubkeyHex in followingKeySet) && (isGlobal || it.author?.pubkeyHex in followingKeySet) &&
it.event?.isTaggedUser(loggedInUserHex) ?: false && it.event?.isTaggedUser(loggedInUserHex) ?: false &&
(isHiddenList || it.author == null || !account.isHidden(it.author!!.pubkeyHex)) && (isHiddenList || it.author == null || !account.isHidden(it.author!!.pubkeyHex)) &&
@@ -481,8 +481,8 @@ fun NormalNote(
) )
} }
is BadgeDefinitionEvent -> BadgeDisplay(baseNote = baseNote) is BadgeDefinitionEvent -> BadgeDisplay(baseNote = baseNote)
is FileHeaderEvent -> FileHeaderDisplay(baseNote, accountViewModel) is FileHeaderEvent -> FileHeaderDisplay(baseNote, isQuotedNote, accountViewModel)
is FileStorageHeaderEvent -> FileStorageHeaderDisplay(baseNote, accountViewModel) is FileStorageHeaderEvent -> FileStorageHeaderDisplay(baseNote, isQuotedNote, accountViewModel)
else -> else ->
LongPressToQuickAction(baseNote = baseNote, accountViewModel = accountViewModel) { showPopup -> LongPressToQuickAction(baseNote = baseNote, accountViewModel = accountViewModel) { showPopup ->
CheckNewAndRenderNote( CheckNewAndRenderNote(
@@ -3194,7 +3194,7 @@ private fun RenderBadge(
} }
@Composable @Composable
fun FileHeaderDisplay(note: Note, accountViewModel: AccountViewModel) { fun FileHeaderDisplay(note: Note, isQuotedNote: Boolean, accountViewModel: AccountViewModel) {
val event = (note.event as? FileHeaderEvent) ?: return val event = (note.event as? FileHeaderEvent) ?: return
val fullUrl = event.url() ?: return val fullUrl = event.url() ?: return
@@ -3230,18 +3230,18 @@ fun FileHeaderDisplay(note: Note, accountViewModel: AccountViewModel) {
} }
SensitivityWarning(note = note, accountViewModel = accountViewModel) { SensitivityWarning(note = note, accountViewModel = accountViewModel) {
ZoomableContentView(content = content, accountViewModel = accountViewModel) ZoomableContentView(content = content, roundedCorner = isQuotedNote, accountViewModel = accountViewModel)
} }
} }
@Composable @Composable
fun FileStorageHeaderDisplay(baseNote: Note, accountViewModel: AccountViewModel) { fun FileStorageHeaderDisplay(baseNote: Note, isQuotedNote: Boolean, accountViewModel: AccountViewModel) {
val eventHeader = (baseNote.event as? FileStorageHeaderEvent) ?: return val eventHeader = (baseNote.event as? FileStorageHeaderEvent) ?: return
val dataEventId = eventHeader.dataEventId() ?: return val dataEventId = eventHeader.dataEventId() ?: return
LoadNote(baseNoteHex = dataEventId) { contentNote -> LoadNote(baseNoteHex = dataEventId) { contentNote ->
if (contentNote != null) { if (contentNote != null) {
ObserverAndRenderNIP95(baseNote, contentNote, accountViewModel) ObserverAndRenderNIP95(baseNote, contentNote, isQuotedNote, accountViewModel)
} }
} }
} }
@@ -3250,6 +3250,7 @@ fun FileStorageHeaderDisplay(baseNote: Note, accountViewModel: AccountViewModel)
private fun ObserverAndRenderNIP95( private fun ObserverAndRenderNIP95(
header: Note, header: Note,
content: Note, content: Note,
isQuotedNote: Boolean,
accountViewModel: AccountViewModel accountViewModel: AccountViewModel
) { ) {
val eventHeader = (header.event as? FileStorageHeaderEvent) ?: return val eventHeader = (header.event as? FileStorageHeaderEvent) ?: return
@@ -3296,7 +3297,7 @@ private fun ObserverAndRenderNIP95(
Crossfade(targetState = content) { Crossfade(targetState = content) {
if (it != null) { if (it != null) {
SensitivityWarning(note = header, accountViewModel = accountViewModel) { SensitivityWarning(note = header, accountViewModel = accountViewModel) {
ZoomableContentView(content = it, accountViewModel = accountViewModel) ZoomableContentView(content = it, roundedCorner = isQuotedNote, accountViewModel = accountViewModel)
} }
} }
} }
@@ -3367,6 +3368,7 @@ fun AudioTrackHeader(noteEvent: AudioTrackEvent, note: Note, accountViewModel: A
title = noteEvent.subject(), title = noteEvent.subject(),
thumbUri = cover, thumbUri = cover,
authorName = note.author?.toBestDisplayName(), authorName = note.author?.toBestDisplayName(),
roundedCorner = true,
nostrUriCallback = "nostr:${note.toNEvent()}", nostrUriCallback = "nostr:${note.toNEvent()}",
accountViewModel = accountViewModel accountViewModel = accountViewModel
) )
@@ -3375,6 +3377,7 @@ fun AudioTrackHeader(noteEvent: AudioTrackEvent, note: Note, accountViewModel: A
videoUri = media, videoUri = media,
title = noteEvent.subject(), title = noteEvent.subject(),
authorName = note.author?.toBestDisplayName(), authorName = note.author?.toBestDisplayName(),
roundedCorner = true,
accountViewModel = accountViewModel accountViewModel = accountViewModel
) )
} }
@@ -3387,9 +3390,23 @@ fun AudioTrackHeader(noteEvent: AudioTrackEvent, note: Note, accountViewModel: A
fun AudioHeader(noteEvent: AudioHeaderEvent, note: Note, accountViewModel: AccountViewModel, nav: (String) -> Unit) { fun AudioHeader(noteEvent: AudioHeaderEvent, note: Note, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
val media = remember { noteEvent.stream() ?: noteEvent.download() } val media = remember { noteEvent.stream() ?: noteEvent.download() }
val waveform = remember { noteEvent.wavefrom()?.toImmutableList()?.ifEmpty { null } } val waveform = remember { noteEvent.wavefrom()?.toImmutableList()?.ifEmpty { null } }
val subject = remember { noteEvent.subject()?.ifBlank { null } }
val content = remember { noteEvent.content().ifBlank { null } } val content = remember { noteEvent.content().ifBlank { null } }
val defaultBackground = MaterialTheme.colors.background
val background = remember { mutableStateOf(defaultBackground) }
val tags = remember(noteEvent) { noteEvent?.tags()?.toImmutableListOfLists() ?: ImmutableListOfLists() }
val eventContent = remember(note.event) {
val subject = (note.event as? TextNoteEvent)?.subject()?.ifEmpty { null }
val body = accountViewModel.decrypt(note)
if (!subject.isNullOrBlank() && body?.split("\n")?.get(0)?.contains(subject) == false) {
"## $subject\n$body"
} else {
body
}
}
Row(modifier = Modifier.padding(top = 5.dp)) { Row(modifier = Modifier.padding(top = 5.dp)) {
Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
media?.let { media -> media?.let { media ->
@@ -3401,42 +3418,30 @@ fun AudioHeader(noteEvent: AudioHeaderEvent, note: Note, accountViewModel: Accou
waveform = waveform, waveform = waveform,
title = noteEvent.subject(), title = noteEvent.subject(),
authorName = note.author?.toBestDisplayName(), authorName = note.author?.toBestDisplayName(),
roundedCorner = true,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
nostrUriCallback = note.toNostrUri() nostrUriCallback = note.toNostrUri()
) )
} }
} }
Row() { content?.let {
subject?.let { Row(verticalAlignment = CenterVertically, modifier = Modifier.fillMaxWidth().padding(top = 5.dp)) {
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(top = 5.dp, bottom = 5.dp)) { TranslatableRichTextViewer(
Text( content = it,
text = it, canPreview = true,
fontWeight = FontWeight.Bold, tags = tags,
maxLines = 3, backgroundColor = background,
overflow = TextOverflow.Ellipsis, accountViewModel = accountViewModel,
modifier = Modifier.fillMaxWidth() nav = nav
) )
}
} }
} }
Row() { Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
content?.let { val hashtags = remember(noteEvent) { noteEvent.hashtags().toImmutableList() }
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(top = 5.dp, bottom = 5.dp)) { DisplayUncitedHashtags(hashtags, content ?: "", nav)
Text(
text = it,
fontWeight = FontWeight.Bold,
maxLines = 3,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.fillMaxWidth()
)
}
}
} }
val hashtags = remember(noteEvent) { noteEvent.hashtags().toImmutableList() }
DisplayUncitedHashtags(hashtags, content ?: "", nav)
} }
} }
} }
@@ -3559,6 +3564,7 @@ fun RenderLiveActivityEventInner(baseNote: Note, accountViewModel: AccountViewMo
title = subject, title = subject,
artworkUri = cover, artworkUri = cover,
authorName = baseNote.author?.toBestDisplayName(), authorName = baseNote.author?.toBestDisplayName(),
roundedCorner = true,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
nostrUriCallback = "nostr:${baseNote.toNEvent()}" nostrUriCallback = "nostr:${baseNote.toNEvent()}"
) )
@@ -377,9 +377,9 @@ fun NoteMaster(
nav = nav nav = nav
) )
} else if (noteEvent is FileHeaderEvent) { } else if (noteEvent is FileHeaderEvent) {
FileHeaderDisplay(baseNote, accountViewModel) FileHeaderDisplay(baseNote, true, accountViewModel)
} else if (noteEvent is FileStorageHeaderEvent) { } else if (noteEvent is FileStorageHeaderEvent) {
FileStorageHeaderDisplay(baseNote, accountViewModel) FileStorageHeaderDisplay(baseNote, true, accountViewModel)
} else if (noteEvent is PeopleListEvent) { } else if (noteEvent is PeopleListEvent) {
DisplayPeopleList(baseNote, backgroundColor, accountViewModel, nav) DisplayPeopleList(baseNote, backgroundColor, accountViewModel, nav)
} else if (noteEvent is AudioTrackEvent) { } else if (noteEvent is AudioTrackEvent) {
@@ -640,6 +640,7 @@ fun ShowVideoStreaming(
ZoomableContentView( ZoomableContentView(
content = zoomableUrlVideo, content = zoomableUrlVideo,
roundedCorner = false,
accountViewModel = accountViewModel accountViewModel = accountViewModel
) )
} }
@@ -302,9 +302,9 @@ private fun RenderVideoOrPictureNote(
Row(remember { Modifier.weight(1f) }, verticalAlignment = Alignment.CenterVertically) { Row(remember { Modifier.weight(1f) }, verticalAlignment = Alignment.CenterVertically) {
val noteEvent = remember { note.event } val noteEvent = remember { note.event }
if (noteEvent is FileHeaderEvent) { if (noteEvent is FileHeaderEvent) {
FileHeaderDisplay(note, accountViewModel) FileHeaderDisplay(note, false, accountViewModel)
} else if (noteEvent is FileStorageHeaderEvent) { } else if (noteEvent is FileStorageHeaderEvent) {
FileStorageHeaderDisplay(note, accountViewModel) FileStorageHeaderDisplay(note, false, accountViewModel)
} }
} }
} }