Skip to content

Commit

Permalink
Merge commit '91b51f4fdf4253c1d09ccd1398e31ad759af955b' into redo_rep…
Browse files Browse the repository at this point in the history
…orted_game_layout

# Conflicts:
#	src/views/ReportsCenter/ReportedGame.tsx
  • Loading branch information
GreenAsJade committed Aug 22, 2024
2 parents 37e4e3f + 91b51f4 commit ac127e7
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 39 deletions.
19 changes: 16 additions & 3 deletions src/views/Game/GameLog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,15 @@ const TRUNCATED_GAME_LOG_LENGTH = 25;

interface GameLogProps {
goban_config: GobanEngineConfig;
onContainsTimeout?: (player_id: number) => void;
onContainsTimeout?: (player_id: number | null) => void;
onContainsAbandonment?: (contains_abandonment: boolean) => void;
}

export function GameLog({ goban_config, onContainsTimeout }: GameLogProps): JSX.Element {
export function GameLog({
goban_config,
onContainsTimeout,
onContainsAbandonment,
}: GameLogProps): JSX.Element {
const [log, setLog] = React.useState<LogEntry[]>([]);
const [shouldDisplayFullLog, setShouldDisplayFullLog] = React.useState(false);

Expand All @@ -42,11 +47,19 @@ export function GameLog({ goban_config, onContainsTimeout }: GameLogProps): JSX.
React.useEffect(() => {
socket.send(`game/log`, { game_id }, (log) => {
setLog(log);

onContainsTimeout && onContainsTimeout(null);
onContainsAbandonment && onContainsAbandonment(false);
const timeout_entry = log.find((entry) => entry.event === "timed_out");
if (timeout_entry && onContainsTimeout) {
onContainsTimeout(timeout_entry.data.player_id);
}
const abandoned_entry = log.find(
(entry) => entry.event === "force_stone_removal_acceptance_abandoned",
);
if (abandoned_entry && onContainsAbandonment) {
console.log("GameLog: Found an abandonment event");
onContainsAbandonment(true);
}
});
}, [game_id]);

Expand Down
88 changes: 64 additions & 24 deletions src/views/ReportsCenter/ReportedGame.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/

import * as React from "react";
import * as moment from "moment";
import { useRefresh } from "hooks";
import { _, pgettext } from "translate";
import { Link } from "react-router-dom";
Expand All @@ -33,14 +34,15 @@ import {
GobanContext,
useCurrentMove,
game_control,
GameLog,
useGoban,
} 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,7 +63,9 @@ 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 [scoringAbandoned, setScoringAbandoned] = React.useState<boolean>(false);

const user = useUser();

Expand Down Expand Up @@ -178,30 +182,15 @@ 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>
<GameSummary
winner={winner}
finalActionTime={finalActionTime}
timedOutPlayer={timedOutPlayer}
reported_by={reported_by}
annulled={annulled}
scoringAbandoned={scoringAbandoned}
/>
)}

{user.is_moderator && (
<>
{goban.engine.phase === "finished" ? (
Expand Down Expand Up @@ -273,11 +262,13 @@ 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
goban_config={goban.config}
onContainsTimeout={setTimedOutPlayer}
onContainsAbandonment={setScoringAbandoned}
/>
</div>

Expand All @@ -295,3 +286,52 @@ export function ReportedGame({
</div>
);
}

interface GameSummaryProps {
winner: string;
finalActionTime: moment.Duration | null;
timedOutPlayer: number | null;
reported_by: number;
annulled: boolean;
scoringAbandoned: boolean;
}

function GameSummary({
winner,
finalActionTime,
timedOutPlayer,
reported_by,
annulled,
scoringAbandoned,
}: GameSummaryProps): JSX.Element {
const goban = useGoban();
return (
<div className="GameSummary">
<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>
)}
{scoringAbandoned && <div>{_("Scoring abandoned by both players")}</div>}
</div>
);
}
21 changes: 9 additions & 12 deletions src/views/ReportsCenter/ReportsCenterCMDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ function startOfWeek(the_date: Date): Date {
const EXPECTED_MAX_WEEKLY_CM_REPORTS = 160;
const Y_STEP_SIZE = 40; // must divide evenly into EXPECTED_MAX_WEEKLY_CM_REPORTS

interface CMVotingOutcomeGraphProps {
interface CMVoteCountGraphProps {
vote_data: ReportCount[];
period: number;
}
const CMVotingOutcomeGraph = ({ vote_data, period }: CMVotingOutcomeGraphProps): JSX.Element => {
const CMVoteCountGraph = ({ vote_data, period }: CMVoteCountGraphProps): JSX.Element => {
if (!vote_data) {
vote_data = [];
}
Expand Down Expand Up @@ -338,8 +338,8 @@ export function ReportsCenterCMDashboard(): JSX.Element {
<TabList>
<Tab disabled={!user.moderator_powers}>My Summary</Tab>
<Tab>Group Outcomes</Tab>
<Tab disabled={!user.is_moderator}>Individual Outcomes</Tab>
<Tab disabled={!user.moderator_powers}>My Outcomes</Tab>
<Tab disabled={!user.is_moderator}>Individual Votes</Tab>
<Tab disabled={!user.moderator_powers}>My Votes</Tab>
</TabList>

{/* A CM's Summary Pie Charts */}
Expand Down Expand Up @@ -390,7 +390,7 @@ export function ReportsCenterCMDashboard(): JSX.Element {
<div key={report_type}>
<h3>{report_type}</h3>
{vote_data[report_type] ? (
<CMVotingOutcomeGraph
<CMVoteCountGraph
vote_data={vote_data[report_type]}
period={120}
/>
Expand All @@ -402,7 +402,7 @@ export function ReportsCenterCMDashboard(): JSX.Element {
: "loading..."}
</TabPanel>

{/* Moderator view of each CM's voting outcomes */}
{/* Moderator view of each CM's vote categories */}
<TabPanel>
<PaginatedTable
pageSize={4} /* Limit aggregation compute load */
Expand All @@ -420,24 +420,21 @@ export function ReportsCenterCMDashboard(): JSX.Element {
header: "summaries",
className: () => "votes",
render: (X) => (
<CMVotingOutcomeGraph
vote_data={X.vote_data["overall"]}
period={120}
/>
<CMVoteCountGraph vote_data={X.vote_data["overall"]} period={120} />
),
},
]}
/>
</TabPanel>

{/* A CM's individual voting outcomes */}
{/* A CM's individual vote categories (My Votes) */}
<TabPanel>
{users_data
? ["overall", "escaping", "stalling", "score_cheating"].map((report_type) => (
<div key={report_type}>
<h3>{report_type}</h3>
{users_data[report_type] ? (
<CMVotingOutcomeGraph
<CMVoteCountGraph
vote_data={users_data[report_type]}
period={120}
/>
Expand Down

0 comments on commit ac127e7

Please sign in to comment.