feat: implement submission (still needs testing)
This commit is contained in:
parent
c9a2aabc60
commit
74bbc91ea4
@ -3,8 +3,7 @@ S-DOM is a plugin for IntelliJ IDEA that allows you to submit your code to the D
|
|||||||
It is currently in development and not yet ready for use.
|
It is currently in development and not yet ready for use.
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
- Implement submissions
|
- Implement reading detailed results
|
||||||
- Implement reading results
|
|
||||||
- Implement reading problems (and testcases)
|
- Implement reading problems (and testcases)
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
@ -7,19 +7,20 @@ import com.intellij.ide.passwordSafe.PasswordSafe
|
|||||||
import com.intellij.openapi.application.ApplicationManager
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
|
|
||||||
object SDCredentials {
|
object SDCredentials {
|
||||||
private fun createCredentialAttributes(): CredentialAttributes {
|
private fun createCredentialAttributes(name: String): CredentialAttributes {
|
||||||
return CredentialAttributes(generateServiceName("s-dom", "httpAuth"))
|
return CredentialAttributes(generateServiceName("s-dom", name))
|
||||||
}
|
}
|
||||||
|
|
||||||
var credentials: Pair<String?, String?>
|
var credentials: Pair<String?, String?>
|
||||||
get() = PasswordSafe.instance[createCredentialAttributes()]
|
get() = PasswordSafe.instance[createCredentialAttributes("httpAuth")]
|
||||||
.run { this?.userName to this?.getPasswordAsString() }
|
.run { this?.userName to this?.getPasswordAsString() }
|
||||||
set(value) {
|
set(value) {
|
||||||
PasswordSafe.instance[createCredentialAttributes()] = Credentials(value.first, value.second)
|
PasswordSafe.instance[createCredentialAttributes("httpAuth")] = Credentials(value.first, value.second)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun logOut() {
|
fun logOut() {
|
||||||
PasswordSafe.instance[createCredentialAttributes()] = null
|
PasswordSafe.instance[createCredentialAttributes("httpAuth")] = null
|
||||||
|
PasswordSafe.instance[createCredentialAttributes("teamId")] = null
|
||||||
}
|
}
|
||||||
|
|
||||||
var url: String
|
var url: String
|
||||||
@ -27,4 +28,10 @@ object SDCredentials {
|
|||||||
set(value) {
|
set(value) {
|
||||||
ApplicationManager.getApplication().getService(SDSettings::class.java).state.url = value
|
ApplicationManager.getApplication().getService(SDSettings::class.java).state.url = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var teamId: String?
|
||||||
|
get() = PasswordSafe.instance[createCredentialAttributes("teamId")]?.userName
|
||||||
|
set(value) {
|
||||||
|
PasswordSafe.instance[createCredentialAttributes("teamId")] = Credentials(value)
|
||||||
|
}
|
||||||
}
|
}
|
@ -8,10 +8,7 @@ import com.intellij.openapi.diagnostic.Logger
|
|||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import io.gitlab.jfronny.sdom.actions.SDGetContestsAction
|
import io.gitlab.jfronny.sdom.actions.SDGetContestsAction
|
||||||
import io.gitlab.jfronny.sdom.actions.SDGetProblemsAction
|
import io.gitlab.jfronny.sdom.actions.SDGetProblemsAction
|
||||||
import io.gitlab.jfronny.sdom.model.Contest
|
import io.gitlab.jfronny.sdom.model.*
|
||||||
import io.gitlab.jfronny.sdom.model.Problem
|
|
||||||
import io.gitlab.jfronny.sdom.model.SDLoginResult
|
|
||||||
import io.gitlab.jfronny.sdom.model.SDResult
|
|
||||||
import io.ktor.client.*
|
import io.ktor.client.*
|
||||||
import io.ktor.client.call.*
|
import io.ktor.client.call.*
|
||||||
import io.ktor.client.engine.java.*
|
import io.ktor.client.engine.java.*
|
||||||
@ -21,8 +18,15 @@ import io.ktor.client.plugins.contentnegotiation.*
|
|||||||
import io.ktor.client.request.*
|
import io.ktor.client.request.*
|
||||||
import io.ktor.http.*
|
import io.ktor.http.*
|
||||||
import io.ktor.serialization.kotlinx.json.*
|
import io.ktor.serialization.kotlinx.json.*
|
||||||
|
import kotlinx.coroutines.coroutineScope
|
||||||
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.SharedFlow
|
import kotlinx.coroutines.flow.SharedFlow
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
|
import java.util.Base64
|
||||||
|
import java.util.zip.ZipEntry
|
||||||
|
import java.util.zip.ZipOutputStream
|
||||||
|
|
||||||
object SDom {
|
object SDom {
|
||||||
private const val CONTEST_ID_PROPERTY = "io.gitlab.jfronny.sdom.contestId"
|
private const val CONTEST_ID_PROPERTY = "io.gitlab.jfronny.sdom.contestId"
|
||||||
@ -61,7 +65,7 @@ object SDom {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
private val logoutListeners: MutableList<() -> Unit> = mutableListOf()
|
private val logoutListeners: MutableList<() -> Unit> = mutableListOf()
|
||||||
private val resultFlowListeners: MutableList<(SharedFlow<Result<SDResult>>, Problem) -> Unit> = mutableListOf()
|
private val resultFlowListeners: MutableList<(SharedFlow<Result<SDJudgement>>, Contest, Problem) -> Unit> = mutableListOf()
|
||||||
|
|
||||||
fun registerLoginListener(listener: () -> Unit) {
|
fun registerLoginListener(listener: () -> Unit) {
|
||||||
loginListeners.add(listener)
|
loginListeners.add(listener)
|
||||||
@ -71,7 +75,7 @@ object SDom {
|
|||||||
logoutListeners.add(listener)
|
logoutListeners.add(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun registerResultFlowListener(listener: (SharedFlow<Result<SDResult>>, Problem) -> Unit) {
|
fun registerResultFlowListener(listener: (SharedFlow<Result<SDJudgement>>, Contest, Problem) -> Unit) {
|
||||||
resultFlowListeners.add(listener)
|
resultFlowListeners.add(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,6 +88,7 @@ object SDom {
|
|||||||
|
|
||||||
if (!result.enabled) throw Exception("User is not enabled")
|
if (!result.enabled) throw Exception("User is not enabled")
|
||||||
SDCredentials.credentials = Pair(username, password)
|
SDCredentials.credentials = Pair(username, password)
|
||||||
|
SDCredentials.teamId = result.teamId
|
||||||
SDCredentials.url = fixedApi
|
SDCredentials.url = fixedApi
|
||||||
|
|
||||||
loginListeners.forEach { ApplicationManager.getApplication().invokeLater(it) }
|
loginListeners.forEach { ApplicationManager.getApplication().invokeLater(it) }
|
||||||
@ -103,6 +108,7 @@ object SDom {
|
|||||||
}
|
}
|
||||||
var problems: List<Problem> = listOf()
|
var problems: List<Problem> = listOf()
|
||||||
var currentProblem: Problem? = null
|
var currentProblem: Problem? = null
|
||||||
|
var judgementTypes: Map<String, SDJudgementType>? = null
|
||||||
|
|
||||||
suspend fun getContests() {
|
suspend fun getContests() {
|
||||||
val result = client.get("${SDCredentials.url}contests")
|
val result = client.get("${SDCredentials.url}contests")
|
||||||
@ -143,8 +149,63 @@ object SDom {
|
|||||||
currentProblem = null
|
currentProblem = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
judgementTypes = client.get("${SDCredentials.url}contests/${currentContest!!.id}/judgement-types")
|
||||||
|
.body<List<SDJudgementType>>()
|
||||||
|
.associateBy { it.id }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun submitSolution(
|
||||||
|
contest: Contest, problem: Problem, solution: String, fileName: String
|
||||||
|
): SharedFlow<Result<SDJudgement>> = coroutineScope {
|
||||||
|
val resultFlow: MutableSharedFlow<Result<SDJudgement>> = MutableSharedFlow()
|
||||||
|
launch {
|
||||||
|
try {
|
||||||
|
val response: SDSubmission = client.post("${SDCredentials.url}contests/${contest.id}/submissions") {
|
||||||
|
contentType(ContentType.Application.Json)
|
||||||
|
setBody(
|
||||||
|
SDAddSubmission(
|
||||||
|
problem = problem.id,
|
||||||
|
problemId = problem.id,
|
||||||
|
language = "cpp",
|
||||||
|
languageId = "cpp",
|
||||||
|
entryPoint = null,
|
||||||
|
files = listOf(SDAddSubmissionFile(zip(fileName, solution)))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}.body()
|
||||||
|
|
||||||
|
println(response)
|
||||||
|
if (response.importError != null) {
|
||||||
|
resultFlow.emit(Result.failure(Exception(response.importError)))
|
||||||
|
return@launch
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
val result: List<SDJudgement> = client.get("${SDCredentials.url}contests/${contest.id}/judgements?submission_id=${response.id}").body()
|
||||||
|
if (result.isNotEmpty()) {
|
||||||
|
result.forEach { resultFlow.emit(Result.success(it)) }
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
Thread.sleep(1000)
|
||||||
|
}
|
||||||
|
} while (true)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
resultFlow.emit(Result.failure(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resultFlowListeners.forEach { it -> ApplicationManager.getApplication().invokeLater { it(resultFlow, contest, problem) } }
|
||||||
|
return@coroutineScope resultFlow
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun zip(name: String, content: String): String =
|
||||||
|
String(Base64.getEncoder().encode(ByteArrayOutputStream().use { baos ->
|
||||||
|
ZipOutputStream(baos).use {
|
||||||
|
it.putNextEntry(ZipEntry(name))
|
||||||
|
it.write(content.toByteArray())
|
||||||
|
it.closeEntry()
|
||||||
|
}
|
||||||
|
baos.toByteArray()
|
||||||
|
}))
|
||||||
|
|
||||||
val loggedIn: Boolean
|
val loggedIn: Boolean
|
||||||
get() = SDCredentials.credentials.first != null && SDCredentials.credentials.second != null
|
get() = SDCredentials.credentials.first != null && SDCredentials.credentials.second != null
|
||||||
|
|
||||||
|
@ -0,0 +1,83 @@
|
|||||||
|
package io.gitlab.jfronny.sdom.actions
|
||||||
|
|
||||||
|
import com.intellij.icons.AllIcons
|
||||||
|
import com.intellij.notification.Notification
|
||||||
|
import com.intellij.notification.NotificationAction
|
||||||
|
import com.intellij.notification.NotificationGroupManager
|
||||||
|
import com.intellij.notification.NotificationType
|
||||||
|
import com.intellij.openapi.actionSystem.ActionUpdateThread
|
||||||
|
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||||
|
import com.intellij.openapi.actionSystem.CommonDataKeys
|
||||||
|
import com.intellij.openapi.diagnostic.LogLevel
|
||||||
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
|
import com.intellij.testFramework.utils.editor.getVirtualFile
|
||||||
|
import io.gitlab.jfronny.sdom.SDom
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.flow.first
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class SDSubmitAction(text: String) : NotificationAction(text) {
|
||||||
|
constructor() : this("")
|
||||||
|
|
||||||
|
override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.BGT
|
||||||
|
|
||||||
|
override fun actionPerformed(e: AnActionEvent, notification: Notification) = actionPerformed(e)
|
||||||
|
override fun actionPerformed(e: AnActionEvent) {
|
||||||
|
println("Submitting")
|
||||||
|
val editor = e.getData(CommonDataKeys.EDITOR)
|
||||||
|
e.project?.let { project ->
|
||||||
|
if (editor == null) {
|
||||||
|
NotificationGroupManager.getInstance()
|
||||||
|
.getNotificationGroup("sdom.notifications")
|
||||||
|
.createNotification("You have to select a file", NotificationType.ERROR)
|
||||||
|
.setTitle("No file selected")
|
||||||
|
.addAction(SDSubmitAction("Retry"))
|
||||||
|
.notify(e.project)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val currentFile = editor.document.text
|
||||||
|
val fileName = editor.document.getVirtualFile().name
|
||||||
|
|
||||||
|
val contest = SDom.currentContest
|
||||||
|
if (contest == null) {
|
||||||
|
NotificationGroupManager.getInstance()
|
||||||
|
.getNotificationGroup("sdom.notifications")
|
||||||
|
.createNotification("You have to select a contest", NotificationType.ERROR)
|
||||||
|
.setTitle("No contest selected")
|
||||||
|
.addAction(SDContestSelectionNotificationAction("Select Contest"))
|
||||||
|
.addAction(SDSubmitAction("Retry"))
|
||||||
|
.notify(e.project)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val problem = SDom.currentProblem
|
||||||
|
if (problem == null) {
|
||||||
|
NotificationGroupManager.getInstance()
|
||||||
|
.getNotificationGroup("sdom.notifications")
|
||||||
|
.createNotification("You have to select a problem", NotificationType.ERROR)
|
||||||
|
.setTitle("No problem selected")
|
||||||
|
.addAction(SDProblemSelectionNotificationAction("Select Problem"))
|
||||||
|
.addAction(SDSubmitAction("Retry"))
|
||||||
|
.notify(e.project)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
CoroutineScope(Job() + Dispatchers.IO).launch {
|
||||||
|
val result = SDom.submitSolution(contest, problem, currentFile, fileName)
|
||||||
|
println(result.first())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val icon = AllIcons.Actions.Upload
|
||||||
|
override fun update(e: AnActionEvent) {
|
||||||
|
e.presentation.isEnabledAndVisible = e.project != null
|
||||||
|
e.presentation.icon = icon
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val LOG = Logger.getInstance(SDSubmitAction::class.java).apply {
|
||||||
|
setLevel(LogLevel.DEBUG)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package io.gitlab.jfronny.sdom.model
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class SDAddSubmission(
|
||||||
|
val problem: String?,
|
||||||
|
@SerialName("problem_id") val problemId: String?,
|
||||||
|
val language: String?,
|
||||||
|
@SerialName("language_id") val languageId: String?,
|
||||||
|
//@SerialName("team_id") val teamId: String? = null,
|
||||||
|
//@SerialName("user_id") val userId: String? = null,
|
||||||
|
//val time: String? = null, // DateTime
|
||||||
|
@SerialName("entry_point") val entryPoint: String?,
|
||||||
|
//val id: String? = null,
|
||||||
|
val files: List<SDAddSubmissionFile>,
|
||||||
|
//val code: List<String>?, // binary
|
||||||
|
)
|
@ -0,0 +1,9 @@
|
|||||||
|
package io.gitlab.jfronny.sdom.model
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class SDAddSubmissionFile(
|
||||||
|
val data: String,
|
||||||
|
val mime: String? = "application/zip"
|
||||||
|
)
|
18
src/main/kotlin/io/gitlab/jfronny/sdom/model/SDJudgement.kt
Normal file
18
src/main/kotlin/io/gitlab/jfronny/sdom/model/SDJudgement.kt
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package io.gitlab.jfronny.sdom.model
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class SDJudgement(
|
||||||
|
@SerialName("start_time") val startTime: String?,
|
||||||
|
@SerialName("start_contest_time") val startContestTime: String,
|
||||||
|
@SerialName("end_time") val endTime: String?,
|
||||||
|
@SerialName("end_contest_time") val endContestTime: String?,
|
||||||
|
@SerialName("submission_id") val submissionId: String,
|
||||||
|
val id: String,
|
||||||
|
val valid: Boolean,
|
||||||
|
@SerialName("judgement_type_id") val judgementTypeId: String?,
|
||||||
|
@SerialName("judgehost") val judgeHost: String?,
|
||||||
|
@SerialName("max_run_time") val maxRunTime: Float?,
|
||||||
|
)
|
@ -0,0 +1,8 @@
|
|||||||
|
package io.gitlab.jfronny.sdom.model
|
||||||
|
|
||||||
|
data class SDJudgementType(
|
||||||
|
val id: String,
|
||||||
|
val name: String,
|
||||||
|
val penalty: Boolean,
|
||||||
|
val solved: Boolean
|
||||||
|
)
|
@ -9,7 +9,7 @@ data class SDLoginResult(
|
|||||||
@SerialName("last_api_login_time") val lastApiLoginTime: String?, // DateTime
|
@SerialName("last_api_login_time") val lastApiLoginTime: String?, // DateTime
|
||||||
@SerialName("first_login_time") val firstLoginTime: String?, // DateTime
|
@SerialName("first_login_time") val firstLoginTime: String?, // DateTime
|
||||||
val team: String?,
|
val team: String?,
|
||||||
@SerialName("team_id") val teamId: Int?,
|
@SerialName("team_id") val teamId: String?,
|
||||||
val roles: List<String>,
|
val roles: List<String>,
|
||||||
val type: String?,
|
val type: String?,
|
||||||
val id: String,
|
val id: String,
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
package io.gitlab.jfronny.sdom.model
|
|
||||||
|
|
||||||
class SDResult {
|
|
||||||
}
|
|
16
src/main/kotlin/io/gitlab/jfronny/sdom/model/SDSubmission.kt
Normal file
16
src/main/kotlin/io/gitlab/jfronny/sdom/model/SDSubmission.kt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package io.gitlab.jfronny.sdom.model
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
|
||||||
|
data class SDSubmission(
|
||||||
|
@SerialName("language_id") val languageId: String,
|
||||||
|
val time: String,
|
||||||
|
@SerialName("contest_time") val contestTime: String,
|
||||||
|
@SerialName("team_id") val teamId: String,
|
||||||
|
@SerialName("problem_id") val problemId: String,
|
||||||
|
val files: List<FileWithName>?,
|
||||||
|
val id: String,
|
||||||
|
@SerialName("external_id") val externalId: String?,
|
||||||
|
@SerialName("entry_point") val entryPoint: String?,
|
||||||
|
@SerialName("import_error") val importError: String?,
|
||||||
|
)
|
@ -5,8 +5,10 @@ import com.intellij.openapi.project.Project
|
|||||||
import com.intellij.openapi.wm.ToolWindow
|
import com.intellij.openapi.wm.ToolWindow
|
||||||
import com.intellij.openapi.wm.ToolWindowFactory
|
import com.intellij.openapi.wm.ToolWindowFactory
|
||||||
import io.gitlab.jfronny.sdom.SDom
|
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.Problem
|
||||||
import io.gitlab.jfronny.sdom.model.SDResult
|
import io.gitlab.jfronny.sdom.model.SDJudgement
|
||||||
|
import io.gitlab.jfronny.sdom.ui.SDResultPanel
|
||||||
import io.gitlab.jfronny.sdom.ui.SDSubmitPanel
|
import io.gitlab.jfronny.sdom.ui.SDSubmitPanel
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
@ -30,8 +32,13 @@ class SDToolWindowFactory : ToolWindowFactory, DumbAware {
|
|||||||
contentManager.addContent(loggedOutContent)
|
contentManager.addContent(loggedOutContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showResultContent(resultFlow: Flow<Result<SDResult>>, task: Problem) {
|
fun showResultContent(resultFlow: Flow<Result<SDJudgement>>, contest: Contest, problem: Problem) {
|
||||||
|
val resultPanel = SDResultPanel(project, resultFlow, contest, problem)
|
||||||
|
val resultContent = contentManager.factory.createContent(resultPanel.component, "Result", false).apply {
|
||||||
|
preferredFocusableComponent = resultPanel.preferredFocusableComponent
|
||||||
|
}
|
||||||
|
contentManager.addContent(resultContent)
|
||||||
|
contentManager.setSelectedContent(resultContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
SDom.registerLoginListener(::showSubmitContent)
|
SDom.registerLoginListener(::showSubmitContent)
|
||||||
|
@ -2,23 +2,53 @@ package io.gitlab.jfronny.sdom.ui
|
|||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.ui.ComponentContainer
|
import com.intellij.openapi.ui.ComponentContainer
|
||||||
import io.gitlab.jfronny.sdom.model.SDResult
|
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.Flow
|
||||||
|
import kotlinx.coroutines.flow.first
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import java.awt.BorderLayout
|
||||||
import javax.swing.JComponent
|
import javax.swing.JComponent
|
||||||
|
import javax.swing.JLabel
|
||||||
|
import javax.swing.JPanel
|
||||||
|
|
||||||
class SDResultPanel(
|
class SDResultPanel(
|
||||||
val project: Project,
|
val project: Project,
|
||||||
resultFlow: Flow<Result<SDResult>>
|
resultFlow: Flow<Result<SDJudgement>>,
|
||||||
|
contest: Contest,
|
||||||
|
problem: Problem,
|
||||||
) : ComponentContainer {
|
) : ComponentContainer {
|
||||||
override fun dispose() {
|
private val panel = JPanel(BorderLayout())
|
||||||
TODO("Not yet implemented")
|
|
||||||
|
init {
|
||||||
|
CoroutineScope(Job() + Dispatchers.IO).launch {
|
||||||
|
val resultResult = resultFlow.first()
|
||||||
|
|
||||||
|
if (resultResult.isSuccess) {
|
||||||
|
val result = resultResult.getOrThrow()
|
||||||
|
if (!result.valid) {
|
||||||
|
panel.add(JLabel("Judgement failed"), BorderLayout.CENTER)
|
||||||
|
return@launch
|
||||||
|
}
|
||||||
|
val parsedResult =
|
||||||
|
result.judgementTypeId
|
||||||
|
?.let { SDom.judgementTypes?.get(it) }
|
||||||
|
?.let { it.name to it.solved }
|
||||||
|
?: ("Unknown" to false)
|
||||||
|
panel.add(JLabel(parsedResult.first).apply { foreground = if (parsedResult.second) JBColor.GREEN else JBColor.RED }, BorderLayout.CENTER)
|
||||||
|
} else {
|
||||||
|
panel.add(JLabel("Judgement failed"), BorderLayout.CENTER)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getComponent(): JComponent {
|
override fun dispose() {}
|
||||||
TODO("Not yet implemented")
|
override fun getComponent(): JComponent = panel
|
||||||
}
|
override fun getPreferredFocusableComponent(): JComponent = panel // TODO focus on actual content once it's there
|
||||||
|
|
||||||
override fun getPreferredFocusableComponent(): JComponent {
|
|
||||||
TODO("Not yet implemented")
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -56,7 +56,11 @@
|
|||||||
text="Refresh Problems">
|
text="Refresh Problems">
|
||||||
<add-to-group group-id="io.gitlab.jfronny.sdom.actions.SDToolbarActions"/>
|
<add-to-group group-id="io.gitlab.jfronny.sdom.actions.SDToolbarActions"/>
|
||||||
</action>
|
</action>
|
||||||
<!-- TODO: add submission action -->
|
<action id="io.gitlab.jfronny.sdom.actions.SDSubmitAction"
|
||||||
|
class="io.gitlab.jfronny.sdom.actions.SDSubmitAction"
|
||||||
|
text="Submit Solution">
|
||||||
|
<add-to-group group-id="io.gitlab.jfronny.sdom.actions.SDToolbarActions"/>
|
||||||
|
</action>
|
||||||
<action class="io.gitlab.jfronny.sdom.actions.SDLogoutAction"
|
<action class="io.gitlab.jfronny.sdom.actions.SDLogoutAction"
|
||||||
id="io.gitlab.jfronny.sdom.actions.SDLogoutAction"
|
id="io.gitlab.jfronny.sdom.actions.SDLogoutAction"
|
||||||
text="Log out of DOMjudge"/>
|
text="Log out of DOMjudge"/>
|
||||||
|
Loading…
Reference in New Issue
Block a user