diff --git a/plugins/space/src/main/kotlin/com/intellij/space/chat/SpaceChatItem.kt b/plugins/space/src/main/kotlin/com/intellij/space/chat/SpaceChatItem.kt new file mode 100644 index 000000000000..f4fda3fdafff --- /dev/null +++ b/plugins/space/src/main/kotlin/com/intellij/space/chat/SpaceChatItem.kt @@ -0,0 +1,20 @@ +package com.intellij.space.chat + +import circlet.client.api.CPrincipal +import circlet.client.api.ChannelItemRecord +import circlet.client.api.M2ChannelRecord +import circlet.client.api.M2ItemContentDetails +import circlet.platform.api.Ref +import com.intellij.openapi.util.NlsSafe +import com.intellij.util.ui.codereview.timeline.TimelineItem + +class SpaceChatItem(record: ChannelItemRecord) : TimelineItem { + val author: CPrincipal = record.author + val created: circlet.platform.api.KDateTime = record.created + val details: M2ItemContentDetails? = record.details + + @NlsSafe + val text: String = record.text + + val thread: Ref? = record.thread +} \ No newline at end of file diff --git a/plugins/space/src/main/kotlin/com/intellij/space/chat/SpaceChatPanel.kt b/plugins/space/src/main/kotlin/com/intellij/space/chat/SpaceChatPanel.kt index 449e6feb56d8..26d05cdeecc4 100644 --- a/plugins/space/src/main/kotlin/com/intellij/space/chat/SpaceChatPanel.kt +++ b/plugins/space/src/main/kotlin/com/intellij/space/chat/SpaceChatPanel.kt @@ -93,34 +93,34 @@ internal fun createSpaceChatPanel( val avatarProvider = SpaceAvatarProvider(lifetime, timeline, avatarSize) val server = channelsVm.client.server val items = messages.value.messages.mapNotNull { messageViewModel -> - val message = messageViewModel.message - val details = message.details ?: throw IllegalStateException() + val chatItem = SpaceChatItem(messageViewModel.message) + val details = chatItem.details ?: return@mapNotNull null when (details) { is CodeDiscussionAddedFeedEvent -> { val discussion = details.codeDiscussion.resolve() val codeDiscussionChat = channelsVm.channel(lifetime, discussion.channel, mode = M2ChannelMode.CodeDiscussion()) codeDiscussionChat.awaitFullLoad(lifetime) - val codeDiscussionMessages = codeDiscussionChat.mvms.prop.value.messages.map { it.message } + val codeDiscussionMessages = codeDiscussionChat.mvms.prop.value.messages.map { SpaceChatItem(it.message) } createDiff(project, discussion, codeDiscussionMessages.first(), server) ?.withThread(lifetime, server, codeDiscussionMessages.drop(1)) } is M2TextItemContent -> { - val messagePanel = createSimpleMessagePanel(message, server) - val thread = message.thread + val messagePanel = createSimpleMessagePanel(chatItem, server) + val thread = chatItem.thread if (thread == null) { messagePanel } else { val threadChat = channelsVm.channel(lifetime, thread) threadChat.awaitFullLoad(lifetime) - messagePanel.withThread(lifetime, server, threadChat.mvms.value.messages.map { it.message }) + messagePanel.withThread(lifetime, server, threadChat.mvms.value.messages.map { SpaceChatItem(it.message) }) } } else -> createUnsupportedMessageTypePanel(messageViewModel.getLink(server)) }?.let { component -> Item( - message.author.asUser?.let { user -> avatarProvider.getIcon(user) } ?: resizeIcon(SpaceIcons.Main, avatarSize.get()), - createMessageTitle(server, message), + chatItem.author.asUser?.let { user -> avatarProvider.getIcon(user) } ?: resizeIcon(SpaceIcons.Main, avatarSize.get()), + createMessageTitle(server, chatItem), component ) } @@ -165,7 +165,7 @@ private fun createUnsupportedMessageTypePanel(messageLink: String?): JComponent return JBLabel(description, AllIcons.General.Warning, SwingConstants.LEFT).setCopyable(true) } -private fun createMessageTitle(server: String, message: ChannelItemRecord): JComponent { +private fun createMessageTitle(server: String, message: SpaceChatItem): JComponent { val authorPanel = HtmlEditorPane().apply { setBody(createMessageAuthorChunk(message.author, server).bold().toString()) } @@ -196,7 +196,7 @@ private fun createMessageAuthorChunk(author: CPrincipal, server: String): HtmlCh } } -private fun JComponent.withThread(lifetime: Lifetime, server: String, messages: List): JComponent { +private fun JComponent.withThread(lifetime: Lifetime, server: String, messages: List): JComponent { return JPanel(VerticalLayout(JBUI.scale(10))).also { panel -> panel.isOpaque = false val threadAvatarsProvider = SpaceAvatarProvider(lifetime, panel, JBValue.UIInteger("space.chat.thread.avatar.size", 20)) @@ -217,7 +217,7 @@ private fun JComponent.withThread(lifetime: Lifetime, server: String, messages: private fun createDiff( project: Project, discussion: CodeDiscussionRecord, - comment: ChannelItemRecord, + comment: SpaceChatItem, server: String ): JComponent? { val fileNameComponent = JBUI.Panels.simplePanel(createFileNameComponent(discussion.anchor.filename!!)).apply { @@ -264,7 +264,7 @@ private fun createFileNameComponent(filePath: String): JComponent { } } -private fun createSimpleMessagePanel(message: ChannelItemRecord, server: String) = HtmlEditorPane().apply { +private fun createSimpleMessagePanel(message: SpaceChatItem, server: String) = HtmlEditorPane().apply { setBody(MentionConverter.html(message.text, server)) }