Merge branch 'master' into 'master'

Unify Result/Submit Panels

See merge request JFronny/s-dom!2
This commit is contained in:
Johannes Frohnmeyer 2024-05-14 17:43:47 +00:00
commit 5fcfcd3f4a
5 changed files with 99 additions and 75 deletions

View File

@ -29,6 +29,8 @@ import java.util.Base64
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
typealias ResultFlowListener = (SharedFlow<Result<SDJudgement>>, Contest, Problem, String) -> Unit
object SDom {
private const val CONTEST_ID_PROPERTY = "io.gitlab.jfronny.sdom.contestId"
@ -78,7 +80,9 @@ object SDom {
)
})
private val logoutListeners: MutableList<() -> Unit> = mutableListOf()
private val resultFlowListeners: MutableList<(SharedFlow<Result<SDJudgement>>, Contest, Problem, String) -> Unit> = mutableListOf()
private val resultFlowListeners: MutableList<ResultFlowListener> = mutableListOf()
val infoFlow: MutableSharedFlow<Result<SDJudgement>> = MutableSharedFlow()
fun registerLoginListener(listener: () -> Unit) {
loginListeners.add(listener)
@ -88,7 +92,7 @@ object SDom {
logoutListeners.add(listener)
}
fun registerResultFlowListener(listener: (SharedFlow<Result<SDJudgement>>, Contest, Problem, String) -> Unit) {
fun registerResultFlowListener(listener: ResultFlowListener) {
resultFlowListeners.add(listener)
}

View File

@ -2,15 +2,19 @@ package io.gitlab.jfronny.sdom.toolwindow
import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.wm.ToolWindow
import com.intellij.openapi.wm.ToolWindowFactory
import io.gitlab.jfronny.sdom.SDom
import io.gitlab.jfronny.sdom.model.Contest
import io.gitlab.jfronny.sdom.model.Problem
import io.gitlab.jfronny.sdom.model.SDJudgement
import io.gitlab.jfronny.sdom.ui.SDResultPanel
import io.gitlab.jfronny.sdom.ui.SDSubmitPanel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.launch
class SDToolWindowFactory : ToolWindowFactory, DumbAware {
override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) {
@ -18,9 +22,10 @@ class SDToolWindowFactory : ToolWindowFactory, DumbAware {
val loggedOutContent = contentManager.factory.createContent(loggedOutDialogPanel(), null, false).apply {
isCloseable = false
}
val submitContent = contentManager.factory.createContent(SDSubmitPanel(), "Submit", false).apply {
isCloseable = false
}
val submitPanel = SDSubmitPanel(project, SDom.infoFlow)
val submitContent = contentManager.factory.createContent(submitPanel.component, "Submit", false)
Disposer.register(toolWindow.disposable, submitPanel)
fun showSubmitContent() {
contentManager.addContent(submitContent)
@ -33,12 +38,13 @@ class SDToolWindowFactory : ToolWindowFactory, DumbAware {
}
fun showResultContent(resultFlow: Flow<Result<SDJudgement>>, contest: Contest, problem: Problem, filename: String) {
val resultPanel = SDResultPanel(project, resultFlow, contest, problem, filename)
val resultContent = contentManager.factory.createContent(resultPanel.component, "Result", false).apply {
preferredFocusableComponent = resultPanel.preferredFocusableComponent
submitPanel.logSubmission(contest, problem, filename)
CoroutineScope(Job() + Dispatchers.IO).launch {
resultFlow.collect { result ->
submitPanel.logSDJudgement(result, contest, problem, filename)
}
}
contentManager.addContent(resultContent)
contentManager.setSelectedContent(resultContent)
}
SDom.registerLoginListener(::showSubmitContent)

View File

@ -0,0 +1,18 @@
package io.gitlab.jfronny.sdom.ui
import com.intellij.execution.ui.ConsoleView
import com.intellij.execution.ui.ConsoleViewContentType
enum class OutputType {
ERROR, SUCCESS, OUTPUT
}
fun ConsoleView.println(text: String, contentType: OutputType) {
print(
"${text}\n", when (contentType) {
OutputType.ERROR -> ConsoleViewContentType.ERROR_OUTPUT
OutputType.SUCCESS -> ConsoleViewContentType.USER_INPUT
OutputType.OUTPUT -> ConsoleViewContentType.NORMAL_OUTPUT
}
)
}

View File

@ -1,57 +0,0 @@
package io.gitlab.jfronny.sdom.ui
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.ComponentContainer
import com.intellij.ui.JBColor
import io.gitlab.jfronny.sdom.SDom
import io.gitlab.jfronny.sdom.model.Contest
import io.gitlab.jfronny.sdom.model.Problem
import io.gitlab.jfronny.sdom.model.SDJudgement
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import java.awt.BorderLayout
import javax.swing.JComponent
import javax.swing.JLabel
import javax.swing.JPanel
class SDResultPanel(
val project: Project,
resultFlow: Flow<Result<SDJudgement>>,
contest: Contest,
problem: Problem,
filename: String
) : ComponentContainer {
private val panel = JPanel(BorderLayout())
init {
val loading = JLabel("Submitted file \"$filename\" to problem \"${problem.name}\", Waiting for result...")
panel.add(loading, BorderLayout.CENTER)
CoroutineScope(Job() + Dispatchers.IO).launch {
val resultResult = resultFlow.first()
resultResult.fold(
onSuccess = { result ->
val parsedResult =
result.judgementTypeId
?.let { SDom.judgementTypes?.get(it) }
?.let { it.name to it.solved }
?: ("Unknown" to false)
panel.add(JLabel("Submission of \"$filename\" to problem \"${problem.name}\", got result: ${parsedResult.first}").apply { foreground = if (parsedResult.second) JBColor.GREEN else JBColor.RED }, BorderLayout.CENTER)
},
onFailure = { e ->
panel.add(JLabel("Judgement failed: ${e.message}"), BorderLayout.CENTER)
}
)
panel.remove(loading)
panel.revalidate()
}
}
override fun dispose() {}
override fun getComponent(): JComponent = panel
override fun getPreferredFocusableComponent(): JComponent = panel // TODO focus on actual content once it's there
}

View File

@ -1,17 +1,70 @@
package io.gitlab.jfronny.sdom.ui
import com.intellij.ui.components.JBLabel
import com.intellij.execution.filters.TextConsoleBuilderFactory
import com.intellij.execution.ui.ConsoleView
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.ComponentContainer
import com.intellij.openapi.util.Disposer
import io.gitlab.jfronny.sdom.SDom
import io.gitlab.jfronny.sdom.model.Contest
import io.gitlab.jfronny.sdom.model.Problem
import io.gitlab.jfronny.sdom.model.SDJudgement
import kotlinx.coroutines.flow.MutableSharedFlow
import java.awt.BorderLayout
import javax.swing.JComponent
import javax.swing.JPanel
class SDSubmitPanel : JPanel(BorderLayout()) {
class SDSubmitPanel (
project: Project,
infoFlow: MutableSharedFlow<Result<SDJudgement>>,
) : ComponentContainer {
private val panel = JPanel(BorderLayout())
private val console: ConsoleView
init {
val label = JBLabel("Nothing to see here (yet)")
console = TextConsoleBuilderFactory.getInstance().createBuilder(project).console
Disposer.register(this, console)
val splitter = console.component // replace this to add stuff around the console
val toolWindowPanel = SDToolWindowPanel(
topComponent = SDActionToolBar(ToolBarOrientation.HORIZONTAL).apply { setTargetComponent(label) }.component,
mainComponent = label
topComponent = SDActionToolBar(ToolBarOrientation.HORIZONTAL).apply { setTargetComponent(splitter) }.component,
mainComponent = splitter
)
add(toolWindowPanel.getPanel())
isVisible = true
panel.add(toolWindowPanel.getPanel())
panel.isVisible = true
}
fun logSDJudgement(judgement: Result<SDJudgement>, contest: Contest, problem: Problem, filename: String) {
judgement.fold(
onSuccess = { result ->
val parsedResult =
result.judgementTypeId
?.let { SDom.judgementTypes?.get(it) }
?.let { it.name to it.solved }
?: ("Unknown" to false)
console.println(
"Submission of \"$filename\" to problem \"${problem.name}\", got result: ${parsedResult.first}",
if (parsedResult.second) OutputType.SUCCESS else OutputType.ERROR
)
},
onFailure = { e ->
console.println("Judgement failed: ${e.message}", OutputType.ERROR)
}
)
panel.revalidate()
}
fun logSubmission(contest: Contest, problem: Problem, filename: String) {
console.println("Submitted file \"$filename\" to problem \"${problem.name}\", Waiting for result...", OutputType.OUTPUT)
panel.revalidate()
}
override fun dispose() {}
override fun getComponent(): JComponent = panel
override fun getPreferredFocusableComponent(): JComponent = console.component
}