mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-03-17 13:21:50 +01:00
Minor refactoring of chat screen components.
This commit is contained in:
parent
7d2b7789d3
commit
94c78c6327
@ -81,7 +81,7 @@ import com.vitorpamplona.amethyst.ui.note.SearchIcon
|
||||
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.ChannelName
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.ChannelName
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.search.SearchBarViewModel
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
||||
|
@ -62,7 +62,7 @@ import com.vitorpamplona.amethyst.ui.note.UserCompose
|
||||
import com.vitorpamplona.amethyst.ui.note.timeAgo
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.LoadUser
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.LoadUser
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer
|
||||
|
@ -20,7 +20,6 @@
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.components
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
@ -94,7 +93,7 @@ import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.note.NoteCompose
|
||||
import com.vitorpamplona.amethyst.ui.note.toShortenHex
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.LoadUser
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.LoadUser
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.theme.CashuCardBorders
|
||||
import com.vitorpamplona.amethyst.ui.theme.HalfVertPadding
|
||||
|
@ -41,7 +41,7 @@ import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.ui.note.elements.TimeAgo
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.NewItemsBubble
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.NewItemsBubble
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
||||
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
|
||||
|
@ -60,10 +60,10 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.LoadRedirectScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.NewPostScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarks.BookmarkListScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.MessagesScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.ChatroomByAuthorScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.ChatroomScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.ChannelScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.MessagesScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.communities.CommunityScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.DiscoverScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.drafts.DraftListScreen
|
||||
|
@ -44,7 +44,7 @@ import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImage
|
||||
import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage
|
||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.LoadUser
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.LoadUser
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
|
||||
|
||||
|
@ -29,37 +29,21 @@ import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.richtext.BaseMediaContent
|
||||
import com.vitorpamplona.amethyst.commons.richtext.EncryptedMediaUrlImage
|
||||
import com.vitorpamplona.amethyst.commons.richtext.EncryptedMediaUrlVideo
|
||||
import com.vitorpamplona.amethyst.commons.richtext.RichTextParser
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.service.okhttp.HttpClientManager
|
||||
import com.vitorpamplona.amethyst.ui.components.GenericLoadable
|
||||
import com.vitorpamplona.amethyst.ui.components.SensitivityWarning
|
||||
import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer
|
||||
import com.vitorpamplona.amethyst.ui.components.ZoomableContentView
|
||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.navigation.routeFor
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.types.RenderEncryptedFile
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.header.ChatroomHeader
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.HalfVertPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.replyModifier
|
||||
import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKeyable
|
||||
import com.vitorpamplona.quartz.nip17Dm.files.ChatMessageEncryptedFileHeaderEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.files.encryption.AESGCM
|
||||
import com.vitorpamplona.quartz.nip31Alts.alt
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
@Composable
|
||||
fun RenderChatMessageEncryptedFile(
|
||||
@ -99,78 +83,3 @@ fun RenderChatMessageEncryptedFile(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun RenderEncryptedFile(
|
||||
note: Note,
|
||||
backgroundBubbleColor: MutableState<Color>,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val noteEvent = note.event as? ChatMessageEncryptedFileHeaderEvent ?: return
|
||||
|
||||
val algo = noteEvent.algo()
|
||||
val key = noteEvent.key()
|
||||
val nonce = noteEvent.nonce()
|
||||
val mimeType = noteEvent.mimeType()
|
||||
|
||||
if (algo == AESGCM.NAME && key != null && nonce != null) {
|
||||
HttpClientManager.addCipherToCache(noteEvent.content, AESGCM(key, nonce), mimeType)
|
||||
|
||||
val content by remember(noteEvent) {
|
||||
val isImage = mimeType?.startsWith("image/") == true || RichTextParser.isImageUrl(noteEvent.content)
|
||||
|
||||
mutableStateOf<BaseMediaContent>(
|
||||
if (isImage) {
|
||||
EncryptedMediaUrlImage(
|
||||
url = noteEvent.content,
|
||||
description = noteEvent.alt(),
|
||||
hash = noteEvent.originalHash(),
|
||||
blurhash = noteEvent.blurhash(),
|
||||
dim = noteEvent.dimensions(),
|
||||
uri = note.toNostrUri(),
|
||||
mimeType = mimeType,
|
||||
encryptionAlgo = algo,
|
||||
encryptionKey = key,
|
||||
encryptionNonce = nonce,
|
||||
)
|
||||
} else {
|
||||
EncryptedMediaUrlVideo(
|
||||
url = noteEvent.content,
|
||||
description = noteEvent.alt(),
|
||||
hash = noteEvent.originalHash(),
|
||||
blurhash = noteEvent.blurhash(),
|
||||
dim = noteEvent.dimensions(),
|
||||
uri = note.toNostrUri(),
|
||||
authorName = note.author?.toBestDisplayName(),
|
||||
mimeType = mimeType,
|
||||
encryptionAlgo = algo,
|
||||
encryptionKey = key,
|
||||
encryptionNonce = nonce,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
ZoomableContentView(
|
||||
content,
|
||||
persistentListOf(content),
|
||||
roundedCorner = true,
|
||||
contentScale = ContentScale.FillWidth,
|
||||
accountViewModel,
|
||||
)
|
||||
} else {
|
||||
TranslatableRichTextViewer(
|
||||
content = stringRes(id = R.string.could_not_decrypt_the_message),
|
||||
canPreview = true,
|
||||
quotesLeft = 0,
|
||||
modifier = Modifier,
|
||||
tags = EmptyTagList,
|
||||
backgroundColor = backgroundBubbleColor,
|
||||
id = note.idHex,
|
||||
callbackUri = note.toNostrUri(),
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.feed
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed
|
||||
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
@ -28,10 +28,8 @@ import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled
|
||||
import com.vitorpamplona.amethyst.ui.feeds.FeedEmpty
|
||||
@ -40,14 +38,10 @@ import com.vitorpamplona.amethyst.ui.feeds.FeedState
|
||||
import com.vitorpamplona.amethyst.ui.feeds.LoadingFeed
|
||||
import com.vitorpamplona.amethyst.ui.feeds.RefresheableBox
|
||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.note.dateFormatter
|
||||
import com.vitorpamplona.amethyst.ui.screen.FeedViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.SaveableFeedState
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.messages.ChatroomMessageCompose
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||
import com.vitorpamplona.quartz.nip14Subject.subject
|
||||
import com.vitorpamplona.quartz.nip37Drafts.DraftEvent
|
||||
|
||||
@Composable
|
||||
@ -64,7 +58,7 @@ fun RefreshingChatroomFeedView(
|
||||
) {
|
||||
RefresheableBox(viewModel, enablePullRefresh) {
|
||||
SaveableFeedState(viewModel, scrollStateKey) { listState ->
|
||||
RenderChatroomFeedView(
|
||||
RenderChatFeedView(
|
||||
viewModel,
|
||||
accountViewModel,
|
||||
listState,
|
||||
@ -79,7 +73,7 @@ fun RefreshingChatroomFeedView(
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun RenderChatroomFeedView(
|
||||
fun RenderChatFeedView(
|
||||
viewModel: FeedViewModel,
|
||||
accountViewModel: AccountViewModel,
|
||||
listState: LazyListState,
|
||||
@ -97,7 +91,7 @@ fun RenderChatroomFeedView(
|
||||
is FeedState.Empty -> FeedEmpty { viewModel.invalidateData() }
|
||||
is FeedState.FeedError -> FeedError(state.errorMessage) { viewModel.invalidateData() }
|
||||
is FeedState.Loaded ->
|
||||
ChatroomFeedLoaded(
|
||||
ChatFeedLoaded(
|
||||
state,
|
||||
accountViewModel,
|
||||
listState,
|
||||
@ -112,7 +106,7 @@ fun RenderChatroomFeedView(
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ChatroomFeedLoaded(
|
||||
fun ChatFeedLoaded(
|
||||
loaded: FeedState.Loaded,
|
||||
accountViewModel: AccountViewModel,
|
||||
listState: LazyListState,
|
||||
@ -153,31 +147,3 @@ fun ChatroomFeedLoaded(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun NewDateOrSubjectDivisor(
|
||||
previous: Note?,
|
||||
note: Note,
|
||||
) {
|
||||
if (previous == null) return
|
||||
|
||||
val never = stringRes(R.string.never)
|
||||
val today = stringRes(R.string.today)
|
||||
|
||||
val prevDate = remember(previous) { dateFormatter(previous.event?.createdAt, never, today) }
|
||||
val date = remember(note) { dateFormatter(note.event?.createdAt, never, today) }
|
||||
|
||||
val subject = remember(note) { note.event?.subject() }
|
||||
|
||||
if (prevDate != date) {
|
||||
if (subject != null) {
|
||||
ChatDivisor("$date - $subject")
|
||||
} else {
|
||||
ChatDivisor(date)
|
||||
}
|
||||
} else {
|
||||
if (subject != null) {
|
||||
ChatDivisor(subject)
|
||||
}
|
||||
}
|
||||
}
|
@ -18,71 +18,48 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.messages
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed
|
||||
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.runtime.produceState
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.model.FeatureSetType
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji
|
||||
import com.vitorpamplona.amethyst.ui.components.SensitivityWarning
|
||||
import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer
|
||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.note.DisplayDraftChat
|
||||
import com.vitorpamplona.amethyst.ui.note.FollowingIcon
|
||||
import com.vitorpamplona.amethyst.ui.note.InnerUserPicture
|
||||
import com.vitorpamplona.amethyst.ui.note.LikeReaction
|
||||
import com.vitorpamplona.amethyst.ui.note.LoadDecryptedContentOrNull
|
||||
import com.vitorpamplona.amethyst.ui.note.NoteQuickActionMenu
|
||||
import com.vitorpamplona.amethyst.ui.note.ObserveDraftEvent
|
||||
import com.vitorpamplona.amethyst.ui.note.RelayBadgesHorizontal
|
||||
import com.vitorpamplona.amethyst.ui.note.ReplyReaction
|
||||
import com.vitorpamplona.amethyst.ui.note.WatchBlockAndReport
|
||||
import com.vitorpamplona.amethyst.ui.note.WatchNoteEvent
|
||||
import com.vitorpamplona.amethyst.ui.note.WatchUserFollows
|
||||
import com.vitorpamplona.amethyst.ui.note.ZapReaction
|
||||
import com.vitorpamplona.amethyst.ui.note.timeAgoShort
|
||||
import com.vitorpamplona.amethyst.ui.note.types.RenderEncryptedFile
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.layouts.ChatBubbleLayout
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.types.RenderChangeChannelMetadataNote
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.types.RenderCreateChannelNote
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.types.RenderDraftEvent
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.types.RenderEncryptedFile
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.types.RenderRegularTextNote
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.IncognitoBadge
|
||||
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.Font12SP
|
||||
import com.vitorpamplona.amethyst.ui.theme.RowColSpacing
|
||||
import com.vitorpamplona.amethyst.ui.theme.RowColSpacing5dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size18Modifier
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size20dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size5Modifier
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.chatAuthorBox
|
||||
import com.vitorpamplona.amethyst.ui.theme.incognitoIconModifier
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists
|
||||
import com.vitorpamplona.quartz.nip02FollowList.toImmutableListOfLists
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.PrivateDmEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKeyable
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.NIP17Group
|
||||
import com.vitorpamplona.quartz.nip17Dm.files.ChatMessageEncryptedFileHeaderEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelMetadataEvent
|
||||
@ -225,11 +202,11 @@ fun NormalChatNote(
|
||||
}
|
||||
}
|
||||
},
|
||||
) { backgroundBubbleColor ->
|
||||
) { bgColor ->
|
||||
MessageBubbleLines(
|
||||
note,
|
||||
innerQuote,
|
||||
backgroundBubbleColor,
|
||||
bgColor,
|
||||
onWantsToReply,
|
||||
onWantsToEditDraft,
|
||||
canPreview,
|
||||
@ -243,7 +220,7 @@ fun NormalChatNote(
|
||||
private fun MessageBubbleLines(
|
||||
baseNote: Note,
|
||||
innerQuote: Boolean,
|
||||
backgroundBubbleColor: MutableState<Color>,
|
||||
bgColor: MutableState<Color>,
|
||||
onWantsToReply: (Note) -> Unit,
|
||||
onWantsToEditDraft: (Note) -> Unit,
|
||||
canPreview: Boolean,
|
||||
@ -254,7 +231,7 @@ private fun MessageBubbleLines(
|
||||
RenderReplyRow(
|
||||
note = baseNote,
|
||||
innerQuote = innerQuote,
|
||||
backgroundBubbleColor = backgroundBubbleColor,
|
||||
bgColor = bgColor,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
onWantsToReply = onWantsToReply,
|
||||
@ -268,31 +245,31 @@ private fun MessageBubbleLines(
|
||||
innerQuote = innerQuote,
|
||||
onWantsToReply = onWantsToReply,
|
||||
onWantsToEditDraft = onWantsToEditDraft,
|
||||
backgroundBubbleColor = backgroundBubbleColor,
|
||||
bgColor = bgColor,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RenderReplyRow(
|
||||
fun RenderReplyRow(
|
||||
note: Note,
|
||||
innerQuote: Boolean,
|
||||
backgroundBubbleColor: MutableState<Color>,
|
||||
bgColor: MutableState<Color>,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
onWantsToReply: (Note) -> Unit,
|
||||
onWantsToEditDraft: (Note) -> Unit,
|
||||
) {
|
||||
if (!innerQuote && note.replyTo?.lastOrNull() != null) {
|
||||
RenderReply(note, backgroundBubbleColor, accountViewModel, nav, onWantsToReply, onWantsToEditDraft)
|
||||
RenderReply(note, bgColor, accountViewModel, nav, onWantsToReply, onWantsToEditDraft)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RenderReply(
|
||||
note: Note,
|
||||
backgroundBubbleColor: MutableState<Color>,
|
||||
bgColor: MutableState<Color>,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
onWantsToReply: (Note) -> Unit,
|
||||
@ -312,7 +289,7 @@ private fun RenderReply(
|
||||
baseNote = note,
|
||||
routeForLastRead = null,
|
||||
innerQuote = true,
|
||||
parentBackgroundColor = backgroundBubbleColor,
|
||||
parentBackgroundColor = bgColor,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
onWantsToReply = onWantsToReply,
|
||||
@ -323,280 +300,23 @@ private fun RenderReply(
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun NoteRow(
|
||||
fun NoteRow(
|
||||
note: Note,
|
||||
canPreview: Boolean,
|
||||
innerQuote: Boolean,
|
||||
onWantsToReply: (Note) -> Unit,
|
||||
onWantsToEditDraft: (Note) -> Unit,
|
||||
backgroundBubbleColor: MutableState<Color>,
|
||||
bgColor: MutableState<Color>,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
when (note.event) {
|
||||
is ChannelCreateEvent -> RenderCreateChannelNote(note)
|
||||
is ChannelMetadataEvent -> RenderChangeChannelMetadataNote(note)
|
||||
is DraftEvent ->
|
||||
RenderDraftEvent(
|
||||
note,
|
||||
canPreview,
|
||||
innerQuote,
|
||||
onWantsToReply,
|
||||
onWantsToEditDraft,
|
||||
backgroundBubbleColor,
|
||||
accountViewModel,
|
||||
nav,
|
||||
)
|
||||
is ChatMessageEncryptedFileHeaderEvent ->
|
||||
RenderEncryptedFile(
|
||||
note,
|
||||
backgroundBubbleColor,
|
||||
accountViewModel,
|
||||
nav,
|
||||
)
|
||||
else ->
|
||||
RenderRegularTextNote(
|
||||
note,
|
||||
canPreview,
|
||||
innerQuote,
|
||||
backgroundBubbleColor,
|
||||
accountViewModel,
|
||||
nav,
|
||||
)
|
||||
is ChannelCreateEvent -> RenderCreateChannelNote(note, bgColor, accountViewModel, nav)
|
||||
is ChannelMetadataEvent -> RenderChangeChannelMetadataNote(note, bgColor, accountViewModel, nav)
|
||||
is DraftEvent -> RenderDraftEvent(note, canPreview, innerQuote, onWantsToReply, onWantsToEditDraft, bgColor, accountViewModel, nav)
|
||||
is ChatMessageEncryptedFileHeaderEvent -> RenderEncryptedFile(note, bgColor, accountViewModel, nav)
|
||||
else -> RenderRegularTextNote(note, canPreview, innerQuote, bgColor, accountViewModel, nav)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RenderDraftEvent(
|
||||
note: Note,
|
||||
canPreview: Boolean,
|
||||
innerQuote: Boolean,
|
||||
onWantsToReply: (Note) -> Unit,
|
||||
onWantsToEditDraft: (Note) -> Unit,
|
||||
backgroundBubbleColor: MutableState<Color>,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
ObserveDraftEvent(note, accountViewModel) {
|
||||
Column(verticalArrangement = RowColSpacing5dp) {
|
||||
RenderReplyRow(
|
||||
note = it,
|
||||
innerQuote = innerQuote,
|
||||
backgroundBubbleColor = backgroundBubbleColor,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
onWantsToReply = onWantsToReply,
|
||||
onWantsToEditDraft = onWantsToEditDraft,
|
||||
)
|
||||
|
||||
NoteRow(
|
||||
note = it,
|
||||
canPreview = canPreview,
|
||||
innerQuote = innerQuote,
|
||||
onWantsToReply = onWantsToReply,
|
||||
onWantsToEditDraft = onWantsToEditDraft,
|
||||
backgroundBubbleColor = backgroundBubbleColor,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun IncognitoBadge(baseNote: Note) {
|
||||
if (baseNote.event is NIP17Group) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.incognito),
|
||||
null,
|
||||
modifier = incognitoIconModifier,
|
||||
tint = MaterialTheme.colorScheme.placeholderText,
|
||||
)
|
||||
Spacer(modifier = StdHorzSpacer)
|
||||
} else if (baseNote.event is PrivateDmEvent) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.incognito_off),
|
||||
null,
|
||||
modifier = incognitoIconModifier,
|
||||
tint = MaterialTheme.colorScheme.placeholderText,
|
||||
)
|
||||
Spacer(modifier = StdHorzSpacer)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ChatTimeAgo(baseNote: Note) {
|
||||
val nowStr = stringRes(id = R.string.now)
|
||||
val time = remember(baseNote) { timeAgoShort(baseNote.createdAt() ?: 0, nowStr) }
|
||||
|
||||
Text(
|
||||
text = time,
|
||||
color = MaterialTheme.colorScheme.placeholderText,
|
||||
fontSize = Font12SP,
|
||||
maxLines = 1,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RenderRegularTextNote(
|
||||
note: Note,
|
||||
canPreview: Boolean,
|
||||
innerQuote: Boolean,
|
||||
backgroundBubbleColor: MutableState<Color>,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
LoadDecryptedContentOrNull(note = note, accountViewModel = accountViewModel) { eventContent ->
|
||||
if (eventContent != null) {
|
||||
SensitivityWarning(
|
||||
note = note,
|
||||
accountViewModel = accountViewModel,
|
||||
) {
|
||||
val tags = remember(note.event) { note.event?.tags?.toImmutableListOfLists() ?: EmptyTagList }
|
||||
|
||||
TranslatableRichTextViewer(
|
||||
content = eventContent,
|
||||
canPreview = canPreview,
|
||||
quotesLeft = if (innerQuote) 0 else 1,
|
||||
modifier = Modifier,
|
||||
tags = tags,
|
||||
backgroundColor = backgroundBubbleColor,
|
||||
id = note.idHex,
|
||||
callbackUri = note.toNostrUri(),
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
TranslatableRichTextViewer(
|
||||
content = stringRes(id = R.string.could_not_decrypt_the_message),
|
||||
canPreview = true,
|
||||
quotesLeft = 0,
|
||||
modifier = Modifier,
|
||||
tags = EmptyTagList,
|
||||
backgroundColor = backgroundBubbleColor,
|
||||
id = note.idHex,
|
||||
callbackUri = note.toNostrUri(),
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RenderChangeChannelMetadataNote(note: Note) {
|
||||
val noteEvent = note.event as? ChannelMetadataEvent ?: return
|
||||
|
||||
val channelInfo = noteEvent.channelInfo()
|
||||
val text =
|
||||
note.author?.toBestDisplayName().toString() +
|
||||
" ${stringRes(R.string.changed_chat_name_to)} '" +
|
||||
(channelInfo.name ?: "") +
|
||||
"', ${stringRes(R.string.description_to)} '" +
|
||||
(channelInfo.about ?: "") +
|
||||
"', ${stringRes(R.string.and_picture_to)} '" +
|
||||
(channelInfo.picture ?: "") +
|
||||
"'"
|
||||
|
||||
CreateTextWithEmoji(
|
||||
text = text,
|
||||
tags = note.author?.info?.tags,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RenderCreateChannelNote(note: Note) {
|
||||
val noteEvent = note.event as? ChannelCreateEvent ?: return
|
||||
val channelInfo = remember { noteEvent.channelInfo() }
|
||||
|
||||
val text =
|
||||
note.author?.toBestDisplayName().toString() +
|
||||
" ${stringRes(R.string.created)} " +
|
||||
(channelInfo.name ?: "") +
|
||||
" ${stringRes(R.string.with_description_of)} '" +
|
||||
(channelInfo.about ?: "") +
|
||||
"', ${stringRes(R.string.and_picture)} '" +
|
||||
(channelInfo.picture ?: "") +
|
||||
"'"
|
||||
|
||||
CreateTextWithEmoji(
|
||||
text = text,
|
||||
tags = note.author?.info?.tags,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DrawAuthorInfo(
|
||||
baseNote: Note,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
baseNote.author?.let {
|
||||
WatchAndDisplayUser(it, accountViewModel, nav)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun UserDisplayNameLayout(
|
||||
picture: @Composable () -> Unit,
|
||||
name: @Composable () -> Unit,
|
||||
) {
|
||||
Box(chatAuthorBox, contentAlignment = Alignment.TopEnd) {
|
||||
picture()
|
||||
}
|
||||
|
||||
Spacer(modifier = StdHorzSpacer)
|
||||
|
||||
name()
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun WatchAndDisplayUser(
|
||||
author: User,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val userState by author.live().userMetadataInfo.observeAsState()
|
||||
|
||||
UserDisplayNameLayout(
|
||||
picture = {
|
||||
InnerUserPicture(
|
||||
userHex = author.pubkeyHex,
|
||||
userPicture = userState?.picture,
|
||||
userName = userState?.bestName(),
|
||||
size = Size20dp,
|
||||
modifier = Modifier,
|
||||
accountViewModel = accountViewModel,
|
||||
)
|
||||
|
||||
WatchUserFollows(author.pubkeyHex, accountViewModel) { newFollowingState ->
|
||||
if (newFollowingState) {
|
||||
FollowingIcon(Size5Modifier)
|
||||
}
|
||||
}
|
||||
},
|
||||
name = {
|
||||
if (userState != null) {
|
||||
DisplayMessageUsername(userState?.bestName() ?: author.pubkeyDisplayHex(), userState?.tags ?: EmptyTagList)
|
||||
} else {
|
||||
DisplayMessageUsername(author.pubkeyDisplayHex(), EmptyTagList)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DisplayMessageUsername(
|
||||
userDisplayName: String,
|
||||
userTags: ImmutableListOfLists<String>,
|
||||
) {
|
||||
CreateTextWithEmoji(
|
||||
text = userDisplayName,
|
||||
tags = userTags,
|
||||
maxLines = 1,
|
||||
fontWeight = FontWeight.Bold,
|
||||
)
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed
|
||||
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.ui.note.timeAgoShort
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.Font12SP
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
|
||||
@Composable
|
||||
fun ChatTimeAgo(baseNote: Note) {
|
||||
val nowStr = stringRes(id = R.string.now)
|
||||
val time = remember(baseNote) { timeAgoShort(baseNote.createdAt() ?: 0, nowStr) }
|
||||
|
||||
Text(
|
||||
text = time,
|
||||
color = MaterialTheme.colorScheme.placeholderText,
|
||||
fontSize = Font12SP,
|
||||
maxLines = 1,
|
||||
)
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji
|
||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.note.FollowingIcon
|
||||
import com.vitorpamplona.amethyst.ui.note.InnerUserPicture
|
||||
import com.vitorpamplona.amethyst.ui.note.WatchUserFollows
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.layouts.UserDisplayNameLayout
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size20dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size5Modifier
|
||||
import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList
|
||||
|
||||
@Composable
|
||||
fun DrawAuthorInfo(
|
||||
baseNote: Note,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
baseNote.author?.let {
|
||||
WatchAndDisplayUser(it, accountViewModel, nav)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun WatchAndDisplayUser(
|
||||
author: User,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val userState by author.live().userMetadataInfo.observeAsState()
|
||||
|
||||
UserDisplayNameLayout(
|
||||
picture = {
|
||||
InnerUserPicture(
|
||||
userHex = author.pubkeyHex,
|
||||
userPicture = userState?.picture,
|
||||
userName = userState?.bestName(),
|
||||
size = Size20dp,
|
||||
modifier = Modifier,
|
||||
accountViewModel = accountViewModel,
|
||||
)
|
||||
|
||||
WatchUserFollows(author.pubkeyHex, accountViewModel) { newFollowingState ->
|
||||
if (newFollowingState) {
|
||||
FollowingIcon(Size5Modifier)
|
||||
}
|
||||
}
|
||||
},
|
||||
name = {
|
||||
if (userState != null) {
|
||||
CreateTextWithEmoji(
|
||||
text = userState?.bestName() ?: author.pubkeyDisplayHex(),
|
||||
tags = userState?.tags ?: EmptyTagList,
|
||||
maxLines = 1,
|
||||
fontWeight = FontWeight.Bold,
|
||||
)
|
||||
} else {
|
||||
CreateTextWithEmoji(
|
||||
text = author.pubkeyDisplayHex(),
|
||||
tags = EmptyTagList,
|
||||
maxLines = 1,
|
||||
fontWeight = FontWeight.Bold,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.ui.note.dateFormatter
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.layouts.ChatDivisor
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.quartz.nip14Subject.subject
|
||||
|
||||
@Composable
|
||||
fun NewDateOrSubjectDivisor(
|
||||
previous: Note?,
|
||||
note: Note,
|
||||
) {
|
||||
if (previous == null) return
|
||||
|
||||
val never = stringRes(R.string.never)
|
||||
val today = stringRes(R.string.today)
|
||||
|
||||
val prevDate = remember(previous) { dateFormatter(previous.event?.createdAt, never, today) }
|
||||
val date = remember(note) { dateFormatter(note.event?.createdAt, never, today) }
|
||||
|
||||
val subject = remember(note) { note.event?.subject() }
|
||||
|
||||
if (prevDate != date) {
|
||||
if (subject != null) {
|
||||
ChatDivisor("$date - $subject")
|
||||
} else {
|
||||
ChatDivisor(date)
|
||||
}
|
||||
} else {
|
||||
if (subject != null) {
|
||||
ChatDivisor(subject)
|
||||
}
|
||||
}
|
||||
}
|
@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.messages
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.layouts
|
||||
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.background
|
||||
@ -82,7 +82,7 @@ fun ChatBubbleLayout(
|
||||
val defaultBackground = MaterialTheme.colorScheme.background
|
||||
val draftColor = MaterialTheme.colorScheme.chatDraftBackground
|
||||
|
||||
val backgroundBubbleColor =
|
||||
val bgColor =
|
||||
remember {
|
||||
if (isLoggedInUser) {
|
||||
if (isDraft) {
|
||||
@ -135,7 +135,7 @@ fun ChatBubbleLayout(
|
||||
modifier = if (innerQuote) Modifier else ChatBubbleMaxSizeModifier,
|
||||
) {
|
||||
Surface(
|
||||
color = backgroundBubbleColor.value,
|
||||
color = bgColor.value,
|
||||
shape = if (isLoggedInUser) ChatBubbleShapeMe else ChatBubbleShapeThem,
|
||||
modifier = clickableModifier,
|
||||
) {
|
||||
@ -150,7 +150,7 @@ fun ChatBubbleLayout(
|
||||
}
|
||||
}
|
||||
|
||||
inner(backgroundBubbleColor)
|
||||
inner(bgColor)
|
||||
|
||||
if (showDetails.value) {
|
||||
Row(
|
||||
@ -175,7 +175,7 @@ fun ChatBubbleLayout(
|
||||
@Preview
|
||||
@Composable
|
||||
private fun BubblePreview() {
|
||||
val backgroundBubbleColor =
|
||||
val bgColor =
|
||||
remember {
|
||||
mutableStateOf<Color>(Color.Transparent)
|
||||
}
|
||||
@ -188,7 +188,7 @@ private fun BubblePreview() {
|
||||
isComplete = true,
|
||||
hasDetailsToShow = true,
|
||||
drawAuthorInfo = true,
|
||||
parentBackgroundColor = backgroundBubbleColor,
|
||||
parentBackgroundColor = bgColor,
|
||||
onClick = { false },
|
||||
onAuthorClick = {},
|
||||
actionMenu = { onDismiss ->
|
||||
@ -212,7 +212,7 @@ private fun BubblePreview() {
|
||||
)
|
||||
},
|
||||
detailRow = { Text("Relays and Actions") },
|
||||
) { backgroundBubbleColor ->
|
||||
) { bgColor ->
|
||||
Text("This is my note")
|
||||
}
|
||||
|
||||
@ -223,7 +223,7 @@ private fun BubblePreview() {
|
||||
isComplete = true,
|
||||
hasDetailsToShow = true,
|
||||
drawAuthorInfo = true,
|
||||
parentBackgroundColor = backgroundBubbleColor,
|
||||
parentBackgroundColor = bgColor,
|
||||
onClick = { false },
|
||||
onAuthorClick = {},
|
||||
actionMenu = { onDismiss ->
|
||||
@ -246,7 +246,7 @@ private fun BubblePreview() {
|
||||
)
|
||||
},
|
||||
detailRow = { Text("Relays and Actions") },
|
||||
) { backgroundBubbleColor ->
|
||||
) { bgColor ->
|
||||
Text("This is a very long long loong note")
|
||||
}
|
||||
|
||||
@ -257,7 +257,7 @@ private fun BubblePreview() {
|
||||
isComplete = true,
|
||||
hasDetailsToShow = true,
|
||||
drawAuthorInfo = true,
|
||||
parentBackgroundColor = backgroundBubbleColor,
|
||||
parentBackgroundColor = bgColor,
|
||||
onClick = { false },
|
||||
onAuthorClick = {},
|
||||
actionMenu = { onDismiss ->
|
||||
@ -280,7 +280,7 @@ private fun BubblePreview() {
|
||||
)
|
||||
},
|
||||
detailRow = { Text("Relays and Actions") },
|
||||
) { backgroundBubbleColor ->
|
||||
) { bgColor ->
|
||||
Text("This is a draft note")
|
||||
}
|
||||
|
||||
@ -291,7 +291,7 @@ private fun BubblePreview() {
|
||||
isComplete = false,
|
||||
hasDetailsToShow = false,
|
||||
drawAuthorInfo = false,
|
||||
parentBackgroundColor = backgroundBubbleColor,
|
||||
parentBackgroundColor = bgColor,
|
||||
onClick = { false },
|
||||
onAuthorClick = {},
|
||||
actionMenu = { onDismiss ->
|
||||
@ -314,7 +314,7 @@ private fun BubblePreview() {
|
||||
)
|
||||
},
|
||||
detailRow = { Text("Relays and Actions") },
|
||||
) { backgroundBubbleColor ->
|
||||
) { bgColor ->
|
||||
Text("Short note")
|
||||
}
|
||||
}
|
@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.feed
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.layouts
|
||||
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.material3.HorizontalDivider
|
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.layouts
|
||||
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.chatAuthorBox
|
||||
|
||||
@Composable
|
||||
fun UserDisplayNameLayout(
|
||||
picture: @Composable () -> Unit,
|
||||
name: @Composable () -> Unit,
|
||||
) {
|
||||
Box(chatAuthorBox, contentAlignment = Alignment.TopEnd) {
|
||||
picture()
|
||||
}
|
||||
|
||||
Spacer(modifier = StdHorzSpacer)
|
||||
|
||||
name()
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.types
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer
|
||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelMetadataEvent
|
||||
|
||||
@Composable
|
||||
fun RenderChangeChannelMetadataNote(
|
||||
note: Note,
|
||||
bgColor: MutableState<Color>,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val noteEvent = note.event as? ChannelMetadataEvent ?: return
|
||||
|
||||
val channelInfo = noteEvent.channelInfo()
|
||||
val text =
|
||||
note.author?.toBestDisplayName().toString() +
|
||||
" ${stringRes(R.string.changed_chat_name_to)} '" +
|
||||
(channelInfo.name ?: "") +
|
||||
"', ${stringRes(R.string.description_to)} '" +
|
||||
(channelInfo.about ?: "") +
|
||||
"' ${stringRes(R.string.and_picture_to)} " +
|
||||
(channelInfo.picture ?: "")
|
||||
|
||||
TranslatableRichTextViewer(
|
||||
content = text,
|
||||
canPreview = true,
|
||||
quotesLeft = 0,
|
||||
modifier = Modifier,
|
||||
tags = note.author?.info?.tags ?: EmptyTagList,
|
||||
backgroundColor = bgColor,
|
||||
id = note.idHex,
|
||||
callbackUri = note.toNostrUri(),
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.types
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer
|
||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||
|
||||
@Composable
|
||||
fun RenderCreateChannelNote(
|
||||
note: Note,
|
||||
bgColor: MutableState<Color>,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val noteEvent = note.event as? ChannelCreateEvent ?: return
|
||||
val channelInfo = remember { noteEvent.channelInfo() }
|
||||
|
||||
val text =
|
||||
note.author?.toBestDisplayName().toString() +
|
||||
" ${stringRes(R.string.created)} " +
|
||||
(channelInfo.name ?: "") +
|
||||
" ${stringRes(R.string.with_description_of)} '" +
|
||||
(channelInfo.about ?: "") +
|
||||
"' ${stringRes(R.string.and_picture_to)} " +
|
||||
(channelInfo.picture ?: "")
|
||||
|
||||
TranslatableRichTextViewer(
|
||||
content = text,
|
||||
canPreview = true,
|
||||
quotesLeft = 0,
|
||||
modifier = Modifier,
|
||||
tags = note.author?.info?.tags ?: EmptyTagList,
|
||||
backgroundColor = bgColor,
|
||||
id = note.idHex,
|
||||
callbackUri = note.toNostrUri(),
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.types
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.note.ObserveDraftEvent
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.NoteRow
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.RenderReplyRow
|
||||
import com.vitorpamplona.amethyst.ui.theme.RowColSpacing5dp
|
||||
|
||||
@Composable
|
||||
fun RenderDraftEvent(
|
||||
note: Note,
|
||||
canPreview: Boolean,
|
||||
innerQuote: Boolean,
|
||||
onWantsToReply: (Note) -> Unit,
|
||||
onWantsToEditDraft: (Note) -> Unit,
|
||||
backgroundBubbleColor: MutableState<Color>,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
ObserveDraftEvent(note, accountViewModel) {
|
||||
Column(verticalArrangement = RowColSpacing5dp) {
|
||||
RenderReplyRow(
|
||||
note = it,
|
||||
innerQuote = innerQuote,
|
||||
bgColor = backgroundBubbleColor,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
onWantsToReply = onWantsToReply,
|
||||
onWantsToEditDraft = onWantsToEditDraft,
|
||||
)
|
||||
|
||||
NoteRow(
|
||||
note = it,
|
||||
canPreview = canPreview,
|
||||
innerQuote = innerQuote,
|
||||
onWantsToReply = onWantsToReply,
|
||||
onWantsToEditDraft = onWantsToEditDraft,
|
||||
bgColor = backgroundBubbleColor,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,122 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.types
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.richtext.BaseMediaContent
|
||||
import com.vitorpamplona.amethyst.commons.richtext.EncryptedMediaUrlImage
|
||||
import com.vitorpamplona.amethyst.commons.richtext.EncryptedMediaUrlVideo
|
||||
import com.vitorpamplona.amethyst.commons.richtext.RichTextParser
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.service.okhttp.HttpClientManager
|
||||
import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer
|
||||
import com.vitorpamplona.amethyst.ui.components.ZoomableContentView
|
||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList
|
||||
import com.vitorpamplona.quartz.nip17Dm.files.ChatMessageEncryptedFileHeaderEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.files.encryption.AESGCM
|
||||
import com.vitorpamplona.quartz.nip31Alts.alt
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
@Composable
|
||||
fun RenderEncryptedFile(
|
||||
note: Note,
|
||||
bgColor: MutableState<Color>,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val noteEvent = note.event as? ChatMessageEncryptedFileHeaderEvent ?: return
|
||||
|
||||
val algo = noteEvent.algo()
|
||||
val key = noteEvent.key()
|
||||
val nonce = noteEvent.nonce()
|
||||
val mimeType = noteEvent.mimeType()
|
||||
|
||||
if (algo == AESGCM.NAME && key != null && nonce != null) {
|
||||
HttpClientManager.addCipherToCache(noteEvent.content, AESGCM(key, nonce), mimeType)
|
||||
|
||||
val content by remember(noteEvent) {
|
||||
val isImage = mimeType?.startsWith("image/") == true || RichTextParser.isImageUrl(noteEvent.content)
|
||||
|
||||
mutableStateOf<BaseMediaContent>(
|
||||
if (isImage) {
|
||||
EncryptedMediaUrlImage(
|
||||
url = noteEvent.content,
|
||||
description = noteEvent.alt(),
|
||||
hash = noteEvent.originalHash(),
|
||||
blurhash = noteEvent.blurhash(),
|
||||
dim = noteEvent.dimensions(),
|
||||
uri = note.toNostrUri(),
|
||||
mimeType = mimeType,
|
||||
encryptionAlgo = algo,
|
||||
encryptionKey = key,
|
||||
encryptionNonce = nonce,
|
||||
)
|
||||
} else {
|
||||
EncryptedMediaUrlVideo(
|
||||
url = noteEvent.content,
|
||||
description = noteEvent.alt(),
|
||||
hash = noteEvent.originalHash(),
|
||||
blurhash = noteEvent.blurhash(),
|
||||
dim = noteEvent.dimensions(),
|
||||
uri = note.toNostrUri(),
|
||||
authorName = note.author?.toBestDisplayName(),
|
||||
mimeType = mimeType,
|
||||
encryptionAlgo = algo,
|
||||
encryptionKey = key,
|
||||
encryptionNonce = nonce,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
ZoomableContentView(
|
||||
content,
|
||||
persistentListOf(content),
|
||||
roundedCorner = true,
|
||||
contentScale = ContentScale.FillWidth,
|
||||
accountViewModel,
|
||||
)
|
||||
} else {
|
||||
TranslatableRichTextViewer(
|
||||
content = stringRes(id = R.string.could_not_decrypt_the_message),
|
||||
canPreview = true,
|
||||
quotesLeft = 0,
|
||||
modifier = Modifier,
|
||||
tags = EmptyTagList,
|
||||
backgroundColor = bgColor,
|
||||
id = note.idHex,
|
||||
callbackUri = note.toNostrUri(),
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.types
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.ui.components.SensitivityWarning
|
||||
import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer
|
||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.note.LoadDecryptedContentOrNull
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList
|
||||
import com.vitorpamplona.quartz.nip02FollowList.toImmutableListOfLists
|
||||
|
||||
@Composable
|
||||
fun RenderRegularTextNote(
|
||||
note: Note,
|
||||
canPreview: Boolean,
|
||||
innerQuote: Boolean,
|
||||
bgColor: MutableState<Color>,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
LoadDecryptedContentOrNull(note = note, accountViewModel = accountViewModel) { eventContent ->
|
||||
if (eventContent != null) {
|
||||
SensitivityWarning(
|
||||
note = note,
|
||||
accountViewModel = accountViewModel,
|
||||
) {
|
||||
val tags = remember(note.event) { note.event?.tags?.toImmutableListOfLists() ?: EmptyTagList }
|
||||
|
||||
TranslatableRichTextViewer(
|
||||
content = eventContent,
|
||||
canPreview = canPreview,
|
||||
quotesLeft = if (innerQuote) 0 else 1,
|
||||
modifier = Modifier,
|
||||
tags = tags,
|
||||
backgroundColor = bgColor,
|
||||
id = note.idHex,
|
||||
callbackUri = note.toNostrUri(),
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
TranslatableRichTextViewer(
|
||||
content = stringRes(id = R.string.could_not_decrypt_the_message),
|
||||
canPreview = true,
|
||||
quotesLeft = 0,
|
||||
modifier = Modifier,
|
||||
tags = EmptyTagList,
|
||||
backgroundColor = bgColor,
|
||||
id = note.idHex,
|
||||
callbackUri = note.toNostrUri(),
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -41,7 +41,7 @@ import com.vitorpamplona.amethyst.ui.note.elements.ObserveRelayListForDMs
|
||||
import com.vitorpamplona.amethyst.ui.note.elements.ObserveRelayListForDMsAndDisplayIfNotFound
|
||||
import com.vitorpamplona.amethyst.ui.screen.NostrChatroomFeedViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.feed.RefreshingChatroomFeedView
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.RefreshingChatroomFeedView
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.send.ChatNewMessageViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.send.PrivateMessageEditFieldRow
|
||||
import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer
|
||||
|
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM
|
||||
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.incognitoIconModifier
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.PrivateDmEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.NIP17Group
|
||||
|
||||
@Composable
|
||||
fun IncognitoBadge(baseNote: Note) {
|
||||
if (baseNote.event is NIP17Group) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.incognito),
|
||||
null,
|
||||
modifier = incognitoIconModifier,
|
||||
tint = MaterialTheme.colorScheme.placeholderText,
|
||||
)
|
||||
Spacer(modifier = StdHorzSpacer)
|
||||
} else if (baseNote.event is PrivateDmEvent) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.incognito_off),
|
||||
null,
|
||||
modifier = incognitoIconModifier,
|
||||
tint = MaterialTheme.colorScheme.placeholderText,
|
||||
)
|
||||
Spacer(modifier = StdHorzSpacer)
|
||||
}
|
||||
}
|
@ -36,7 +36,7 @@ import com.vitorpamplona.amethyst.ui.note.ClickableUserPicture
|
||||
import com.vitorpamplona.amethyst.ui.note.NonClickableUserPictures
|
||||
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.LoadUser
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.LoadUser
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size34dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdPadding
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
|
||||
|
@ -55,7 +55,7 @@ import com.vitorpamplona.amethyst.ui.note.NonClickableUserPictures
|
||||
import com.vitorpamplona.amethyst.ui.note.UserCompose
|
||||
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.LoadUser
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.LoadUser
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
||||
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
|
||||
|
@ -36,7 +36,7 @@ import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled
|
||||
import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji
|
||||
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.LoadUser
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.LoadUser
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
|
||||
import kotlin.math.min
|
||||
|
@ -42,7 +42,7 @@ import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.note.LoadChannel
|
||||
import com.vitorpamplona.amethyst.ui.screen.NostrChannelFeedViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.feed.RefreshingChatroomFeedView
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.RefreshingChatroomFeedView
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.nip53LiveActivities.ShowVideoStreaming
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.send.ChannelNewMessageViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.send.EditFieldRow
|
||||
|
@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms
|
||||
|
||||
import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
|
||||
import androidx.compose.runtime.Composable
|
||||
@ -27,8 +27,8 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.singlepane.MessagesSinglePane
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.twopane.MessagesTwoPane
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.singlepane.MessagesSinglePane
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.twopane.MessagesTwoPane
|
||||
|
||||
@Composable
|
||||
fun MessagesScreen(
|
@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.feed
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.feed
|
||||
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.layout.Row
|
||||
@ -42,7 +42,7 @@ import com.vitorpamplona.amethyst.ui.feeds.LoadingFeed
|
||||
import com.vitorpamplona.amethyst.ui.feeds.RefresheableBox
|
||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.ChatroomHeaderCompose
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.ChatroomHeaderCompose
|
||||
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||
|
@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.feed
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.feed
|
||||
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.singlepane
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.singlepane
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
@ -35,12 +35,12 @@ import com.vitorpamplona.amethyst.ui.navigation.MainTopBar
|
||||
import com.vitorpamplona.amethyst.ui.navigation.Route
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.DisappearingScaffold
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.ChannelFabColumn
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.WatchAccountForListScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.WatchLifecycleAndRefreshDataSource
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.feed.MessagesPager
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.feed.MessagesTabHeader
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.feed.MessagesTabItem
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.ChannelFabColumn
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.WatchAccountForListScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.WatchLifecycleAndRefreshDataSource
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.feed.MessagesPager
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.feed.MessagesTabHeader
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.feed.MessagesTabItem
|
||||
|
||||
@Composable
|
||||
fun MessagesSinglePane(
|
@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.twopane
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.twopane
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
@ -33,11 +33,11 @@ import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.ui.feeds.FeedContentState
|
||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.WatchAccountForListScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.WatchLifecycleAndRefreshDataSource
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.feed.MessagesPager
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.feed.MessagesTabHeader
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.feed.MessagesTabItem
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.WatchAccountForListScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.WatchLifecycleAndRefreshDataSource
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.feed.MessagesPager
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.feed.MessagesTabHeader
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.feed.MessagesTabItem
|
||||
|
||||
@Composable
|
||||
fun ChatroomList(
|
@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.twopane
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.twopane
|
||||
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@ -42,9 +42,9 @@ import com.vitorpamplona.amethyst.ui.navigation.MainTopBar
|
||||
import com.vitorpamplona.amethyst.ui.navigation.Route
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.DisappearingScaffold
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.ChannelFabColumn
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.Chatroom
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.ChannelView
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.ChannelFabColumn
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size20dp
|
||||
|
||||
@Composable
|
@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.twopane
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.twopane
|
||||
|
||||
import androidx.compose.material3.DrawerState
|
||||
import androidx.compose.runtime.mutableStateOf
|
@ -39,7 +39,7 @@ import androidx.compose.ui.unit.dp
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.messages.ChatroomMessageCompose
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.ChatroomMessageCompose
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size20Modifier
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
|
||||
|
@ -75,7 +75,7 @@ import com.vitorpamplona.amethyst.ui.note.UserCompose
|
||||
import com.vitorpamplona.amethyst.ui.note.elements.ObserveRelayListForSearchAndDisplayIfNotFound
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.DisappearingScaffold
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.list.ChannelName
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.ChannelName
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||
|
Loading…
x
Reference in New Issue
Block a user