Skip to content

Commit

Permalink
Merged PR 281: v1.18.0 - reorder players feature, highlight current c…
Browse files Browse the repository at this point in the history
…ycle (#220)

- Add a dialog that lets you reorder players under Actions | Player Management | Reorder Players... (#203)
- Highlight the current cycle in the Event Log and underline the number for the selected cycle (#206)
- Simplify tossup get message in Event Log (remove buzz position info) to reduce clutter (partial #211)
- Bump version to 1.18.0
  • Loading branch information
alopezlago authored Jun 2, 2023
1 parent f4d3499 commit 9056519
Show file tree
Hide file tree
Showing 10 changed files with 706 additions and 12 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "modaq",
"version": "1.17.0",
"version": "1.18.0",
"description": "Quiz Bowl Reader using TypeScript, React, and MobX",
"repository": {
"type": "git",
Expand Down
52 changes: 47 additions & 5 deletions src/components/EventViewer.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import * as React from "react";
import { observer } from "mobx-react-lite";
import { DetailsList, CheckboxVisibility, SelectionMode, IColumn, Label, Text } from "@fluentui/react";
import { DetailsList, CheckboxVisibility, SelectionMode, IColumn, Label, Text, ISelection } from "@fluentui/react";
import { mergeStyleSets } from "@fluentui/react";

import { CycleItemList } from "./cycleItems/CycleItemList";
import { Cycle } from "../state/Cycle";
import { AppState } from "../state/AppState";
import { GameState } from "../state/GameState";
import { StateContext } from "../contexts/StateContext";

const numberKey = "number";
const cycleKey = "cycle";

// Needed for filling in dummy values into an interface
// eslint-disable-next-line @typescript-eslint/no-empty-function
function dummyFunction() {}

export const EventViewer = observer(function EventViewer(): JSX.Element | null {
const appState: AppState = React.useContext(StateContext);
const classes: IEventViewerClassNames = getClassNames(appState.uiState.isEventLogHidden);
Expand All @@ -31,7 +34,7 @@ export const EventViewer = observer(function EventViewer(): JSX.Element | null {
return <></>;
}

return onRenderItemColumn(item, appState.game, index, column);
return onRenderItemColumn(item, appState, index, column);
},
[appState]
);
Expand All @@ -46,6 +49,7 @@ export const EventViewer = observer(function EventViewer(): JSX.Element | null {
ariaLabel: "Question number",
isResizable: true,
isRowHeader: true,
data: appState.uiState.cycleIndex,
},
{
key: cycleKey,
Expand All @@ -63,6 +67,35 @@ export const EventViewer = observer(function EventViewer(): JSX.Element | null {
},
];

// DetailsList doesn't know how to change its selection when the cycle index changes unless we tell it how to select it
const selection: ISelection = {
count: 1,
mode: SelectionMode.single,
canSelectItem: () => true,
setChangeEvents: dummyFunction,
setItems: dummyFunction,
getItems: () => [],
getSelection: () => [{}],
getSelectedIndices: () => [appState.uiState.cycleIndex],
getSelectedCount: () => 1,
isRangeSelected: (): boolean => false,
isAllSelected: () => appState.uiState.cycleIndex === appState.game.playableCycles.length,
isIndexSelected: (index) => index === appState.uiState.cycleIndex,
isKeySelected: () => false,
setAllSelected: dummyFunction,
setKeySelected: dummyFunction,
setIndexSelected: (index: number): void => appState.uiState.setCycleIndex(index),
selectToKey: dummyFunction,
selectToIndex: (index: number): void => appState.uiState.setCycleIndex(index),
toggleAllSelected: dummyFunction,
toggleKeySelected: dummyFunction,
toggleIndexSelected: (index: number): void => {
appState.uiState.setCycleIndex(index);
},
toggleRangeSelected: dummyFunction,
};

// This needs to re-render based on cycleIndex so it can select the current one
return (
<div className={classes.eventViewerContainer} data-is-scrollable="true">
<DetailsList
Expand All @@ -72,26 +105,35 @@ export const EventViewer = observer(function EventViewer(): JSX.Element | null {
items={appState.game.playableCycles}
onActiveItemChanged={activeItemChangedHandler}
onRenderItemColumn={renderColumnHandler}
selection={selection}
/>
</div>
);
});

function onRenderItemColumn(item: Cycle, game: GameState, index: number, column: IColumn): JSX.Element {
function onRenderItemColumn(item: Cycle, appState: AppState, index: number, column: IColumn): JSX.Element {
switch (column?.key) {
case numberKey:
if (index == undefined) {
return <></>;
}

if (column?.data === index) {
return (
<u>
<Label>{index + 1}</Label>
</u>
);
}

return <Label>{index + 1}</Label>;
case cycleKey:
const scores: [number, number][] = column.data;
const scoreInCurrentCycle: [number, number] = scores[index];

return (
<>
<CycleItemList cycle={item} game={game} />
<CycleItemList cycle={item} game={appState.game} />
<Text>{`(${scoreInCurrentCycle[0]} - ${scoreInCurrentCycle[1]})`}</Text>
</>
);
Expand Down
21 changes: 18 additions & 3 deletions src/components/GameBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ export const GameBar = observer(function GameBar(): JSX.Element {

const openHelpHandler = React.useCallback(() => appState.uiState.dialogState.showHelpDialog(), [appState]);

const reorderPlayersHandler = React.useCallback(() => {
uiState.dialogState.showReorderPlayersDialog(game.players);
}, [uiState, game]);

const items: ICommandBarItemProps[] = appState.uiState.hideNewGame
? []
: [
Expand Down Expand Up @@ -142,6 +146,7 @@ export const GameBar = observer(function GameBar(): JSX.Element {
appState,
addPlayerHandler,
protestBonusHandler,
reorderPlayersHandler,
addQuestionsHandler
);
items.push({
Expand Down Expand Up @@ -213,6 +218,7 @@ function getActionSubMenuItems(
appState: AppState,
addPlayerHandler: () => void,
protestBonusHandler: () => void,
reorderPlayersHandler: () => void,
addQuestionsHandler: () => void
): ICommandBarItemProps[] {
const items: ICommandBarItemProps[] = [];
Expand All @@ -223,7 +229,8 @@ function getActionSubMenuItems(
appState,
game,
uiState,
addPlayerHandler
addPlayerHandler,
reorderPlayersHandler
);
items.push(playerManagementSection);

Expand Down Expand Up @@ -382,7 +389,8 @@ function getPlayerManagementSubMenuItems(
appState: AppState,
game: GameState,
uiState: UIState,
addPlayerHandler: () => void
addPlayerHandler: () => void,
reorderPlayersHandler: () => void
): ICommandBarItemProps {
const teamNames: string[] = game.teamNames;
const swapActivePlayerMenus: ICommandBarItemProps[] = [];
Expand Down Expand Up @@ -477,13 +485,20 @@ function getPlayerManagementSubMenuItems(
disabled: appState.game.cycles.length === 0,
};

const reorderPlayersItem: ICommandBarItemProps = {
key: "reorderPlayers",
text: "Reorder players...",
onClick: reorderPlayersHandler,
disabled: appState.game.cycles.length === 0,
};

return {
key: "playerManagement",
itemType: ContextualMenuItemType.Section,
sectionProps: {
bottomDivider: true,
title: "Player Management",
items: [swapPlayerItem, addPlayerItem],
items: [swapPlayerItem, addPlayerItem, reorderPlayersItem],
},
};
}
Expand Down
2 changes: 2 additions & 0 deletions src/components/ModalDialogContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { CustomizeGameFormatDialog } from "./dialogs/CustomizeGameFormatDialog";
import { AddQuestionsDialog } from "./dialogs/AddQuestionsDialog";
import { MessageDialog } from "./dialogs/MessageDialog";
import { RenamePlayerDialog } from "./dialogs/RenamePlayerDialog";
import { ReorderPlayerDialog } from "./dialogs/ReorderPlayerDialog";

export const ModalDialogContainer = observer(function ModalDialogContainer() {
// The Protest dialogs aren't here because they require extra information
Expand All @@ -29,6 +30,7 @@ export const ModalDialogContainer = observer(function ModalDialogContainer() {
<MessageDialog />
<NewGameDialog />
<RenamePlayerDialog />
<ReorderPlayerDialog />
</>
);
});
4 changes: 1 addition & 3 deletions src/components/cycleItems/TossupAnswerCycleItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@ export const TossupAnswerCycleItem = observer(function TossupAnswerCycleItem(
}
}

const text = `${props.buzz.marker.player.name} (${
props.buzz.marker.player.teamName
}) ${buzzDescription} on tossup #${props.buzz.tossupIndex + 1} at word ${props.buzz.marker.position + 1}`;
const text = `${props.buzz.marker.player.name} (${props.buzz.marker.player.teamName}) ${buzzDescription}`;
return <CycleItem text={text} onDelete={deleteHandler} />;
});

Expand Down
Loading

0 comments on commit 9056519

Please sign in to comment.