Skip to content

Commit

Permalink
Make asset condition trackers rollable, add experience tracker and re…
Browse files Browse the repository at this point in the history
…work legacy tracks, fix duplicated move categories, fix display bug on character list
  • Loading branch information
AG-Guardian committed Oct 25, 2024
1 parent e97e8a0 commit 9f41b52
Show file tree
Hide file tree
Showing 19 changed files with 356 additions and 529 deletions.
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
18
3 changes: 3 additions & 0 deletions SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
## Steps

1. Clone this project `git clone https://github.com/scottbenton/Iron-Fellowship.git`
1. Install node v18 and npm v10
1. Follow [these instructions](https://github.com/nvm-sh/nvm?tab=readme-ov-file#installing-and-updating) to install nvm
1. Switch to project dir and `nvm install` to install and configure the correct node version
1. Install dependencies `npm i`
1. Create an `.env.local` file (see `.env.local` below)
1. Set up firebase (see Firebase Setup below, or contact Scott to get credentials to the dev instance)
Expand Down
422 changes: 213 additions & 209 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"scripts": {
"dev": "vite",
"lint": "eslint ./src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"format": "eslint ./src --ext ts,tsx --fix",
"build": "tsc && vite build",
"preview": "vite preview"
},
Expand Down
2 changes: 1 addition & 1 deletion src/api-calls/character/_character.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export interface CharacterDocument {
momentum: number;

specialTracks?: Record<string, SpecialTrack>; // Bonds, Quests, Discoveries, etc.
// Ironsworn only - starforged XP is stored on specialTracks

experience?: {
earned?: number;
spent?: number;
Expand Down
2 changes: 1 addition & 1 deletion src/api-calls/user/listenToUserDoc.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { onSnapshot, ListenSource } from "firebase/firestore";
import { onSnapshot } from "firebase/firestore";
import { getUsersDoc } from "./_getRef";
import { UserDocument } from "api-calls/user/_user.type";

Expand Down
9 changes: 6 additions & 3 deletions src/components/features/ProgressTrack/ProgressTrack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,15 @@ const trackMoveIdSystemValues: GameSystemChooser<{
[TrackTypes.Fray]: "classic/moves/combat/end_the_fight",
[TrackTypes.SceneChallenge]: "",
[TrackTypes.BondProgress]: "",
[TrackTypes.Legacy]: "",
},
[GAME_SYSTEMS.STARFORGED]: {
[TrackTypes.Vow]: "starforged/moves/quest/fulfill_your_vow",
[TrackTypes.Journey]: "starforged/moves/exploration/finish_an_expedition",
[TrackTypes.Fray]: "starforged/moves/combat/take_decisive_action",
[TrackTypes.BondProgress]: "starforged/moves/connection/forge_a_bond",
[TrackTypes.SceneChallenge]:
"starforged/moves/scene_challenge/finish_the_scene",
[TrackTypes.SceneChallenge]: "starforged/moves/scene_challenge/finish_the_scene",
[TrackTypes.Legacy]: "starforged/moves/legacy/continue_a_legacy",
},
};

Expand All @@ -52,6 +53,7 @@ export interface BaseProgressTrackProps {
onEdit?: () => void;
hideDifficultyLabel?: boolean;
hideRollButton?: boolean;
useMaxRoll?: boolean;
}

interface ProgressTrackProgressProps extends BaseProgressTrackProps {
Expand Down Expand Up @@ -117,6 +119,7 @@ export function ProgressTrack(props: ProgressTracksProps) {
onEdit,
hideDifficultyLabel,
hideRollButton,
useMaxRoll,
} = props;

const trackMoveIds = useGameSystemValue(trackMoveIdSystemValues);
Expand Down Expand Up @@ -171,7 +174,7 @@ export function ProgressTrack(props: ProgressTracksProps) {
rollTrackProgress(
trackType,
label || "",
Math.min(Math.floor(value / 4), 10),
useMaxRoll ? 10 : Math.min(Math.floor(value / 4), 10),
move?._id ?? ""
);
}
Expand Down
29 changes: 28 additions & 1 deletion src/components/features/Track.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Box, Typography, SxProps, Theme, ButtonBase } from "@mui/material";
import { useDebouncedState } from "hooks/useDebouncedState";
import { useEffect, useId, useRef, useState } from "react";
import { useStore } from "stores/store";
import { useRoller } from "stores/appState/useRoller";

export interface TrackProps {
label?: string;
Expand All @@ -11,6 +12,7 @@ export interface TrackProps {
onChange?: (newValue: number) => Promise<boolean | void>;
sx?: SxProps<Theme>;
disabled?: boolean;
rollable?: boolean;
}

function getArr(min: number, max: number): number[] {
Expand All @@ -24,7 +26,7 @@ function getArr(min: number, max: number): number[] {
}

export function Track(props: TrackProps) {
const { label, min, max, value, onChange, sx, disabled } = props;
const { label, min, max, value, onChange, sx, disabled, rollable } = props;

const [numbers, setNumbers] = useState<number[]>([]);
const hasUnsavedChangesRef = useRef(false);
Expand Down Expand Up @@ -66,6 +68,14 @@ export function Track(props: TrackProps) {

const labelId = useId();

const { rollStat } = useRoller();
const adds = useStore(
(store) => store.characters.currentCharacter.currentCharacter?.adds ?? 0
);
const resetAdds = useStore(
(store) => store.characters.currentCharacter.updateCurrentCharacter
);

return (
<Box
role={"group"}
Expand All @@ -92,7 +102,24 @@ export function Track(props: TrackProps) {
sx={(theme) => ({
borderTopLeftRadius: `${theme.shape.borderRadius}px`,
borderBottomLeftRadius: `${theme.shape.borderRadius}px`,
transition: theme.transitions.create(
["background-color"],
{ duration: theme.transitions.duration.shorter }
),
"&:hover":
disabled || !rollable
? {}
: {
backgroundColor: theme.palette.primary.main,
},
})}
onClick={() => {
if (!disabled && rollable) {
rollStat(label, value, undefined, adds);
resetAdds({ adds: 0 }).catch(() => {});
}
}}
component={(disabled || !rollable) ? "div" : ButtonBase}
>
<Typography
fontFamily={(theme) => theme.fontFamilyTitle}
Expand Down
1 change: 1 addition & 0 deletions src/components/features/assets/AssetCard/AssetControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ export function AssetControl(props: AssetControlProps) {
}
: undefined
}
rollable={true}
/>
</Box>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,14 @@ export function MoveCategory(props: MoveCategoryProps) {

const [isExpanded, setIsExpanded] = useState(false);

if (visibleCategories[category._id] === CATEGORY_VISIBILITY.HIDDEN || category.enhances) {
return null;
}

const isExpandedOrForced = isExpanded || forceOpen;
const visibleContents = Object.values(category.contents).filter((move) => !move.replaces);

if (visibleCategories[category._id] === CATEGORY_VISIBILITY.HIDDEN) {
if (visibleContents.length === 0) {
return null;
}

Expand All @@ -49,9 +54,9 @@ export function MoveCategory(props: MoveCategoryProps) {
mb: isExpandedOrForced ? 0.5 : 0,
}}
>
{Object.values(category.contents ?? {}).map((move, index) =>
{visibleContents.map((move, index) =>
visibleCategories[category._id] === CATEGORY_VISIBILITY.ALL ||
visibleMoves[move._id] === true ? (
visibleMoves[move._id] ? (
<Move
key={index}
move={moveMap[move._id]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ export interface LocationMapProps {
map?: ILocationMap;
}

const DEFAULT_ROWS = 13;
const DEFAULT_COLS = 18;

export function LocationMap(props: LocationMapProps) {
const { locationId, map = {}, backgroundImageUrl } = props;
const locationMap = useStore(
Expand Down Expand Up @@ -69,14 +66,6 @@ export function LocationMap(props: LocationMapProps) {
backgroundImageDimensions
);

// const rows = 13;
// const cols = 18;

// // Calculate SVG dimensions
// const width: number =
// cols * s * Math.sqrt(3) + (s * Math.sqrt(3)) / 2 - cols + 6; // Updated
// const height: number = rows * 1.5 * s + s / 2 + 1; // Updated

const verticalSpacing: number = 1.5 * s; // Updated
const horizontalSpacing: number = s * Math.sqrt(3); // Updated
const offsetX: number = (s * Math.sqrt(3)) / 2; // New offset for vertical positioning
Expand Down Expand Up @@ -430,7 +419,7 @@ export function LocationMap(props: LocationMapProps) {

paintOrder: "stroke",
stroke: "#000000",
strokeOpacity: !!backgroundImageUrl ? "100%" : "60%",
strokeOpacity: backgroundImageUrl ? "100%" : "60%",
strokeWidth: s / 12,
strokeLinecap: "butt",
strokeLinejoin: "miter",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IconButton, ListItemText, Menu, MenuItem } from "@mui/material";
import { IconButton, Menu, MenuItem } from "@mui/material";
import { useRef, useState } from "react";
import { MapBackgroundImageFit, MapStrokeColors } from "types/Locations.type";
import OverflowMenuIcon from "@mui/icons-material/MoreHoriz";
Expand Down
1 change: 0 additions & 1 deletion src/components/shared/Layout/UpdateDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {
Box,
Button,
Dialog,
DialogActions,
Expand Down
2 changes: 0 additions & 2 deletions src/hooks/featureFlags/useNewMaps.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { useFeatureFlag } from "./useFeatureFlag";

export function useNewMaps() {
return true;
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import {
Accordion,
AccordionDetails,
AccordionSummary,
Box,
Button,
Card,
List,
Stack,
Typography,
ListItemButton,
ListItemText,
Collapse
} from "@mui/material";
import { StatComponent } from "components/features/characters/StatComponent";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import { ExpandMore, ExpandLess } from "@mui/icons-material";
import { AssetCard } from "components/features/assets/AssetCard";
import { InitiativeStatusChip } from "components/features/characters/InitiativeStatusChip";
import { PortraitAvatar } from "components/features/characters/PortraitAvatar/PortraitAvatar";
Expand All @@ -25,6 +26,7 @@ import {
import { LinkComponent } from "components/shared/LinkComponent";
import { constructCharacterSheetPath } from "pages/Character/routes";
import { useCampaignType } from "hooks/useCampaignType";
import { useState } from "react";

export interface CharacterCardProps {
uid: string;
Expand Down Expand Up @@ -71,6 +73,18 @@ export function CharacterCard(props: CharacterCardProps) {
(store) => store.campaigns.currentCampaign.removeCharacter
);

const [assetsOpen, setAssetsOpen] = useState(false);

const handleExpandAssets = () => {
setAssetsOpen(!assetsOpen);
};

const [tracksOpen, setTracksOpen] = useState(false);

const handleExpandTracks = () => {
setTracksOpen(!tracksOpen);
};

return (
<Card variant={"outlined"}>
<Box>
Expand Down Expand Up @@ -146,36 +160,40 @@ export function CharacterCard(props: CharacterCardProps) {
sx={{ mr: 1, mt: 1 }}
/>
</Box>
<Accordion
variant={"outlined"}
sx={{ borderLeftWidth: 0, borderRightWidth: 0 }}
>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
Assets
</AccordionSummary>
<AccordionDetails>
<Stack spacing={2} px={2}>
{storedAssets?.map((storedAsset, index) => (
<AssetCard
key={index}
storedAsset={storedAsset}
assetId={storedAsset.id}
/>
))}
</Stack>
</AccordionDetails>
</Accordion>
<Accordion
variant="outlined"
sx={{ borderLeftWidth: 0, borderRightWidth: 0 }}
>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
{trackLabel}
</AccordionSummary>
<AccordionDetails>
<TrackComponent characterId={characterId} />
</AccordionDetails>
</Accordion>
<List>
<ListItemButton
divider={true}
onClick={handleExpandAssets}
sx={(theme) => ({ borderTop: `1px solid ${theme.palette.divider}` })}
>
<ListItemText primary="Assets" />
{assetsOpen ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={assetsOpen} timeout="auto" unmountOnExit>
<Stack spacing={2} p={2} >
{storedAssets?.map((storedAsset, index) => (
<AssetCard
key={index}
storedAsset={storedAsset}
assetId={storedAsset.id}
/>
))}
</Stack>
</Collapse>
<ListItemButton
divider={true}
onClick={handleExpandTracks}
sx={(theme) => ({ borderTop: `1px solid ${theme.palette.divider}` })}
>
<ListItemText primary={trackLabel} />
{tracksOpen ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={tracksOpen} timeout="auto" unmountOnExit>
<Box py={2} >
<TrackComponent characterId={characterId} />
</Box>
</Collapse>
</List>
<Box display={"flex"} justifyContent={"flex-end"} p={1}>
<Stack direction={"row"} spacing={1} flexWrap={"wrap"}>
{(uid === currentUserUid || !showGuidedPlayerView) && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ export function LegacyTracks(props: LegacyTracksProps) {
key={st}
label={specialTracks[st].label}
value={specialTrackValues[st]?.value}
checkedExperience={specialTrackValues[st]?.spentExperience ?? {}}
isLegacy={specialTrackValues[st]?.isLegacy ?? false}
/>
))}
Expand Down
Loading

0 comments on commit 9f41b52

Please sign in to comment.