Skip to content

Commit

Permalink
Merge pull request #513 from scottbenton/feat/hide-oracles
Browse files Browse the repository at this point in the history
Add campaign setting to hide oracles
  • Loading branch information
scottbenton authored Nov 6, 2024
2 parents 99a60a6 + e2e3d82 commit cb76be2
Show file tree
Hide file tree
Showing 13 changed files with 357 additions and 61 deletions.
1 change: 1 addition & 0 deletions src/api-calls/campaign/_campaign.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface CampaignDocument {
worldId?: string;
expansionIds?: string[];
hiddenAssetIds?: string[];
hiddenOracleIds?: string[];
customTracks?: Record<string, number>;
conditionMeters?: Record<string, number>;
specialTracks?: Record<string, LegacyTrack>;
Expand Down
33 changes: 33 additions & 0 deletions src/api-calls/campaign/updateHiddenOracles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { arrayUnion, arrayRemove, updateDoc } from "firebase/firestore";
import { getCampaignDoc } from "./_getRef";
import { createApiFunction } from "api-calls/createApiFunction";

export const updateCampaignHiddenOracles = createApiFunction<
{
campaignId: string;
oracleId: string;
hidden: boolean;
},
void
>((params) => {
const { campaignId, oracleId, hidden } = params;

return new Promise((resolve, reject) => {
updateDoc(
getCampaignDoc(campaignId),
hidden
? {
hiddenOracleIds: arrayUnion(oracleId),
}
: {
hiddenOracleIds: arrayRemove(oracleId),
}
)
.then(() => {
resolve();
})
.catch((e) => {
reject(e);
});
});
}, "Failed to update hidden oracles.");
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ export interface CollapsibleSectionHeaderProps {
toggleOpen: () => void;
disabled?: boolean;
actions?: React.JSX.Element;
hidden?: boolean;
}

export function CollapsibleSectionHeader(props: CollapsibleSectionHeaderProps) {
const { component, text, open, forcedOpen, toggleOpen, disabled, actions } =
const { component, text, open, forcedOpen, toggleOpen, disabled, actions, hidden } =
props;

if (forcedOpen) {
Expand All @@ -39,6 +40,7 @@ export function CollapsibleSectionHeader(props: CollapsibleSectionHeaderProps) {
transition: theme.transitions.create(["margin"], {
duration: theme.transitions.duration.shorter,
}),
filter: hidden ? "grayscale(30%) opacity(70%)" : undefined
})}
>
{text}
Expand Down Expand Up @@ -72,6 +74,7 @@ export function CollapsibleSectionHeader(props: CollapsibleSectionHeaderProps) {
transition: theme.transitions.create(["margin"], {
duration: theme.transitions.duration.shorter,
}),
filter: hidden ? "grayscale(30%) opacity(70%)" : undefined
})}
>
{!forcedOpen ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,12 @@ export function ListItemButtonWithSecondaryAction(
{...listItemProps}
>
<ListItemButton
disabled={disabled}
disabled={disabled || !onClick}
onClick={onClick}
{...listItemButtonProps}
sx={(theme) => ({
pr: `calc(${theme.spacing(2)} + ${actionWidth ?? 0}px) !important`,
opacity: !onClick ? "1 !important" : undefined
})}
>
{children}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
CATEGORY_VISIBILITY,
CombinedCollectionType,
} from "./useFilterOracles";
import { useStore } from "stores/store";
import { ToggleVisibilityButton } from "../../../shared/ToggleVisibilityButton";

export interface OracleCollectionProps {
collectionId: string;
Expand All @@ -18,6 +20,7 @@ export interface OracleCollectionProps {
visibleOracles: Record<string, boolean>;
enhancesCollections: Record<string, string[]>;
disabled?: boolean;
actionIsHide?: boolean;
}

export function OracleCollection(props: OracleCollectionProps) {
Expand All @@ -30,8 +33,28 @@ export function OracleCollection(props: OracleCollectionProps) {
visibleOracles,
enhancesCollections,
disabled,
actionIsHide,
} = props;

const hiddenOracles = useStore(
(store) => store.campaigns.currentCampaign.currentCampaign?.hiddenOracleIds
);
const updateHiddenOracles = useStore(
(store) => store.campaigns.currentCampaign.updateHiddenOracles
);

const [hideIsloading, setHideIsLoading] = useState(false);

const onToggleVisibility = () => {
setHideIsLoading(true);
updateHiddenOracles(collectionId, !hidden)
.catch(() => {
})
.finally(() => {
setHideIsLoading(false);
});
};

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

Expand Down Expand Up @@ -71,9 +94,12 @@ export function OracleCollection(props: OracleCollectionProps) {
return { oracleIds, subCollectionIds };
}, [contents, subCollections, collections, enhancingCollectionIds]);

const hidden = hiddenOracles?.includes(collectionId);

if (
visibleCollections[collectionId] === CATEGORY_VISIBILITY.HIDDEN ||
!collection
!collection ||
(!actionIsHide && hidden)
) {
return null;
} else if (
Expand All @@ -85,6 +111,8 @@ export function OracleCollection(props: OracleCollectionProps) {
<OracleSelectableRollableCollectionListItem
collection={collection}
disabled={disabled}
actionIsHide={actionIsHide}
hidden={hidden}
/>
);
}
Expand All @@ -97,19 +125,32 @@ export function OracleCollection(props: OracleCollectionProps) {
toggleOpen={() => !forceOpen && setIsExpanded((prev) => !prev)}
text={collection.name}
disabled={disabled}
actions={actionIsHide ? (
<ToggleVisibilityButton
onToggleVisibility={onToggleVisibility}
loading={hideIsloading}
hidden={hidden}
/>
) : undefined}
hidden={hidden}
/>
<Collapse in={isExpandedOrForced}>
<List sx={{ py: 0, mb: isExpandedOrForced ? 0.5 : 0 }}>
{oracleIds.map((oracleId) => (
<OracleListItem
key={collectionId + "-" + oracleId}
oracleId={oracleId}
oracles={oracles}
disabled={!isExpandedOrForced || disabled}
visibleOracles={visibleOracles}
collectionVisibility={visibleCollections[collection._id]}
/>
))}
{oracleIds.map((oracleId) => {
const hidden = hiddenOracles?.includes(oracleId);
return (
<OracleListItem
key={collectionId + "-" + oracleId}
oracleId={oracleId}
oracles={oracles}
disabled={!isExpandedOrForced || disabled}
visibleOracles={visibleOracles}
collectionVisibility={visibleCollections[collection._id]}
actionIsHide={actionIsHide}
hidden={hidden}
/>
);
})}
{subCollectionIds.map((subCollectionId) => (
<OracleCollection
key={collectionId + "-" + subCollectionId}
Expand All @@ -121,6 +162,7 @@ export function OracleCollection(props: OracleCollectionProps) {
visibleOracles={visibleOracles}
enhancesCollections={enhancesCollections}
disabled={disabled || !isExpandedOrForced}
actionIsHide={actionIsHide}
/>
))}
</List>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,46 @@ import { CATEGORY_VISIBILITY } from "./useFilterOracles";
import { useRoller } from "stores/appState/useRoller";
import { OracleListItemActionOpenDialogButton } from "./OracleListItemActionOpenDialogButton";
import { ListItemButtonWithSecondaryAction } from "./ListItemButtonWithSecondaryAction";
import { ToggleVisibilityButton } from "components/shared/ToggleVisibilityButton";
import { useStore } from "stores/store";
import { useState } from "react";

export interface OracleListItemProps {
oracleId: string;
oracles: Record<string, Datasworn.OracleRollable>;
visibleOracles: Record<string, boolean>;
disabled?: boolean;
collectionVisibility?: CATEGORY_VISIBILITY;
actionIsHide?: boolean;
hidden?: boolean;
}

export function OracleListItem(props: OracleListItemProps) {
const { oracleId, oracles, visibleOracles, disabled, collectionVisibility } =
const { oracleId, oracles, visibleOracles, disabled, collectionVisibility, actionIsHide, hidden } =
props;
const oracle = oracles[oracleId];
const { rollOracleTable } = useRoller();

const updateHiddenOracles = useStore(
(store) => store.campaigns.currentCampaign.updateHiddenOracles
);

const [hideIsloading, setHideIsLoading] = useState(false);

const onToggleVisibility = () => {
setHideIsLoading(true);
updateHiddenOracles(oracleId, !hidden)
.catch(() => {
})
.finally(() => {
setHideIsLoading(false);
});
};

if(!actionIsHide && hidden) {
return null;
}

if (
(collectionVisibility !== CATEGORY_VISIBILITY.ALL &&
!visibleOracles[oracleId]) ||
Expand All @@ -30,13 +55,25 @@ export function OracleListItem(props: OracleListItemProps) {
return (
<ListItemButtonWithSecondaryAction
secondaryAction={
<OracleListItemActionOpenDialogButton
item={oracle}
disabled={disabled}
/>
<>
<OracleListItemActionOpenDialogButton
item={oracle}
disabled={disabled}
/>
{actionIsHide && (
<ToggleVisibilityButton
onToggleVisibility={onToggleVisibility}
loading={hideIsloading}
hidden={hidden}
/>
)}
</>
}
disabled={disabled}
onClick={() => rollOracleTable(oracle._id, true, false)}
onClick={!actionIsHide ? () => rollOracleTable(oracle._id, true, false) : undefined}
sx={{
filter: hidden ? "grayscale(30%) opacity(70%)" : undefined
}}
>
<ListItemText primary={oracle.name} />
</ListItemButtonWithSecondaryAction>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@ import { EmptyState } from "components/shared/EmptyState";
import { OracleCollection } from "./OracleCollection";
import { AskTheOracleButtons } from "./AskTheOracleButtons";

export function OracleSection() {
export interface OraclesSectionProps {
actionIsHide?: boolean
}

export function OracleSection(props: OraclesSectionProps) {
const { actionIsHide = false } = props;

const {
oracleCollections,
setSearch,
Expand All @@ -20,47 +26,49 @@ export function OracleSection() {

return (
<>
<Box
color={(theme) => theme.palette.darkGrey.contrastText}
bgcolor={(theme) => theme.palette.darkGrey.dark}
borderBottom={(theme) => `1px solid ${theme.palette.darkGrey.dark}`}
>
{!actionIsHide && (
<Box
color={(theme) => theme.palette.darkGrey.contrastText}
bgcolor={(theme) => theme.palette.darkGrey.dark}
borderBottom={(theme) => `1px solid ${theme.palette.darkGrey.dark}`}
>
<Typography
variant={"body2"}
component={"div"}
textAlign={"center"}
fontFamily={(theme) => theme.fontFamilyTitle}
<Box
color={(theme) => theme.palette.darkGrey.contrastText}
bgcolor={(theme) => theme.palette.darkGrey.dark}
borderBottom={(theme) => `1px solid ${theme.palette.darkGrey.dark}`}
>
Ask the Oracle
</Typography>
<AskTheOracleButtons />
<Typography
variant={"body2"}
component={"div"}
textAlign={"center"}
fontFamily={(theme) => theme.fontFamilyTitle}
>
Ask the Oracle
</Typography>
<AskTheOracleButtons />
</Box>
<Input
fullWidth
startAdornment={
<InputAdornment position={"start"}>
<SearchIcon
sx={(theme) => ({ color: theme.palette.grey[300] })}
/>
</InputAdornment>
}
aria-label={"Filter Oracles"}
placeholder={"Filter Oracles"}
onChange={(evt) => setSearch(evt.currentTarget.value)}
color={"primary"}
sx={(theme) => ({
backgroundColor: theme.palette.darkGrey.main,
color: "#fff",
px: 2,
borderBottomColor: theme.palette.darkGrey.light,
})}
/>
</Box>
<Input
fullWidth
startAdornment={
<InputAdornment position={"start"}>
<SearchIcon
sx={(theme) => ({ color: theme.palette.grey[300] })}
/>
</InputAdornment>
}
aria-label={"Filter Oracles"}
placeholder={"Filter Oracles"}
onChange={(evt) => setSearch(evt.currentTarget.value)}
color={"primary"}
sx={(theme) => ({
backgroundColor: theme.palette.darkGrey.main,
color: "#fff",
px: 2,
borderBottomColor: theme.palette.darkGrey.light,
})}
/>
</Box>
)}
{!isEmpty ? (
<List
sx={(theme) => ({
Expand All @@ -81,6 +89,7 @@ export function OracleSection() {
visibleCollections={visibleOracleCollectionIds}
visibleOracles={visibleOracleIds}
enhancesCollections={enhancesCollections}
actionIsHide={actionIsHide}
/>
))}
</List>
Expand Down
Loading

0 comments on commit cb76be2

Please sign in to comment.