Skip to content

Commit

Permalink
Merge pull request online-go#2789 from GreenAsJade/final_action_time_…
Browse files Browse the repository at this point in the history
…into_game_summary_in_report

Final action time in Game Summary in Reports
  • Loading branch information
anoek authored Aug 20, 2024
2 parents b0677fe + 2e93e0d commit 21623e5
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 55 deletions.
14 changes: 14 additions & 0 deletions src/lib/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { browserHistory } from "ogsHistory";
import * as preferences from "preferences";
import { alert } from "swal_config";
import React from "react";
import moment from "moment";

export type Timeout = ReturnType<typeof setTimeout>;

Expand Down Expand Up @@ -655,6 +656,19 @@ export function getCurrentGameId() {
return null;
}

// needed because Game end_time and start_time are only to the nearest second
export function showSecondsResolution(duration: moment.Duration | null): string {
if (!duration) {
return "-";
} else if (duration < moment.duration(1000)) {
return `${moment.duration(duration).asSeconds().toFixed(2)}s`;
} else if (duration < moment.duration(60000)) {
return `${moment.duration(duration).asSeconds().toFixed(1)}s`;
} else {
return moment.duration(duration).format("d:h:m:s");
}
}

/* This code is hacked together from
https://github.com/simov/slugify/blob/master/slugify.js and
https://github.com/dodo/node-slug/blob/master/slug.js
Expand Down
32 changes: 32 additions & 0 deletions src/views/Game/GameLog.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (C) Online-Go.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

.GameLog {
td {
padding-right: 1rem;
border-bottom: 1px solid transparent;
themed border-bottom-color shade3
}

.timestamp {
width: 12rem;
}

.field {
margin-right: 1rem;
}
}
2 changes: 1 addition & 1 deletion src/views/Game/GameLog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export function GameLog({ goban_config, onContainsTimeout }: GameLogProps): JSX.
<h3>{_("Game Log")}</h3>
{log.length > 0 ? (
<>
<table className="game-log">
<table className="GameLog">
<thead>
<tr>
<th>
Expand Down
14 changes: 0 additions & 14 deletions src/views/Game/GameLogModal.styl
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,4 @@
width: 90vw;
min-width: 90vw;
max-width: 90vw;

td {
padding-right: 1rem;
border-bottom: 1px solid transparent;
themed border-bottom-color shade3
}

.timestamp {
width: 12rem;
}

.field {
margin-right: 1rem;
}
}
1 change: 0 additions & 1 deletion src/views/Game/GameLogModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ export class GameLogModal extends Modal<Events, GameLogModalProperties, { log: A
}

setLog(log: Array<LogEntry>) {
console.log(log);
this.setState({ log });
}

Expand Down
26 changes: 14 additions & 12 deletions src/views/Game/GameTimings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import * as React from "react";

import { AdHocPackedMove, GobanMovesArray } from "goban";
import { useUser } from "hooks";
import { showSecondsResolution } from "misc";

interface GameTimingProperties {
moves: GobanMovesArray;
Expand All @@ -31,6 +32,7 @@ interface GameTimingProperties {
handicap: number;
black_id: number;
white_id: number;
onFinalActionCalculated?: (final_action_timing: moment.Duration) => void;
}

export function GameTimings(props: GameTimingProperties): JSX.Element {
Expand All @@ -47,22 +49,22 @@ export function GameTimings(props: GameTimingProperties): JSX.Element {
<span className="timing-slow">{moment.duration(duration).format()}</span>
);

// needed because end_time and start_time are only to the nearest second
const show_seconds_resolution = (duration: moment.Duration): string => {
if (duration < moment.duration(1000)) {
return `${moment.duration(duration).asSeconds().toFixed(2)}s`;
} else if (duration < moment.duration(60000)) {
return `${moment.duration(duration).asSeconds().toFixed(1)}s`;
} else {
return moment.duration(duration).format("d:h:m:s");
}
};

const game_elapsed: ReturnType<typeof moment.duration> = moment.duration(0); // running total
const black_elapsed: ReturnType<typeof moment.duration> = moment.duration(0);
const white_elapsed: ReturnType<typeof moment.duration> = moment.duration(0);
const move_elapsed: Array<ReturnType<typeof moment.duration>> = []; // the time elapsed up to each move

// Publish final action timing after game_elapsed is calculated (during render!)
React.useEffect(() => {
if (props.end_time && props.onFinalActionCalculated) {
props.onFinalActionCalculated(
moment
.duration(props.end_time - props.start_time, "seconds")
.subtract(game_elapsed),
);
}
}, [props.start_time, props.end_time, props.onFinalActionCalculated]);

let non_handicap_moves = [...props.moves];
let handicap_moves: any[] = [];
let handicap_move_offset = 0;
Expand Down Expand Up @@ -244,7 +246,7 @@ export function GameTimings(props: GameTimingProperties): JSX.Element {
<div className="span-3 final-action-row">Final action:</div>
<div className="final-action-row">
{props.end_time &&
show_seconds_resolution(
showSecondsResolution(
moment
.duration(props.end_time - props.start_time, "seconds")
.subtract(game_elapsed),
Expand Down
63 changes: 37 additions & 26 deletions src/views/ReportsCenter/ReportedGame.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@
*/

import * as React from "react";
import * as moment from "moment";
import { useRefresh } from "hooks";
import { _, pgettext } from "translate";
import { Link } from "react-router-dom";
import { MiniGoban } from "MiniGoban";
import { alert } from "swal_config";
import { post, get } from "requests";
import { errorAlerter } from "misc";
import { errorAlerter, showSecondsResolution } from "misc";
import { doAnnul } from "moderation";

import {
Expand All @@ -33,14 +34,14 @@ import {
GobanContext,
useCurrentMove,
game_control,
GameLog,
} from "Game";
import { GobanRenderer } from "goban";
import { Resizable } from "Resizable";

import { Player } from "Player";
import { useUser } from "hooks";
import { shortTimeControl } from "TimeControl";
import { GameLog } from "../Game/GameLog";

export function ReportedGame({
game_id,
Expand All @@ -61,6 +62,7 @@ export function ReportedGame({
const [game, setGame] = React.useState<rest_api.GameDetails | null>(null);
const [_aiReviewUuid, setAiReviewUuid] = React.useState<string | null>(null);
const [annulled, setAnnulled] = React.useState<boolean>(false);
const [finalActionTime, setFinalActionTime] = React.useState<moment.Duration | null>(null);
const [timedOutPlayer, setTimedOutPlayer] = React.useState<number | null>(null);

const user = useUser();
Expand Down Expand Up @@ -178,30 +180,39 @@ export function ReportedGame({
<div>White: {game && <Player user={game.white} />}</div>
<div>Game Phase: {goban.engine.phase}</div>
{(goban.engine.phase === "finished" || null) && (
<div>
{_("Game Outcome:") + ` ${winner} (`}
<Player user={goban!.engine.winner as number} />
{` ) ${pgettext("use like: they won 'by' this much", "by")} `}
{goban.engine.outcome}
{annulled ? _(" annulled") : ""}
</div>
)}
{timedOutPlayer && (
<div>
{_("Player timed out:")}
<Player user={timedOutPlayer} />
{timedOutPlayer === reported_by
? pgettext(
"A note of surprise telling a moderator that the person who timed out is the reporter",
" (reporter!)",
)
: pgettext(
"A label next to a player name telling a moderator that a they are the one who was reported",
" (reported)",
)}
</div>
)}
<>
<div>
{_("Game Outcome:") + ` ${winner} (`}
<Player user={goban!.engine.winner as number} />
{` ) ${pgettext(
"use like: they won 'by' this much",
"by",
)} `}
{goban.engine.outcome}
{annulled ? _(" annulled") : ""}
</div>
<div>
{_("The last event took: ") +
showSecondsResolution(finalActionTime)}
</div>

{timedOutPlayer && (
<div>
{_("Player timed out:")}
<Player user={timedOutPlayer} />
{timedOutPlayer === reported_by
? pgettext(
"A note of surprise telling a moderator that the person who timed out is the reporter",
" (reporter!)",
)
: pgettext(
"A label next to a player name telling a moderator that a they are the one who was reported",
" (the reported player)",
)}
</div>
)}
</>
)}
{user.is_moderator && (
<>
{goban.engine.phase === "finished" ? (
Expand Down Expand Up @@ -249,7 +260,6 @@ export function ReportedGame({
hidden={false}
/>
)}

<Resizable
id="move-tree-container"
className="vertically-resizable"
Expand All @@ -273,6 +283,7 @@ export function ReportedGame({
handicap={goban.engine.config.handicap as any}
black_id={goban.engine.config.black_player_id as any}
white_id={goban.engine.config.white_player_id as any}
onFinalActionCalculated={setFinalActionTime}
/>

<GameLog
Expand Down
3 changes: 2 additions & 1 deletion src/views/ReportsCenter/ReportsCenter.styl
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ reports_center_content_width=56rem
themed background-color shade5
}

.game-log {
// We have horizontal less room than `GameLog` expects
.GameLog {
tr {
vertical-align: top;
}
Expand Down

0 comments on commit 21623e5

Please sign in to comment.