Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Timeline #188

Merged
merged 21 commits into from
Jul 30, 2024
Merged

Added Timeline #188

merged 21 commits into from
Jul 30, 2024

Conversation

Mond1c
Copy link
Contributor

@Mond1c Mond1c commented Jul 18, 2024

No description provided.

@Mond1c Mond1c marked this pull request as draft July 18, 2024 12:26
@Mond1c Mond1c force-pushed the timeline branch 2 times, most recently from e698af6 to e8b8b80 Compare July 19, 2024 06:28
Copy link

Playwright tests screens

Copy link

Playwright tests screens

TimeLineRunInfo.InProgress(info.time, info.problemId)
}
}
}.filterNotNull()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use mapNotNull instead


is RunResult.IOI -> {
val ioiResult = info.result as RunResult.IOI
TimeLineRunInfo.IOI(info.time, info.problemId, ioiResult.scoreAfter)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we should use scoreAfter or score difference here. With score after, maybe we can show only improvements.

is RunResult.ICPC -> {
val icpcResult = info.result as RunResult.ICPC
if (!acceptedProblems.contains(info.problemId)) {
if (icpcResult.verdict == Verdict.Accepted) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to use .isAccepted instead of equality check

@@ -28,13 +29,52 @@ fun Route.configureOverlayRouting() {
flowEndpoint("/mainScreen") { DataBus.mainScreenFlow.await() }
flowEndpoint("/contestInfo") { DataBus.currentContestInfoFlow() }
flowEndpoint("/runs") { DataBus.contestStateFlow.await().map { it.runsAfterEvent.values.sortedBy { it.time } } }
webSocket("/teamRuns") {
val teamIdStr = (incoming.receive() as? Frame.Text)?.readText()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we don't want to be able to subscribe to more teams over the existing webSocket, why send this instead of adding to name?

}
val teamId = teamIdStr.toTeamId()
sendJsonFlow(DataBus.contestStateFlow.await().map { state ->
state.runsAfterEvent.values.filter { it.teamId == teamId }
Copy link
Contributor

@kunyavskiy kunyavskiy Jul 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a bit too time-consuming. Probably we should process events ourselves, ignoring events except known teams.

Something like (didn't run or test to be compilable, just as main idea)

contestStateFlow
.mapNotNull { (it.event as? RunEvent)?.newInfo }
.runningFold(persistentMapOf<RunId, RunInfo>()) { acc, it ->
   if (it.teamId == teamId) acc.put(it.id, it) else if (it.runId in acc) acc.remove(it.runId) else acc
}
.distintUntilChanged { a, b -> a === b }
.map { it.value.sortedBy { it.time } }

@Mond1c Mond1c marked this pull request as ready for review July 21, 2024 08:29
Copy link

Playwright tests screens

Copy link

Playwright tests screens

val acceptedProblems = mutableSetOf<ProblemId>()
val allRuns = mutableMapOf<RunId, RunInfo>()
DataBus.contestStateFlow.await().first().runsAfterEvent.values
.filter { teamId == it.teamId && it.time.toLong(DurationUnit.MILLISECONDS) != 0L }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

!= Duration.ZERO

val teamId = teamIdStr.toTeamId()
val acceptedProblems = mutableSetOf<ProblemId>()
val allRuns = mutableMapOf<RunId, RunInfo>()
DataBus.contestStateFlow.await().first().runsAfterEvent.values
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tbh, I don't like how it ended, but let's proceed with this, I'll rewrite this part later, not sure how exactly.

return (
<ProblemWrap left={left + "%"}>
<Circle color={getColor(problemResult)}>
<Label darkText={darkText} isBold={problemResult.type === "IN_PROGRESS"}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use generated ts constants instead. You can add class into list in build.gradle.kts ins scheme generator, if it is not generated.

Copy link

Playwright tests screens

Comment on lines 81 to 95
const TextWithAnimation = styled.div`
animation: ${ChangeTextAnimation} 10s infinite;
justify-content: center;
position: absolute;
align-items: center;
text-align: center;
`;

const TextWithAnimation2 = styled.div`
animation: ${ChangeTextAnimation2} 10s infinite;
justify-content: center;
position: absolute;
align-items: center;
text-align: center;
font-size: 12px;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Может, придумать какие-то более разумные названия?

@@ -0,0 +1,182 @@
import React, { useEffect, useState } from "react";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Может, сразу назвать файл TimeLine.tsx и навесить типы?

Comment on lines 111 to 124
const getColor = (problemResult) => {
if (problemResult.type === RunResult.Type.IN_PROGRESS) {
return c.VERDICT_UNKNOWN;
} else if (problemResult.type === RunResult.Type.ICPC) {
if (problemResult.isAccepted) {
return c.VERDICT_OK;
} else {
return c.VERDICT_NOK;
}
} else {
const task = contestInfo.problems.find(info => info.letter === problemResult.problemId);
return getIOIColor(problemResult.score, task?.minScore, task?.maxScore);
}
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Наверное, можно наружу от функции компонента вынести? Ну или useMemo?

useEffect(() => {
const socket = new WebSocket(c.BASE_URL_WS + "/teamRuns/" + teamId);
socket.onopen = function () {
console.log("WebSocket is open");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Здесь и ниже может быь лучше console.debug + добавить какую-то информацию про то, что за вебсокет?

Copy link

Playwright tests screens

@Mond1c Mond1c merged commit 2ab162a into main Jul 30, 2024
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants