mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[gitlab] IJPL-82619: images uploaded by "/uploads/*" links are rendered in MR notes
* images are rendered in MR timeline entries, diff comments and editor comments (in review mode) GitOrigin-RevId: e45fa4c7de0436133dcb2dcab020e922d6e5cc95
This commit is contained in:
committed by
intellij-monorepo-bot
parent
fdd225e48e
commit
fabbe79d14
+3
-2
@@ -36,8 +36,9 @@ class GitLabProjectConnection(
|
||||
|
||||
val tokenRefreshFlow: Flow<Unit> = tokenState.drop(1).map { }
|
||||
|
||||
val projectData: GitLabProject = GitLabLazyProject(project, scope, apiClient, glMetadata, repo, glProject, currentUser, tokenRefreshFlow)
|
||||
val imageLoader: GitLabImageLoader = GitLabImageLoader(apiClient, repo.repository.serverPath)
|
||||
val imageLoader: GitLabImageLoader = GitLabImageLoader(apiClient, repo.repository)
|
||||
|
||||
val projectData: GitLabProject = GitLabLazyProject(project, scope, apiClient, glMetadata, repo, glProject, currentUser, tokenRefreshFlow, imageLoader)
|
||||
|
||||
val serverVersion: GitLabVersion? = glMetadata?.version
|
||||
|
||||
|
||||
+6
@@ -9,6 +9,7 @@ import org.jetbrains.plugins.gitlab.api.dto.GitLabUserDTO
|
||||
import org.jetbrains.plugins.gitlab.api.dto.GitLabUserRestDTO
|
||||
import org.jetbrains.plugins.gitlab.util.GitLabApiRequestName
|
||||
import java.awt.Image
|
||||
import java.net.URI
|
||||
import java.net.http.HttpResponse
|
||||
|
||||
@SinceGitLab("7.0", note = "No exact version")
|
||||
@@ -33,3 +34,8 @@ suspend fun GitLabApi.loadImage(uri: String): Image {
|
||||
val request = request(uri).GET().build()
|
||||
return loadImage(request).body()
|
||||
}
|
||||
|
||||
suspend fun GitLabApi.loadImage(uri: URI): Image {
|
||||
val request = request(uri).GET().build()
|
||||
return loadImage(request).body()
|
||||
}
|
||||
|
||||
+28
-14
@@ -2,15 +2,20 @@
|
||||
package org.jetbrains.plugins.gitlab.data
|
||||
|
||||
import com.intellij.collaboration.ui.icon.AsyncImageIconsProvider
|
||||
import com.intellij.collaboration.ui.html.AsyncHtmlImageLoader
|
||||
import com.intellij.collaboration.util.resolveRelative
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.util.IconUtil
|
||||
import com.intellij.util.ui.ImageUtil
|
||||
import icons.CollaborationToolsIcons
|
||||
import org.jetbrains.plugins.gitlab.api.GitLabApi
|
||||
import org.jetbrains.plugins.gitlab.api.GitLabServerPath
|
||||
import org.jetbrains.plugins.gitlab.api.GitLabProjectCoordinates
|
||||
import org.jetbrains.plugins.gitlab.api.dto.GitLabUserDTO
|
||||
import org.jetbrains.plugins.gitlab.api.request.loadImage
|
||||
import org.jetbrains.plugins.gitlab.api.restApiUri
|
||||
import java.awt.Image
|
||||
import java.net.URI
|
||||
import java.net.URL
|
||||
import javax.swing.Icon
|
||||
import kotlin.coroutines.cancellation.CancellationException
|
||||
|
||||
@@ -20,25 +25,34 @@ private const val LOADED_GRAVATAR_SIZE: Int = 80
|
||||
|
||||
class GitLabImageLoader(
|
||||
private val apiClient: GitLabApi,
|
||||
private val server: GitLabServerPath
|
||||
) : AsyncImageIconsProvider.AsyncImageLoader<GitLabUserDTO> {
|
||||
private val gitLabProjectCoordinates: GitLabProjectCoordinates
|
||||
) : AsyncImageIconsProvider.AsyncImageLoader<GitLabUserDTO>, AsyncHtmlImageLoader {
|
||||
override suspend fun load(key: GitLabUserDTO): Image? {
|
||||
return key.avatarUrl?.let { avatarUrl ->
|
||||
val actualUri = when {
|
||||
avatarUrl.startsWith("http") -> avatarUrl
|
||||
avatarUrl.startsWith("/avatar") -> "https://secure.gravatar.com$avatarUrl?s=$LOADED_GRAVATAR_SIZE&d=identicon"
|
||||
else -> server.uri + avatarUrl
|
||||
else -> gitLabProjectCoordinates.serverPath.uri + avatarUrl
|
||||
}
|
||||
try {
|
||||
apiClient.loadImage(actualUri)
|
||||
}
|
||||
catch (ce: CancellationException) {
|
||||
throw ce
|
||||
}
|
||||
catch (e: Exception) {
|
||||
LOG.warn("Failed to load the avatar image from avatarUrl $avatarUrl with actual URI $actualUri", e)
|
||||
throw e
|
||||
load(null, actualUri)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun load(baseUrl: URL?, src: String): Image? {
|
||||
try {
|
||||
if (src.startsWith("/uploads/")) {
|
||||
val uriString = gitLabProjectCoordinates.restApiUri.resolveRelative(src.trimStart('/')).toString()
|
||||
return apiClient.loadImage(uriString)
|
||||
}
|
||||
val uri = URI.create(src)
|
||||
return apiClient.loadImage(uri)
|
||||
}
|
||||
catch (ce: CancellationException) {
|
||||
throw ce
|
||||
}
|
||||
catch (e: Exception) {
|
||||
LOG.warn("Failed to load the image from src $src", e)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,4 +63,4 @@ class GitLabImageLoader(
|
||||
override suspend fun postProcess(image: Image): Image {
|
||||
return ImageUtil.createCircleImage(ImageUtil.toBufferedImage(image))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-2
@@ -17,6 +17,7 @@ import org.jetbrains.plugins.gitlab.api.dto.GitLabUserDTO
|
||||
import org.jetbrains.plugins.gitlab.api.dto.GitLabWorkItemDTO.GitLabWidgetDTO.WorkItemWidgetAssignees
|
||||
import org.jetbrains.plugins.gitlab.api.dto.GitLabWorkItemDTO.WorkItemType
|
||||
import org.jetbrains.plugins.gitlab.api.request.*
|
||||
import org.jetbrains.plugins.gitlab.data.GitLabImageLoader
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.api.dto.GitLabMergeRequestDTO
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.api.request.loadMergeRequest
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.api.request.mergeRequestSetReviewers
|
||||
@@ -67,6 +68,7 @@ class GitLabLazyProject(
|
||||
private val initialData: GitLabProjectDTO,
|
||||
private val currentUser: GitLabUserDTO,
|
||||
private val tokenRefreshFlow: Flow<Unit>,
|
||||
imageLoader: GitLabImageLoader
|
||||
) : GitLabProject {
|
||||
|
||||
private val cs = parentCs.childScope(javaClass.name)
|
||||
@@ -84,9 +86,9 @@ class GitLabLazyProject(
|
||||
}
|
||||
override val gitLabProjectId: GitLabId = initialData.id
|
||||
|
||||
val uploadFileUrlBase: String = projectMapping.repository.serverPath.toString() + "/-/project/" + gitLabProjectId.guessRestId() + "/uploads/"
|
||||
private val uploadFileUrlBase: String = projectMapping.repository.serverPath.toString() + "/-/project/" + gitLabProjectId.guessRestId() + "/uploads/"
|
||||
|
||||
override val contextDataLoader: GitLabContextDataLoader = GitLabContextDataLoader(uploadFileUrlBase)
|
||||
override val contextDataLoader: GitLabContextDataLoader = GitLabContextDataLoader(imageLoader, uploadFileUrlBase)
|
||||
|
||||
override val mergeRequests by lazy {
|
||||
CachingGitLabProjectMergeRequestsStore(project, cs, api, glMetadata, projectMapping, currentUser, tokenRefreshFlow)
|
||||
|
||||
+5
-3
@@ -32,6 +32,7 @@ import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jetbrains.plugins.gitlab.GitLabSettings
|
||||
import org.jetbrains.plugins.gitlab.api.dto.GitLabUserDTO
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.GitLabContextDataLoader
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.diff.GitLabMergeRequestDiffDiscussionViewModel
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.diff.GitLabMergeRequestDiffDraftNoteViewModel
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.diff.GitLabMergeRequestDiffNewDiscussionViewModel
|
||||
@@ -84,7 +85,7 @@ class GitLabMergeRequestDiffExtension : DiffExtension() {
|
||||
UnifiedCodeReviewItemPosition(change, leftLine, rightLine)
|
||||
}
|
||||
},
|
||||
rendererFactory = { createRenderer(it, changeVm.avatarIconsProvider) }
|
||||
rendererFactory = { createRenderer(it, changeVm.avatarIconsProvider, changeVm.contextDataLoader) }
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -94,13 +95,14 @@ class GitLabMergeRequestDiffExtension : DiffExtension() {
|
||||
private fun CoroutineScope.createRenderer(
|
||||
model: GitLabMergeRequestEditorMappedComponentModel,
|
||||
avatarIconsProvider: IconsProvider<GitLabUserDTO>,
|
||||
contextDataLoader: GitLabContextDataLoader,
|
||||
): CodeReviewComponentInlayRenderer =
|
||||
when (model) {
|
||||
is GitLabMergeRequestEditorMappedComponentModel.Discussion<*> ->
|
||||
GitLabMergeRequestDiscussionInlayRenderer(this, project, model.vm, avatarIconsProvider,
|
||||
GitLabMergeRequestDiscussionInlayRenderer(this, project, model.vm, avatarIconsProvider, contextDataLoader,
|
||||
GitLabStatistics.MergeRequestNoteActionPlace.DIFF)
|
||||
is GitLabMergeRequestEditorMappedComponentModel.DraftNote<*> ->
|
||||
GitLabMergeRequestDraftNoteInlayRenderer(this, project, model.vm, avatarIconsProvider,
|
||||
GitLabMergeRequestDraftNoteInlayRenderer(this, project, model.vm, avatarIconsProvider, contextDataLoader,
|
||||
GitLabStatistics.MergeRequestNoteActionPlace.DIFF)
|
||||
is GitLabMergeRequestEditorMappedComponentModel.NewDiscussion<*> ->
|
||||
GitLabMergeRequestNewDiscussionInlayRenderer(this, project, model.vm, avatarIconsProvider,
|
||||
|
||||
+4
-1
@@ -28,6 +28,7 @@ import org.jetbrains.plugins.gitlab.mergerequest.GitLabMergeRequestsPreferences
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.data.GitLabMergeRequest
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.data.GitLabMergeRequestChanges
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.data.loadRevisionsAndParseChanges
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.GitLabContextDataLoader
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.createDiffDataFlow
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.diff.*
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.review.GitLabMergeRequestDiscussionsViewModels
|
||||
@@ -71,6 +72,7 @@ internal class GitLabMergeRequestDiffProcessorViewModelImpl(
|
||||
private val mergeRequest: GitLabMergeRequest,
|
||||
private val discussionsContainer: GitLabMergeRequestDiscussionsViewModels,
|
||||
private val avatarIconsProvider: IconsProvider<GitLabUserDTO>,
|
||||
private val contextDataLoader: GitLabContextDataLoader,
|
||||
) : GitLabMergeRequestDiffViewModel, GitLabMergeRequestReviewViewModelBase(
|
||||
parentCs.childScope("GitLab Merge Request Diff Review VM"),
|
||||
currentUser, mergeRequest,
|
||||
@@ -194,7 +196,8 @@ internal class GitLabMergeRequestDiffProcessorViewModelImpl(
|
||||
project, this,
|
||||
mergeRequest, diffData, change,
|
||||
this@GitLabMergeRequestDiffProcessorViewModelImpl,
|
||||
discussionsContainer, discussionsViewOption, avatarIconsProvider
|
||||
discussionsContainer, discussionsViewOption, avatarIconsProvider,
|
||||
contextDataLoader
|
||||
)
|
||||
|
||||
override fun findNextComment(currentThreadId: String, additionalIsVisible: (String) -> Boolean): String? =
|
||||
|
||||
+3
-1
@@ -111,7 +111,9 @@ class GitLabMergeRequestTimelineEditorFactory(private val project: Project, pare
|
||||
withContext(Dispatchers.Main.immediate) {
|
||||
timelineVmResult.fold(
|
||||
onSuccess = {
|
||||
val timeline = GitLabMergeRequestTimelineComponentFactory.create(project, this, it, projectVm.avatarIconProvider)
|
||||
val timeline = GitLabMergeRequestTimelineComponentFactory.create(project, this, it,
|
||||
projectVm.avatarIconProvider,
|
||||
projectVm.contextDataLoader)
|
||||
wrapper.setContent(timeline)
|
||||
wrapper.repaint()
|
||||
},
|
||||
|
||||
+5
-1
@@ -48,6 +48,7 @@ interface GitLabConnectedProjectViewModel {
|
||||
val accountVm: GitLabAccountViewModel
|
||||
val listVm: GitLabMergeRequestsListViewModel
|
||||
val currentMergeRequestReviewVm: Flow<GitLabMergeRequestEditorReviewViewModel?>
|
||||
val contextDataLoader: GitLabContextDataLoader
|
||||
fun findMergeRequestDetails(mrIid: String): GitLabMergeRequestDetails?
|
||||
fun reloadMergeRequestDetails(mergeRequestId: String)
|
||||
fun getDiffViewModel(mrIid: String): Flow<Result<GitLabMergeRequestDiffViewModel>>
|
||||
@@ -77,6 +78,8 @@ abstract class GitLabConnectedProjectViewModelBase(
|
||||
|
||||
override val avatarIconProvider: IconsProvider<GitLabUserDTO> = CachingIconsProvider(AsyncImageIconsProvider(cs, connection.imageLoader))
|
||||
|
||||
override val contextDataLoader: GitLabContextDataLoader = connection.projectData.contextDataLoader
|
||||
|
||||
private val projectName: @Nls String = connection.repo.repository.projectPath.name
|
||||
|
||||
override val listVm: GitLabMergeRequestsListViewModel = run {
|
||||
@@ -103,7 +106,8 @@ abstract class GitLabConnectedProjectViewModelBase(
|
||||
connection.projectData.mergeRequests.getShared(iid)
|
||||
.transformConsecutiveSuccesses {
|
||||
mapScoped {
|
||||
GitLabMergeRequestViewModels(project, this, connection.projectData, avatarIconProvider, it, connection.currentUser,
|
||||
GitLabMergeRequestViewModels(project, this, connection.projectData, avatarIconProvider,
|
||||
it, connection.currentUser,
|
||||
::openMergeRequestDetails, ::openMergeRequestTimeline, ::openMergeRequestDiff)
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -1,6 +1,7 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.plugins.gitlab.mergerequest.ui
|
||||
|
||||
import com.intellij.collaboration.ui.html.AsyncHtmlImageLoader
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
/**
|
||||
@@ -8,5 +9,6 @@ import org.jetbrains.annotations.ApiStatus
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
class GitLabContextDataLoader(
|
||||
val imageLoader: AsyncHtmlImageLoader,
|
||||
val uploadFileUrlBase: String
|
||||
)
|
||||
+4
-2
@@ -66,7 +66,8 @@ internal class GitLabMergeRequestViewModels(
|
||||
}
|
||||
|
||||
private val _diffVm by lazy {
|
||||
GitLabMergeRequestDiffProcessorViewModelImpl(project, cs, currentUser, mergeRequest, discussionsVms, avatarIconProvider).apply {
|
||||
GitLabMergeRequestDiffProcessorViewModelImpl(project, cs, currentUser, mergeRequest, discussionsVms,
|
||||
avatarIconProvider, projectData.contextDataLoader).apply {
|
||||
setup()
|
||||
}
|
||||
}
|
||||
@@ -74,7 +75,8 @@ internal class GitLabMergeRequestViewModels(
|
||||
|
||||
val editorReviewVm: GitLabMergeRequestEditorReviewViewModel by lazy {
|
||||
GitLabMergeRequestEditorReviewViewModel(cs, project, projectData.projectMapping, currentUser, mergeRequest,
|
||||
discussionsVms, avatarIconProvider, openMergeRequestDetails, openMergeRequestDiff).apply {
|
||||
discussionsVms, avatarIconProvider, projectData.contextDataLoader,
|
||||
openMergeRequestDetails, openMergeRequestDiff).apply {
|
||||
setup()
|
||||
}
|
||||
}
|
||||
|
||||
+6
-2
@@ -18,6 +18,7 @@ import com.intellij.util.ui.launchOnShow
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import org.jetbrains.plugins.gitlab.api.dto.GitLabUserDTO
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.GitLabContextDataLoader
|
||||
import org.jetbrains.plugins.gitlab.ui.comment.*
|
||||
import org.jetbrains.plugins.gitlab.util.GitLabBundle
|
||||
import org.jetbrains.plugins.gitlab.util.GitLabStatistics
|
||||
@@ -32,10 +33,11 @@ internal object GitLabMergeRequestDiffInlayComponentsFactory {
|
||||
project: Project,
|
||||
cs: CoroutineScope,
|
||||
avatarIconsProvider: IconsProvider<GitLabUserDTO>,
|
||||
contextDataLoader: GitLabContextDataLoader,
|
||||
vm: GitLabMergeRequestDiscussionViewModel,
|
||||
place: GitLabStatistics.MergeRequestNoteActionPlace,
|
||||
): JComponent =
|
||||
GitLabDiscussionComponentFactory.create(project, cs, avatarIconsProvider, vm, place).apply {
|
||||
GitLabDiscussionComponentFactory.create(project, cs, avatarIconsProvider, contextDataLoader, vm, place).apply {
|
||||
border = JBUI.Borders.empty(CodeReviewCommentUIUtil.getInlayPadding(CodeReviewChatItemUIUtil.ComponentType.COMPACT))
|
||||
}.apply {
|
||||
isFocusable = true
|
||||
@@ -57,10 +59,12 @@ internal object GitLabMergeRequestDiffInlayComponentsFactory {
|
||||
project: Project,
|
||||
cs: CoroutineScope,
|
||||
avatarIconsProvider: IconsProvider<GitLabUserDTO>,
|
||||
contextDataLoader: GitLabContextDataLoader,
|
||||
vm: GitLabNoteViewModel,
|
||||
place: GitLabStatistics.MergeRequestNoteActionPlace,
|
||||
): JComponent =
|
||||
GitLabNoteComponentFactory.create(CodeReviewChatItemUIUtil.ComponentType.COMPACT, project, cs, avatarIconsProvider, vm, place).apply {
|
||||
GitLabNoteComponentFactory.create(CodeReviewChatItemUIUtil.ComponentType.COMPACT, project, cs, avatarIconsProvider,
|
||||
contextDataLoader, vm, place).apply {
|
||||
border = JBUI.Borders.empty(CodeReviewCommentUIUtil.getInlayPadding(CodeReviewChatItemUIUtil.ComponentType.COMPACT))
|
||||
}.apply {
|
||||
isFocusable = true
|
||||
|
||||
+3
@@ -24,6 +24,7 @@ import org.jetbrains.plugins.gitlab.mergerequest.data.GitLabMergeRequest
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.data.GitLabMergeRequestNewDiscussionPosition
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.data.mapToLocation
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.diff.GitLabMergeRequestDiffViewModel
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.GitLabContextDataLoader
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.details.model.GitLabPersistentMergeRequestChangesViewedState
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.filterInFile
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.review.GitLabMergeRequestDiscussionsViewModels
|
||||
@@ -42,6 +43,7 @@ interface GitLabMergeRequestDiffReviewViewModel {
|
||||
val locationsWithNewDiscussions: StateFlow<Set<DiffLineLocation>>
|
||||
|
||||
val avatarIconsProvider: IconsProvider<GitLabUserDTO>
|
||||
val contextDataLoader: GitLabContextDataLoader
|
||||
|
||||
fun nextComment(focused: String, additionalIsVisible: (String) -> Boolean): String?
|
||||
fun nextComment(cursorLocation: UnifiedCodeReviewItemPosition, additionalIsVisible: (String) -> Boolean): String?
|
||||
@@ -66,6 +68,7 @@ internal class GitLabMergeRequestDiffReviewViewModelImpl(
|
||||
private val discussionsContainer: GitLabMergeRequestDiscussionsViewModels,
|
||||
discussionsViewOption: StateFlow<DiscussionsViewOption>,
|
||||
override val avatarIconsProvider: IconsProvider<GitLabUserDTO>,
|
||||
override val contextDataLoader: GitLabContextDataLoader
|
||||
) : GitLabMergeRequestDiffReviewViewModel {
|
||||
private val cs = parentCs.childScope(javaClass.name)
|
||||
|
||||
|
||||
+5
-1
@@ -27,6 +27,7 @@ import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.*
|
||||
import org.jetbrains.plugins.gitlab.api.dto.GitLabUserDTO
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.GitLabMergeRequestsPreferences
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.GitLabContextDataLoader
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.GitLabProjectViewModel
|
||||
import org.jetbrains.plugins.gitlab.util.GitLabStatistics
|
||||
|
||||
@@ -103,7 +104,7 @@ internal class GitLabMergeRequestEditorReviewController(private val project: Pro
|
||||
}
|
||||
launchNow {
|
||||
editor.renderInlays(model.inlays, HashingUtil.mappingStrategy(GitLabMergeRequestEditorMappedComponentModel::key)) {
|
||||
createRenderer(it, fileVm.avatarIconsProvider)
|
||||
createRenderer(it, fileVm.avatarIconsProvider, fileVm.contextDataLoader)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,13 +123,16 @@ internal class GitLabMergeRequestEditorReviewController(private val project: Pro
|
||||
private fun CoroutineScope.createRenderer(
|
||||
inlayModel: GitLabMergeRequestEditorMappedComponentModel,
|
||||
avatarIconsProvider: IconsProvider<GitLabUserDTO>,
|
||||
contextDataLoader: GitLabContextDataLoader
|
||||
) =
|
||||
when (inlayModel) {
|
||||
is GitLabMergeRequestEditorMappedComponentModel.Discussion<*> ->
|
||||
GitLabMergeRequestDiscussionInlayRenderer(this, project, inlayModel.vm, avatarIconsProvider,
|
||||
contextDataLoader,
|
||||
GitLabStatistics.MergeRequestNoteActionPlace.EDITOR)
|
||||
is GitLabMergeRequestEditorMappedComponentModel.DraftNote<*> ->
|
||||
GitLabMergeRequestDraftNoteInlayRenderer(this, project, inlayModel.vm, avatarIconsProvider,
|
||||
contextDataLoader,
|
||||
GitLabStatistics.MergeRequestNoteActionPlace.EDITOR)
|
||||
is GitLabMergeRequestEditorMappedComponentModel.NewDiscussion<*> ->
|
||||
GitLabMergeRequestNewDiscussionInlayRenderer(this, project, inlayModel.vm, avatarIconsProvider,
|
||||
|
||||
+3
@@ -29,6 +29,7 @@ import org.jetbrains.plugins.gitlab.api.dto.GitLabUserDTO
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.data.GitLabMergeRequest
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.data.GitLabMergeRequestNewDiscussionPosition
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.data.mapToLocation
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.GitLabContextDataLoader
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.filterInFile
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.review.GitLabMergeRequestDiscussionsViewModels
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.review.mapToLocation
|
||||
@@ -54,6 +55,7 @@ interface GitLabMergeRequestEditorReviewFileViewModel {
|
||||
val newDiscussions: StateFlow<Collection<GitLabMergeRequestEditorNewDiscussionViewModel>>
|
||||
|
||||
val avatarIconsProvider: IconsProvider<GitLabUserDTO>
|
||||
val contextDataLoader: GitLabContextDataLoader
|
||||
|
||||
fun lookupNextComment(line: Int, additionalIsVisible: (String) -> Boolean): String?
|
||||
fun lookupNextComment(noteTrackingId: String, additionalIsVisible: (String) -> Boolean): String?
|
||||
@@ -79,6 +81,7 @@ internal class GitLabMergeRequestEditorReviewFileViewModelImpl(
|
||||
private val reviewVm: GitLabMergeRequestEditorReviewViewModel,
|
||||
discussionsViewOption: StateFlow<DiscussionsViewOption>,
|
||||
override val avatarIconsProvider: IconsProvider<GitLabUserDTO>,
|
||||
override val contextDataLoader: GitLabContextDataLoader
|
||||
) : GitLabMergeRequestEditorReviewFileViewModel {
|
||||
private val cs = parentCs.childScope(javaClass.name, Dispatchers.Default)
|
||||
|
||||
|
||||
+3
-1
@@ -33,6 +33,7 @@ import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.plugins.gitlab.api.dto.GitLabUserDTO
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.GitLabMergeRequestsPreferences
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.data.GitLabMergeRequest
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.GitLabContextDataLoader
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.createDiffDataFlow
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.review.GitLabMergeRequestDiscussionsViewModels
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.review.GitLabMergeRequestReviewViewModelBase
|
||||
@@ -52,6 +53,7 @@ class GitLabMergeRequestEditorReviewViewModel internal constructor(
|
||||
private val mergeRequest: GitLabMergeRequest,
|
||||
private val discussionsVms: GitLabMergeRequestDiscussionsViewModels,
|
||||
private val avatarIconsProvider: IconsProvider<GitLabUserDTO>,
|
||||
private val contextDataLoader: GitLabContextDataLoader,
|
||||
private val openMergeRequestDetails: (String, GitLabStatistics.ToolWindowOpenTabActionPlace, Boolean) -> Unit,
|
||||
private val openMergeRequestDiff: (String, Boolean) -> Unit,
|
||||
) : GitLabMergeRequestReviewViewModelBase(
|
||||
@@ -251,7 +253,7 @@ class GitLabMergeRequestEditorReviewViewModel internal constructor(
|
||||
GitLabMergeRequestEditorReviewFileViewModelImpl(
|
||||
this, project, mergeRequest, changes.selectedItem!!, diffData,
|
||||
discussionsVms, this@GitLabMergeRequestEditorReviewViewModel,
|
||||
discussionsViewOption, avatarIconsProvider
|
||||
discussionsViewOption, avatarIconsProvider, contextDataLoader
|
||||
).also { vm ->
|
||||
launchNow {
|
||||
vm.showDiffRequests.collect { line ->
|
||||
|
||||
+9
-4
@@ -7,6 +7,7 @@ import com.intellij.openapi.project.Project
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.plugins.gitlab.api.dto.GitLabUserDTO
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.GitLabContextDataLoader
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.diff.GitLabMergeRequestDiffInlayComponentsFactory
|
||||
import org.jetbrains.plugins.gitlab.ui.comment.GitLabMergeRequestDiscussionViewModel
|
||||
import org.jetbrains.plugins.gitlab.ui.comment.GitLabNoteViewModel
|
||||
@@ -18,9 +19,11 @@ class GitLabMergeRequestDiscussionInlayRenderer internal constructor(cs: Corouti
|
||||
project: Project,
|
||||
vm: GitLabMergeRequestDiscussionViewModel,
|
||||
avatarIconsProvider: IconsProvider<GitLabUserDTO>,
|
||||
place: GitLabStatistics.MergeRequestNoteActionPlace)
|
||||
contextDataLoader: GitLabContextDataLoader,
|
||||
place: GitLabStatistics.MergeRequestNoteActionPlace,
|
||||
)
|
||||
: CodeReviewComponentInlayRenderer(
|
||||
GitLabMergeRequestDiffInlayComponentsFactory.createDiscussion(project, cs, avatarIconsProvider, vm, place)
|
||||
GitLabMergeRequestDiffInlayComponentsFactory.createDiscussion(project, cs, avatarIconsProvider, contextDataLoader, vm, place)
|
||||
)
|
||||
|
||||
@ApiStatus.Internal
|
||||
@@ -28,9 +31,11 @@ class GitLabMergeRequestDraftNoteInlayRenderer internal constructor(cs: Coroutin
|
||||
project: Project,
|
||||
vm: GitLabNoteViewModel,
|
||||
avatarIconsProvider: IconsProvider<GitLabUserDTO>,
|
||||
place: GitLabStatistics.MergeRequestNoteActionPlace)
|
||||
contextDataLoader: GitLabContextDataLoader,
|
||||
place: GitLabStatistics.MergeRequestNoteActionPlace,
|
||||
)
|
||||
: CodeReviewComponentInlayRenderer(
|
||||
GitLabMergeRequestDiffInlayComponentsFactory.createDraftNote(project, cs, avatarIconsProvider, vm, place)
|
||||
GitLabMergeRequestDiffInlayComponentsFactory.createDraftNote(project, cs, avatarIconsProvider, contextDataLoader, vm, place)
|
||||
)
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
+19
-15
@@ -20,7 +20,6 @@ import com.intellij.ide.DataManager
|
||||
import com.intellij.openapi.actionSystem.ActionGroup
|
||||
import com.intellij.openapi.actionSystem.ActionManager
|
||||
import com.intellij.openapi.actionSystem.ActionPlaces
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.diagnostic.thisLogger
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager
|
||||
import com.intellij.openapi.project.Project
|
||||
@@ -32,17 +31,16 @@ import com.intellij.ui.PopupHandler
|
||||
import com.intellij.ui.ScrollPaneFactory
|
||||
import com.intellij.ui.components.panels.ListLayout
|
||||
import com.intellij.ui.components.panels.Wrapper
|
||||
import com.intellij.util.ui.JBUI
|
||||
import com.intellij.util.ui.JBUI.Borders
|
||||
import com.intellij.util.ui.StyleSheetUtil
|
||||
import com.intellij.util.ui.launchOnShow
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.annotations.Nls
|
||||
import org.jetbrains.plugins.gitlab.api.dto.*
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.GitLabContextDataLoader
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.details.GitLabMergeRequestViewModel
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.util.addGitLabHyperlinkListener
|
||||
import org.jetbrains.plugins.gitlab.ui.comment.*
|
||||
@@ -55,7 +53,8 @@ internal object GitLabMergeRequestTimelineComponentFactory {
|
||||
fun create(project: Project,
|
||||
cs: CoroutineScope,
|
||||
timelineVm: GitLabMergeRequestTimelineViewModel,
|
||||
avatarIconsProvider: IconsProvider<GitLabUserDTO>
|
||||
avatarIconsProvider: IconsProvider<GitLabUserDTO>,
|
||||
contextDataLoader: GitLabContextDataLoader
|
||||
): JComponent {
|
||||
val titleComponent = GitLabMergeRequestTimelineTitleComponent.create(project, cs, timelineVm).let {
|
||||
CollaborationToolsUIUtil.wrapWithLimitedSize(it, CodeReviewChatItemUIUtil.TEXT_CONTENT_WIDTH)
|
||||
@@ -63,10 +62,10 @@ internal object GitLabMergeRequestTimelineComponentFactory {
|
||||
border = Borders.empty(CodeReviewTimelineUIUtil.HEADER_VERT_PADDING, CodeReviewTimelineUIUtil.ITEM_HOR_PADDING)
|
||||
}
|
||||
val descriptionComponent = GitLabMergeRequestTimelineDescriptionComponent
|
||||
.createComponent(project, cs, timelineVm, avatarIconsProvider)
|
||||
.createComponent(project, cs, timelineVm, avatarIconsProvider, contextDataLoader)
|
||||
|
||||
val timelinePanel = VerticalListPanel(0)
|
||||
val errorOrTimelineComponent = createErrorOrTimelineComponent(cs, project, avatarIconsProvider, timelineVm, timelinePanel)
|
||||
val errorOrTimelineComponent = createErrorOrTimelineComponent(cs, project, avatarIconsProvider, contextDataLoader, timelineVm, timelinePanel)
|
||||
|
||||
val newNoteField = timelineVm.newNoteVm?.let {
|
||||
cs.createNewNoteField(project, avatarIconsProvider, it)
|
||||
@@ -138,6 +137,7 @@ internal object GitLabMergeRequestTimelineComponentFactory {
|
||||
private fun createErrorOrTimelineComponent(cs: CoroutineScope,
|
||||
project: Project,
|
||||
avatarIconsProvider: IconsProvider<GitLabUserDTO>,
|
||||
contextDataLoader: GitLabContextDataLoader,
|
||||
timelineVm: GitLabMergeRequestTimelineViewModel,
|
||||
timelinePanel: JComponent): JComponent {
|
||||
val actionManager = ActionManager.getInstance()
|
||||
@@ -148,7 +148,7 @@ internal object GitLabMergeRequestTimelineComponentFactory {
|
||||
|
||||
val timelineItems = MutableStateFlow<List<GitLabMergeRequestTimelineItemViewModel>>(listOf())
|
||||
val timelineItemContent = ComponentListPanelFactory.createVertical(cs, timelineItems) { item ->
|
||||
createItemComponent(project, avatarIconsProvider, item)
|
||||
createItemComponent(project, avatarIconsProvider, contextDataLoader, item)
|
||||
}
|
||||
val timelineItemsAndLoadingLabel = VerticalListPanel(gap = 0).apply {
|
||||
val panel = this
|
||||
@@ -196,6 +196,7 @@ internal object GitLabMergeRequestTimelineComponentFactory {
|
||||
|
||||
private fun CoroutineScope.createItemComponent(project: Project,
|
||||
avatarIconsProvider: IconsProvider<GitLabUserDTO>,
|
||||
contextDataLoader: GitLabContextDataLoader,
|
||||
item: GitLabMergeRequestTimelineItemViewModel): JComponent =
|
||||
when (item) {
|
||||
is GitLabMergeRequestTimelineItemViewModel.Immutable -> {
|
||||
@@ -208,10 +209,10 @@ internal object GitLabMergeRequestTimelineComponentFactory {
|
||||
}
|
||||
}
|
||||
is GitLabMergeRequestTimelineItemViewModel.Discussion -> {
|
||||
GitLabMergeRequestTimelineDiscussionComponentFactory.createIn(project, this, item, avatarIconsProvider)
|
||||
GitLabMergeRequestTimelineDiscussionComponentFactory.createIn(project, this, item, avatarIconsProvider, contextDataLoader)
|
||||
}
|
||||
is GitLabMergeRequestTimelineItemViewModel.DraftNote -> {
|
||||
GitLabMergeRequestTimelineDiscussionComponentFactory.createIn(project, this, item, avatarIconsProvider)
|
||||
GitLabMergeRequestTimelineDiscussionComponentFactory.createIn(project, this, item, avatarIconsProvider, contextDataLoader)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,8 +224,10 @@ internal object GitLabMergeRequestTimelineComponentFactory {
|
||||
is GitLabMergeRequestTimelineItemViewModel.StateEvent -> createStateChangeContent(item)
|
||||
}
|
||||
|
||||
private fun createSystemDiscussionContent(project: Project,
|
||||
item: GitLabMergeRequestTimelineItemViewModel.SystemNote): JComponent {
|
||||
private fun createSystemDiscussionContent(
|
||||
project: Project,
|
||||
item: GitLabMergeRequestTimelineItemViewModel.SystemNote
|
||||
): JComponent {
|
||||
val content = item.content
|
||||
if (content.contains("Compare with previous version")) {
|
||||
try {
|
||||
@@ -253,10 +256,11 @@ internal object GitLabMergeRequestTimelineComponentFactory {
|
||||
StyleSheetUtil.loadStyleSheet("""ul {margin: 0}""")
|
||||
}
|
||||
|
||||
private fun createCommitsListPane(project: Project, commits: @NlsSafe String) = SimpleHtmlPane(noUlGapsStyleSheet, addBrowserListener = false).apply {
|
||||
setHtmlBody(commits)
|
||||
addGitLabHyperlinkListener(project)
|
||||
}
|
||||
private fun createCommitsListPane(project: Project, commits: @NlsSafe String) =
|
||||
SimpleHtmlPane(noUlGapsStyleSheet, addBrowserListener = false).apply {
|
||||
setHtmlBody(commits)
|
||||
addGitLabHyperlinkListener(project)
|
||||
}
|
||||
|
||||
private fun createLabeledEventContent(item: GitLabMergeRequestTimelineItemViewModel.LabelEvent): JComponent {
|
||||
val text = when (item.event.actionEnum) {
|
||||
|
||||
+3
-1
@@ -13,6 +13,7 @@ import com.intellij.util.ui.UIUtil
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.map
|
||||
import org.jetbrains.plugins.gitlab.api.dto.GitLabUserDTO
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.GitLabContextDataLoader
|
||||
import org.jetbrains.plugins.gitlab.ui.comment.GitLabNoteComponentFactory.createTextPanel
|
||||
import org.jetbrains.plugins.gitlab.util.GitLabBundle
|
||||
import javax.swing.JComponent
|
||||
@@ -32,10 +33,11 @@ internal object GitLabMergeRequestTimelineDescriptionComponent {
|
||||
cs: CoroutineScope,
|
||||
vm: GitLabMergeRequestTimelineViewModel,
|
||||
avatarIconsProvider: IconsProvider<GitLabUserDTO>,
|
||||
contextDataLoader: GitLabContextDataLoader,
|
||||
): JComponent {
|
||||
val titlePanel = CodeReviewTimelineUIUtil.createTitleTextPane(vm.author.name, vm.author.webUrl, date = null)
|
||||
val descriptionTextComponent = createTextPanel(project, cs, vm.descriptionHtml.map { it.ifBlank { noDescriptionHtmlText } },
|
||||
vm.serverUrl)
|
||||
vm.serverUrl, contextDataLoader)
|
||||
|
||||
|
||||
return CodeReviewChatItemUIUtil.buildDynamic(CodeReviewChatItemUIUtil.ComponentType.FULL,
|
||||
|
||||
+30
-16
@@ -33,6 +33,7 @@ import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.plugins.gitlab.api.dto.GitLabUserDTO
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.data.filePath
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.GitLabContextDataLoader
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.emoji.GitLabReactionsComponentFactory
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.util.localizedMessageOrClassName
|
||||
import org.jetbrains.plugins.gitlab.ui.comment.GitLabDiscussionComponentFactory
|
||||
@@ -53,18 +54,20 @@ internal object GitLabMergeRequestTimelineDiscussionComponentFactory {
|
||||
fun createIn(project: Project,
|
||||
cs: CoroutineScope,
|
||||
vm: GitLabMergeRequestTimelineDiscussionViewModel,
|
||||
avatarIconsProvider: IconsProvider<GitLabUserDTO>): JComponent =
|
||||
avatarIconsProvider: IconsProvider<GitLabUserDTO>,
|
||||
contextDataLoader: GitLabContextDataLoader): JComponent =
|
||||
VerticalListPanel().apply {
|
||||
name = "GitLab Discussion Panel ${vm.id}"
|
||||
add(createDiscussionItemIn(project, cs, vm, avatarIconsProvider))
|
||||
add(createRepliesPanelIn(project, cs, vm, avatarIconsProvider))
|
||||
add(createDiscussionItemIn(project, cs, vm, avatarIconsProvider, contextDataLoader))
|
||||
add(createRepliesPanelIn(project, cs, vm, avatarIconsProvider, contextDataLoader))
|
||||
}
|
||||
|
||||
fun createIn(project: Project,
|
||||
cs: CoroutineScope,
|
||||
vm: GitLabMergeRequestTimelineItemViewModel.DraftNote,
|
||||
avatarIconsProvider: IconsProvider<GitLabUserDTO>): JComponent {
|
||||
val contentPanel = createContentIn(project, cs, vm)
|
||||
avatarIconsProvider: IconsProvider<GitLabUserDTO>,
|
||||
contextDataLoader: GitLabContextDataLoader): JComponent {
|
||||
val contentPanel = createContentIn(project, cs, vm, contextDataLoader)
|
||||
val mainItem = CodeReviewChatItemUIUtil.build(ComponentType.FULL,
|
||||
{ avatarIconsProvider.getIcon(vm.author, it) },
|
||||
contentPanel) {
|
||||
@@ -82,8 +85,9 @@ internal object GitLabMergeRequestTimelineDiscussionComponentFactory {
|
||||
private fun createDiscussionItemIn(project: Project,
|
||||
cs: CoroutineScope,
|
||||
vm: GitLabMergeRequestTimelineDiscussionViewModel,
|
||||
avatarIconsProvider: IconsProvider<GitLabUserDTO>): JComponent {
|
||||
val contentPanel = createContentIn(project, cs, vm, avatarIconsProvider)
|
||||
avatarIconsProvider: IconsProvider<GitLabUserDTO>,
|
||||
contextDataLoader: GitLabContextDataLoader): JComponent {
|
||||
val contentPanel = createContentIn(project, cs, vm, avatarIconsProvider, contextDataLoader)
|
||||
val mainItem = CodeReviewChatItemUIUtil.buildDynamic(ComponentType.FULL,
|
||||
{ vm.author.createIconValue(cs, avatarIconsProvider, it) },
|
||||
contentPanel) {
|
||||
@@ -104,13 +108,14 @@ internal object GitLabMergeRequestTimelineDiscussionComponentFactory {
|
||||
private fun createContentIn(project: Project,
|
||||
cs: CoroutineScope,
|
||||
vm: GitLabMergeRequestTimelineDiscussionViewModel,
|
||||
avatarIconsProvider: IconsProvider<GitLabUserDTO>): JPanel {
|
||||
avatarIconsProvider: IconsProvider<GitLabUserDTO>,
|
||||
contextDataLoader: GitLabContextDataLoader): JPanel {
|
||||
val mainNoteVm = vm.mainNote
|
||||
val repliesActionsPanel = createRepliesActionsPanel(cs, avatarIconsProvider, vm).apply {
|
||||
border = JBUI.Borders.empty(Replies.ActionsFolded.VERTICAL_PADDING, 0)
|
||||
bindVisibilityIn(cs, vm.repliesFolded)
|
||||
}
|
||||
val textPanel = createDiscussionTextPane(project, cs, vm)
|
||||
val textPanel = createDiscussionTextPane(project, cs, vm, contextDataLoader)
|
||||
|
||||
val editVmFlow = mainNoteVm.flatMapLatest { it.actionsVm?.editVm ?: flowOf(null) }
|
||||
val textContentPanel = EditableComponentFactory.wrapTextComponent(cs, textPanel, editVmFlow) {
|
||||
@@ -162,8 +167,10 @@ internal object GitLabMergeRequestTimelineDiscussionComponentFactory {
|
||||
|
||||
private fun createContentIn(project: Project,
|
||||
cs: CoroutineScope,
|
||||
vm: GitLabMergeRequestTimelineItemViewModel.DraftNote): JPanel {
|
||||
val textPanel = GitLabNoteComponentFactory.createTextPanel(project, cs, vm.bodyHtml, vm.serverUrl)
|
||||
vm: GitLabMergeRequestTimelineItemViewModel.DraftNote,
|
||||
contextDataLoader: GitLabContextDataLoader): JPanel {
|
||||
val textPanel = GitLabNoteComponentFactory.createTextPanel(project, cs, vm.bodyHtml, vm.serverUrl,
|
||||
contextDataLoader)
|
||||
|
||||
val textContentPanel = EditableComponentFactory.wrapTextComponent(cs, textPanel, vm.actionsVm?.editVm ?: flowOf(null)) {
|
||||
GitLabStatistics.logMrActionExecuted(project, GitLabStatistics.MergeRequestAction.UPDATE_NOTE,
|
||||
@@ -270,7 +277,10 @@ internal object GitLabMergeRequestTimelineDiscussionComponentFactory {
|
||||
)
|
||||
}
|
||||
|
||||
private fun createDiscussionTextPane(project: Project, cs: CoroutineScope, vm: GitLabMergeRequestTimelineDiscussionViewModel): JComponent {
|
||||
private fun createDiscussionTextPane(
|
||||
project: Project, cs: CoroutineScope, vm: GitLabMergeRequestTimelineDiscussionViewModel,
|
||||
contextDataLoader: GitLabContextDataLoader
|
||||
): JComponent {
|
||||
val collapsedFlow = combine(vm.collapsible, vm.collapsed) { collapsible, collapsed ->
|
||||
collapsible && collapsed
|
||||
}
|
||||
@@ -279,7 +289,7 @@ internal object GitLabMergeRequestTimelineDiscussionComponentFactory {
|
||||
if (collapsed) mainNote.body else mainNote.bodyHtml
|
||||
}.flatMapLatest { it }
|
||||
|
||||
val textPane = GitLabNoteComponentFactory.createTextPanel(project, cs, textFlow, vm.serverUrl)
|
||||
val textPane = GitLabNoteComponentFactory.createTextPanel(project, cs, textFlow, vm.serverUrl, contextDataLoader)
|
||||
val layout = SizeRestrictedSingleComponentLayout()
|
||||
return JPanel(layout).apply {
|
||||
name = "Text pane wrapper"
|
||||
@@ -306,10 +316,14 @@ internal object GitLabMergeRequestTimelineDiscussionComponentFactory {
|
||||
private fun createRepliesPanelIn(project: Project,
|
||||
cs: CoroutineScope,
|
||||
vm: GitLabMergeRequestTimelineDiscussionViewModel,
|
||||
avatarIconsProvider: IconsProvider<GitLabUserDTO>): JPanel {
|
||||
avatarIconsProvider: IconsProvider<GitLabUserDTO>,
|
||||
contextDataLoader: GitLabContextDataLoader
|
||||
): JPanel {
|
||||
val repliesListPanel = ComponentListPanelFactory.createVertical(cs, vm.replies) { noteVm ->
|
||||
GitLabNoteComponentFactory.create(ComponentType.FULL_SECONDARY, project, this, avatarIconsProvider, noteVm,
|
||||
ACTION_PLACE)
|
||||
GitLabNoteComponentFactory.create(
|
||||
ComponentType.FULL_SECONDARY, project, this, avatarIconsProvider, contextDataLoader, noteVm,
|
||||
ACTION_PLACE
|
||||
)
|
||||
}
|
||||
|
||||
val repliesPanel = VerticalListPanel().apply {
|
||||
|
||||
+5
-1
@@ -32,6 +32,7 @@ import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import org.jetbrains.plugins.gitlab.api.dto.GitLabUserDTO
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.GitLabContextDataLoader
|
||||
import org.jetbrains.plugins.gitlab.ui.comment.GitLabMergeRequestDiscussionViewModel.NoteItem
|
||||
import org.jetbrains.plugins.gitlab.util.GitLabBundle
|
||||
import org.jetbrains.plugins.gitlab.util.GitLabStatistics
|
||||
@@ -39,10 +40,12 @@ import javax.swing.Action
|
||||
import javax.swing.JComponent
|
||||
|
||||
internal object GitLabDiscussionComponentFactory {
|
||||
|
||||
fun create(
|
||||
project: Project,
|
||||
cs: CoroutineScope,
|
||||
avatarIconsProvider: IconsProvider<GitLabUserDTO>,
|
||||
contextDataLoader: GitLabContextDataLoader,
|
||||
vm: GitLabMergeRequestDiscussionViewModel,
|
||||
place: GitLabStatistics.MergeRequestNoteActionPlace,
|
||||
): JComponent {
|
||||
@@ -57,7 +60,8 @@ internal object GitLabDiscussionComponentFactory {
|
||||
TimelineThreadCommentsPanel.UNFOLD_BUTTON_VERTICAL_GAP,
|
||||
0)
|
||||
}
|
||||
is NoteItem.Note -> GitLabNoteComponentFactory.create(ComponentType.COMPACT, project, itemCs, avatarIconsProvider, item.vm, place)
|
||||
is NoteItem.Note -> GitLabNoteComponentFactory.create(ComponentType.COMPACT, project, itemCs, avatarIconsProvider, contextDataLoader,
|
||||
item.vm, place)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
-3
@@ -27,6 +27,7 @@ import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.annotations.Nls
|
||||
import org.jetbrains.plugins.gitlab.api.dto.GitLabUserDTO
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.GitLabContextDataLoader
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.emoji.GitLabReactionsComponentFactory
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.emoji.GitLabReactionsPickerComponentFactory
|
||||
import org.jetbrains.plugins.gitlab.mergerequest.ui.emoji.GitLabReactionsViewModel
|
||||
@@ -37,15 +38,17 @@ import java.net.URL
|
||||
import javax.swing.JComponent
|
||||
|
||||
internal object GitLabNoteComponentFactory {
|
||||
|
||||
fun create(
|
||||
componentType: ComponentType,
|
||||
project: Project,
|
||||
cs: CoroutineScope,
|
||||
avatarIconsProvider: IconsProvider<GitLabUserDTO>,
|
||||
contextDataLoader: GitLabContextDataLoader,
|
||||
vm: GitLabNoteViewModel,
|
||||
place: GitLabStatistics.MergeRequestNoteActionPlace,
|
||||
): JComponent {
|
||||
val textPanel = createTextPanel(project, cs, vm.bodyHtml, vm.serverUrl).let { panel ->
|
||||
val textPanel = createTextPanel(project, cs, vm.bodyHtml, vm.serverUrl, contextDataLoader).let { panel ->
|
||||
val actionsVm = vm.actionsVm ?: return@let panel
|
||||
EditableComponentFactory.wrapTextComponent(cs, panel, actionsVm.editVm) {
|
||||
GitLabStatistics.logMrActionExecuted(project, GitLabStatistics.MergeRequestAction.UPDATE_NOTE, place)
|
||||
@@ -173,8 +176,11 @@ internal object GitLabNoteComponentFactory {
|
||||
return button
|
||||
}
|
||||
|
||||
fun createTextPanel(project: Project, cs: CoroutineScope, textFlow: Flow<@Nls String>, baseUrl: URL): JComponent =
|
||||
SimpleHtmlPane(baseUrl = baseUrl, addBrowserListener = false).apply {
|
||||
fun createTextPanel(
|
||||
project: Project, cs: CoroutineScope, textFlow: Flow<@Nls String>, baseUrl: URL,
|
||||
contextDataLoader: GitLabContextDataLoader
|
||||
): JComponent =
|
||||
SimpleHtmlPane(baseUrl = baseUrl, addBrowserListener = false, customImageLoader = contextDataLoader.imageLoader).apply {
|
||||
bindTextIn(cs, textFlow)
|
||||
addGitLabHyperlinkListener(project)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user