Skip to content

Commit

Permalink
Merge pull request #2797 from GreenAsJade/next_step_reported_game_rel…
Browse files Browse the repository at this point in the history
…ayout

Next step in `ReportedGame` relayout
  • Loading branch information
anoek authored Aug 23, 2024
2 parents e23c16a + 6e35b77 commit 0fa3c89
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 112 deletions.
49 changes: 34 additions & 15 deletions src/views/ReportsCenter/ReportedGame.styl
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,12 @@
margin-bottom: 0;
}

.reported-game-info {
order: -1; // put this first so mobile layout is nice
.reported-turn {
padding: 0.25rem;
}
}

.reported-game-mini-goban {
.MiniGoban {
justify-content: flex-start;
}
}

.col {
.reported-game-element {
flex: 1;
flex-basis: 45%;
flex-basis: 40%;
display: inline-flex;
min-width: 20rem;
max-width: 30rem;
flex-direction: column;
align-items: stretch;
justify-content: stretch;
Expand All @@ -41,6 +29,37 @@
}
}

.reported-game-mini-goban {
max-width: 20rem;
max-height: 20rem;
padding: 2rem;
}

#move-tree-container {
height: 2rem;
}

.reported-game-info {
order: -1; // put this first so mobile layout is nice
.reported-turn {
padding: 0.25rem;
}
}

.moderator-reported-game-actions {
padding: 0.5rem;
text-align: center;
}

.reported-game-chat {
max-width: 5rem;
max-height: 15rem;
}

.reported-game-timing {
text-align: center;
}

// We have horizontal less room than `GameLog` expects
.GameLog {
tr {
Expand Down
205 changes: 112 additions & 93 deletions src/views/ReportsCenter/ReportedGame.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,47 +67,6 @@ export function ReportedGame({
const [timedOutPlayer, setTimedOutPlayer] = React.useState<number | null>(null);
const [scoringAbandoned, setScoringAbandoned] = React.useState<boolean>(false);

const user = useUser();

const decide = React.useCallback(
(winner: string) => {
if (!game_id) {
void alert.fire(_("Game ID missing"));
return;
}

let moderation_note: string | null = null;
do {
moderation_note = prompt(
"Deciding for " + winner.toUpperCase() + " - Moderator note:",
);
if (moderation_note == null) {
return;
}
moderation_note = moderation_note.trim();
} while (moderation_note === "");

post(`games/${game_id}/moderate`, {
decide: winner,
moderation_note: moderation_note,
}).catch(errorAlerter);
},
[game_id, goban],
);

const do_annul = React.useCallback(
(tf: boolean): void => {
if (!game_id) {
void alert.fire(_("Game ID missing"));
return;
}

const engine = goban!.engine;
doAnnul(engine.config, tf);
},
[game_id, goban],
);

React.useEffect(() => {
if (goban) {
goban.on("update", refresh);
Expand Down Expand Up @@ -157,17 +116,37 @@ export function ReportedGame({
return (
<div className="reported-game">
<div className="reported-game-container">
<div className="col reported-game-mini-goban">
<div className="reported-game-element">
{/* This element is providing the goban used by the goban provider wrapped around the rest of them */}
<MiniGoban
className="reported-game-mini-goban"
game_id={game_id}
noLink={true}
onGobanCreated={onGobanCreated}
chat={true}
/>
{goban && goban.engine && (
<GobanContext.Provider value={goban}>
<Resizable
id="move-tree-container"
className="vertically-resizable"
ref={(ref) => ref?.div && goban.setMoveTreeContainer(ref.div)}
/>

<div className="reported-game-timing">
{`Time control: ${shortTimeControl(goban.engine.time_control)}`}
</div>
<ModeratorReportedGameActions
game_id={game_id}
goban={goban}
annulled={annulled}
/>
</GobanContext.Provider>
)}
</div>
{goban && goban.engine && (
<GobanContext.Provider value={goban}>
<div className="col reported-game-info">
<div className="reported-game-element reported-game-info">
<h3>
Game: <Link to={`/game/${game_id}`}>#{game_id}</Link>
<span className="created-note">
Expand All @@ -182,7 +161,7 @@ export function ReportedGame({
<div>White: {game && <Player user={game.white} />}</div>
<div>Game Phase: {goban.engine.phase}</div>
{(goban.engine.phase === "finished" || null) && (
<GameSummary
<GameOutcomeSummary
winner={winner}
finalActionTime={finalActionTime}
timedOutPlayer={timedOutPlayer}
Expand All @@ -191,39 +170,7 @@ export function ReportedGame({
scoringAbandoned={scoringAbandoned}
/>
)}
{user.is_moderator && (
<>
{goban.engine.phase === "finished" ? (
<div className="decide-buttons">
{goban.engine.config.ranked && !annulled && (
<button onClick={() => do_annul(true)}>
{_("Annul")}
</button>
)}
{goban.engine.config.ranked && annulled && (
<button onClick={() => do_annul(false)}>
{_("Remove annulment")}
</button>
)}
</div>
) : (
<div className="decide-buttons">
<button
className="decide-button"
onClick={() => decide("black")}
>
Black ({goban.engine.players?.black?.username}) Wins
</button>
<button
className="decide-button"
onClick={() => decide("white")}
>
White ({goban.engine.players?.white?.username}) Wins
</button>
</div>
)}
</>
)}

{cur_move &&
((goban.engine.phase === "finished" &&
goban.engine.game_id === game_id &&
Expand All @@ -238,20 +185,9 @@ export function ReportedGame({
hidden={false}
/>
)}

<Resizable
id="move-tree-container"
className="vertically-resizable"
ref={(ref) => ref?.div && goban.setMoveTreeContainer(ref.div)}
/>
{!!goban?.engine && (
<div className="reported-game-timing">
{`Time control: ${shortTimeControl(goban.engine.time_control)}`}
</div>
)}
</div>

<div className="col">
<div className="reported-game-element">
<GameTimings
moves={goban.engine.config.moves as any}
start_time={goban.engine.config.start_time as any}
Expand All @@ -272,7 +208,7 @@ export function ReportedGame({
/>
</div>

<div className="col">
<div className="reported-game-element reported-game-chat">
<GameChat
selected_chat_log={selectedChatLog}
onSelectedChatModeChange={setSelectedChatLog}
Expand All @@ -287,7 +223,90 @@ export function ReportedGame({
);
}

interface GameSummaryProps {
interface ModeratorReportedGameActionsProps {
game_id: number;
goban: GobanRenderer;
annulled: boolean;
}

function ModeratorReportedGameActions({
game_id,
goban,
annulled,
}: ModeratorReportedGameActionsProps): JSX.Element {
const user = useUser();

const decide = React.useCallback(
(winner: string) => {
if (!game_id) {
void alert.fire(_("Game ID missing"));
return;
}

let moderation_note: string | null = null;
do {
moderation_note = prompt(
"Deciding for " + winner.toUpperCase() + " - Moderator note:",
);
if (moderation_note == null) {
return;
}
moderation_note = moderation_note.trim();
} while (moderation_note === "");

post(`games/${game_id}/moderate`, {
decide: winner,
moderation_note: moderation_note,
}).catch(errorAlerter);
},
[game_id, goban],
);

const do_annul = React.useCallback(
(tf: boolean): void => {
if (!game_id) {
void alert.fire(_("Game ID missing"));
return;
}

const engine = goban!.engine;
doAnnul(engine.config, tf);
},
[game_id, goban],
);

return (
<div className="moderator-reported-game-actions">
{user.is_moderator && (
<>
{goban.engine.phase === "finished" ? (
<div className="decide-buttons">
{goban.engine.config.ranked && !annulled && (
<button onClick={() => do_annul(true)}>{_("Annul")}</button>
)}
{goban.engine.config.ranked && annulled && (
<button onClick={() => do_annul(false)}>
{_("Remove annulment")}
</button>
)}
</div>
) : (
<div className="decide-buttons">
<button className="decide-button" onClick={() => decide("black")}>
Black ({goban.engine.players?.black?.username}) Wins
</button>
<button className="decide-button" onClick={() => decide("white")}>
White ({goban.engine.players?.white?.username}) Wins
</button>
</div>
)}
</>
)}
</div>
);
}

interface GameOutcomeSummaryProps {
winner: string;
finalActionTime: moment.Duration | null;
timedOutPlayer: number | null;
Expand All @@ -296,14 +315,14 @@ interface GameSummaryProps {
scoringAbandoned: boolean;
}

function GameSummary({
function GameOutcomeSummary({
winner,
finalActionTime,
timedOutPlayer,
reported_by,
annulled,
scoringAbandoned,
}: GameSummaryProps): JSX.Element {
}: GameOutcomeSummaryProps): JSX.Element {
const goban = useGoban();
return (
<div className="GameSummary">
Expand Down
4 changes: 0 additions & 4 deletions src/views/ReportsCenter/ReportsCenter.styl
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,6 @@ reports_center_content_width=56rem
}
}

#move-tree-container {
height: 2rem;
}

.notes-container {
display: flex;
flex: 1;
Expand Down

0 comments on commit 0fa3c89

Please sign in to comment.