[github] simplify component factory

GitOrigin-RevId: 0a61c7511e74323d76ef8dda27731abe2fbd8bb0
This commit is contained in:
Ivan Semenov
2025-07-04 19:08:06 +00:00
committed by intellij-monorepo-bot
parent f6df9c59e5
commit caa37e0116
@@ -5,20 +5,19 @@ import com.intellij.collaboration.async.launchNow
import com.intellij.collaboration.ui.LoadingTextLabel
import com.intellij.collaboration.ui.codereview.list.error.ErrorStatusPanelFactory
import com.intellij.collaboration.ui.codereview.list.error.ErrorStatusPresenter
import com.intellij.collaboration.util.fold
import com.intellij.collaboration.util.getOrNull
import com.intellij.ide.DataManager
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.editor.colors.EditorColorsListener
import com.intellij.openapi.editor.colors.EditorColorsManager
import com.intellij.openapi.editor.colors.EditorColorsManager.TOPIC
import com.intellij.openapi.actionSystem.UiDataProvider
import com.intellij.openapi.editor.colors.EditorColorsManager.getInstance
import com.intellij.openapi.project.Project
import com.intellij.ui.JBColor
import com.intellij.ui.components.JBPanel
import com.intellij.util.concurrency.annotations.RequiresEdt
import com.intellij.util.ui.SingleComponentCenteringLayout
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.collectLatest
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.plugins.github.i18n.GithubBundle
import org.jetbrains.plugins.github.i18n.GithubBundle.message
import org.jetbrains.plugins.github.pullrequest.action.GHPRActionKeys
import org.jetbrains.plugins.github.pullrequest.data.GHPRIdentifier
import org.jetbrains.plugins.github.pullrequest.ui.GHPRConnectedProjectViewModel
@@ -32,53 +31,40 @@ import javax.swing.JPanel
@ApiStatus.Internal
object GHPRTimelineComponentFactory {
@RequiresEdt
fun create(
project: Project, cs: CoroutineScope,
projectVm: GHPRConnectedProjectViewModel, timelineVm: GHPRTimelineViewModel,
pullRequest: GHPRIdentifier,
): JComponent {
return doCreateContent(project, cs, projectVm, timelineVm).apply {
isOpaque = true
background = EditorColorsManager.getInstance().globalScheme.defaultBackground
}.also {
ApplicationManager.getApplication().messageBus.connect(cs)
.subscribe(TOPIC, EditorColorsListener { scheme -> it.background = scheme?.defaultBackground })
DataManager.registerDataProvider(it) { dataId ->
when {
GHPRActionKeys.PULL_REQUEST_ID.`is`(dataId) -> pullRequest
GHPRActionKeys.PULL_REQUEST_URL.`is`(dataId) -> timelineVm.detailsVm.details.value.getOrNull()?.url
else -> null
}
}
val panel = JBPanel<JBPanel<*>>().apply {
background = JBColor.lazy { getInstance().globalScheme.defaultBackground }
}
}
private fun doCreateContent(
project: Project, cs: CoroutineScope,
projectVm: GHPRConnectedProjectViewModel, timelineVm: GHPRTimelineViewModel,
): JComponent {
val panel = JBPanel<JBPanel<*>>()
cs.launchNow {
timelineVm.detailsVm.details.collectLatest {
when (val result = it.result) {
null -> panel.setLayoutAndComponent(SingleComponentCenteringLayout(), LoadingTextLabel())
else -> result
.fold({ details ->
//further updates will be handled by the timeline itself
val timeline = GHPRFileEditorComponentFactory(cs, project, projectVm, timelineVm, details).create()
panel.setLayoutAndComponent(BorderLayout(), timeline)
cancel()
}, { error ->
val errorStatusPresenter = ErrorStatusPresenter.simple(GithubBundle.message("cannot.load.details"),
descriptionProvider = GHHtmlErrorPanel::getLoadingErrorText)
val errorPanel = ErrorStatusPanelFactory.create(error, errorStatusPresenter)
panel.setLayoutAndComponent(SingleComponentCenteringLayout(), errorPanel)
})
}
timelineVm.detailsVm.details.collect {
it.fold(
onInProgress = {
panel.setLayoutAndComponent(SingleComponentCenteringLayout(), LoadingTextLabel())
},
onSuccess = { details ->
val timeline = GHPRFileEditorComponentFactory(cs, project, projectVm, timelineVm, details).create()
panel.setLayoutAndComponent(BorderLayout(), timeline)
//further updates will be handled by the timeline itself
cancel()
},
onFailure = { error ->
val errorStatusPresenter = ErrorStatusPresenter.simple(message("cannot.load.details"),
descriptionProvider = GHHtmlErrorPanel::getLoadingErrorText)
val errorPanel = ErrorStatusPanelFactory.create(error, errorStatusPresenter)
panel.setLayoutAndComponent(SingleComponentCenteringLayout(), errorPanel)
}
)
}
}
return panel
return UiDataProvider.wrapComponent(panel) { sink ->
sink[GHPRActionKeys.PULL_REQUEST_ID] = pullRequest
sink[GHPRActionKeys.PULL_REQUEST_URL] = timelineVm.detailsVm.details.value.getOrNull()?.url
}
}
private fun JPanel.setLayoutAndComponent(newLayout: LayoutManager, component: JComponent) {