Skip to content

Commit

Permalink
feat(oracles): Created a new oracle view for the v2 oracles
Browse files Browse the repository at this point in the history
  • Loading branch information
scottbenton committed Dec 22, 2023
1 parent 0fe7a90 commit 1aca4a4
Show file tree
Hide file tree
Showing 66 changed files with 1,449 additions and 69 deletions.
4 changes: 4 additions & 0 deletions firestore.rules
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ service cloud.firestore {
allow read: if request.auth.uid != null;
allow write: if checkIsHomebrewOwner();
}
match /oracles/oracles {
allow read: if request.auth.uid != null;
allow write: if checkIsHomebrewOwner();
}
}
match /users/{userId} {
allow read: if true;
Expand Down
2 changes: 1 addition & 1 deletion src/api-calls/homebrew/_getRef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
collection,
doc,
} from "firebase/firestore";
import { BaseExpansionOrRuleset } from "types/HomebrewCollection.type";
import { BaseExpansionOrRuleset } from "types/homebrew/HomebrewCollection.type";

export function constructHomebrewCollectionPath() {
return "/homebrew";
Expand Down
2 changes: 1 addition & 1 deletion src/api-calls/homebrew/createHomebrewExpansion.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { addDoc } from "firebase/firestore";
import { getHomebrewCollection } from "./_getRef";
import { BaseExpansion } from "types/HomebrewCollection.type";
import { BaseExpansion } from "types/homebrew/HomebrewCollection.type";
import { createApiFunction } from "api-calls/createApiFunction";

export const createHomebrewExpansion = createApiFunction<BaseExpansion, string>(
Expand Down
2 changes: 1 addition & 1 deletion src/api-calls/homebrew/listenToHomebrewCollections.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { onSnapshot, query, where } from "firebase/firestore";
import { BaseExpansionOrRuleset } from "types/HomebrewCollection.type";
import { BaseExpansionOrRuleset } from "types/homebrew/HomebrewCollection.type";
import { getHomebrewCollection } from "./_getRef";

export function listenToHomebrewCollections(
Expand Down
15 changes: 15 additions & 0 deletions src/api-calls/homebrew/oracles/_getRef.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { DocumentReference, doc } from "firebase/firestore";
import { constructHomebrewCollectionDocPath } from "../_getRef";
import { firestore } from "config/firebase.config";
import { DictKey, OracleTablesCollection } from "@datasworn/core";

function constructHomebrewOracleDocPath(homebrewId: string) {
return `${constructHomebrewCollectionDocPath(homebrewId)}/oracles/oracles`;
}

export function getHomebrewOraclesDoc(homebrewId: string) {
return doc(
firestore,
constructHomebrewOracleDocPath(homebrewId)
) as DocumentReference<Record<DictKey, OracleTablesCollection>>;
}
29 changes: 29 additions & 0 deletions src/api-calls/homebrew/oracles/listenToHomebrewOracles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { OracleTablesCollection } from "@datasworn/core";
import { getHomebrewOraclesDoc } from "./_getRef";
import { onSnapshot } from "firebase/firestore";

export function listenToHomebrewOracles(
homebrewId: string,
updateOracles: (
homebrewId: string,
oracles: Record<string, OracleTablesCollection>
) => void,
onError: (error: unknown) => void,
onLoaded: () => void
) {
return onSnapshot(
getHomebrewOraclesDoc(homebrewId),
(snapshot) => {
const doc = snapshot.data();
if (doc) {
updateOracles(homebrewId, doc);
} else {
onLoaded();
}
},
(error) => {
console.error(error);
onError(error);
}
);
}
22 changes: 22 additions & 0 deletions src/api-calls/homebrew/oracles/updateHomebrewOracles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { OracleTablesCollection } from "@datasworn/core";
import { createApiFunction } from "api-calls/createApiFunction";
import { PartialWithFieldValue, setDoc } from "firebase/firestore";
import { getHomebrewOraclesDoc } from "./_getRef";

export const updateHomebrewOracles = createApiFunction<
{
homebrewId: string;
oracles: PartialWithFieldValue<Record<string, OracleTablesCollection>>;
},
void
>((params) => {
const { homebrewId, oracles } = params;

return new Promise((resolve, reject) => {
setDoc(getHomebrewOraclesDoc(homebrewId), oracles, { merge: true })
.then(() => {
resolve();
})
.catch(reject);
});
}, "Failed to update oracles.");
2 changes: 1 addition & 1 deletion src/api-calls/homebrew/rules/_getRef.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { DocumentReference, doc } from "firebase/firestore";
import { constructHomebrewCollectionDocPath } from "../_getRef";
import { firestore } from "config/firebase.config";
import { StoredRules } from "types/HomebrewCollection.type";
import { StoredRules } from "types/homebrew/HomebrewRules.type";

export function constructHomebrewRulesDocPath(homebrewId: string) {
return `${constructHomebrewCollectionDocPath(homebrewId)}/rules/rules`;
Expand Down
2 changes: 1 addition & 1 deletion src/api-calls/homebrew/rules/createHomebrewRules.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createApiFunction } from "api-calls/createApiFunction";
import { PartialWithFieldValue, updateDoc } from "firebase/firestore";
import { getHomebrewRulesDoc } from "./_getRef";
import { StoredRules } from "types/HomebrewCollection.type";
import { StoredRules } from "types/homebrew/HomebrewRules.type";

export const updateHomebrewRules = createApiFunction<
{
Expand Down
2 changes: 1 addition & 1 deletion src/api-calls/homebrew/rules/listenToHomebrewRules.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { onSnapshot } from "firebase/firestore";
import { StoredRules } from "types/HomebrewCollection.type";
import { StoredRules } from "types/homebrew/HomebrewRules.type";
import { getHomebrewRulesDoc } from "./_getRef";

export function listenToHomebrewRules(
Expand Down
2 changes: 1 addition & 1 deletion src/api-calls/homebrew/rules/updateExpansionRules.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createApiFunction } from "api-calls/createApiFunction";
import { PartialWithFieldValue, setDoc } from "firebase/firestore";
import { getHomebrewRulesDoc } from "./_getRef";
import { StoredRules } from "types/HomebrewCollection.type";
import { StoredRules } from "types/homebrew/HomebrewRules.type";

export const updateExpansionRules = createApiFunction<
{
Expand Down
2 changes: 1 addition & 1 deletion src/api-calls/homebrew/updateHomebrewExpansion.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { updateDoc } from "firebase/firestore";
import { getHomebrewCollectionDoc } from "./_getRef";
import { BaseExpansion } from "types/HomebrewCollection.type";
import { BaseExpansion } from "types/homebrew/HomebrewCollection.type";
import { createApiFunction } from "api-calls/createApiFunction";

export const updateHomebrewExpansion = createApiFunction<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,25 @@ import {
ListItemButton,
ListItemIcon,
ListSubheader,
ListSubheaderProps,
} from "@mui/material";
import OpenIcon from "@mui/icons-material/ChevronRight";

export interface CollapsibleSectionHeaderProps {
component?: ListSubheaderProps["component"];
text: string;
forcedOpen?: boolean;
open: boolean;
toggleOpen: () => void;
disabled?: boolean;
}

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

return (
<ListSubheader
component={component ?? "li"}
disableGutters
sx={(theme) => ({
mt: open ? 0.5 : 0,
Expand All @@ -35,7 +39,7 @@ export function CollapsibleSectionHeader(props: CollapsibleSectionHeaderProps) {
})}
>
{!forcedOpen ? (
<ListItemButton onClick={toggleOpen}>
<ListItemButton onClick={toggleOpen} disabled={disabled}>
<Box sx={{ flexGrow: 1 }}>{text}</Box>
<ListItemIcon sx={{ minWidth: "unset" }}>
<OpenIcon
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,54 @@
import { Dialog } from "@mui/material";
import { Dialog, SwipeableDrawer } from "@mui/material";
import { useStore } from "stores/store";
import { LinkedDialogContent } from "./LinkedDialogContent";
import { useIsMobile } from "hooks/useIsMobile";

export function LinkedDialog() {
const { isOpen, previousIds, openId } = useStore(
const { isOpen, previousIds, openId, newVersion } = useStore(
(store) => store.appState.openDialogState
);
const handleBack = useStore((store) => store.appState.prevDialog);
const handleClose = useStore((store) => store.appState.closeDialog);

const isMobile = useIsMobile();

if (isMobile && newVersion) {
return (
<SwipeableDrawer
anchor={"bottom"}
open={isOpen}
onOpen={() => {}}
disableSwipeToOpen
disableDiscovery
onClose={handleClose}
sx={{ pt: 1 }}
PaperProps={{
sx: (theme) => ({
top: theme.spacing(2),
borderTopLeftRadius: theme.shape.borderRadius,
borderTopRightRadius: theme.shape.borderRadius,
}),
}}
>
<LinkedDialogContent
id={openId}
isLastItem={previousIds.length === 0}
handleBack={handleBack}
handleClose={handleClose}
newVersion={newVersion}
/>
</SwipeableDrawer>
);
}

return (
<Dialog open={isOpen} onClose={handleClose}>
<LinkedDialogContent
id={openId}
isLastItem={previousIds.length === 0}
handleBack={handleBack}
handleClose={handleClose}
newVersion={newVersion}
/>
</Dialog>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@ import { DialogContent } from "@mui/material";
import { LinkedDialogContentTitle } from "./LinkedDialogContentTitle";
import { MoveDialogContent } from "./MoveDialogContent";
import { OracleDialogContent } from "./OracleDialogContent";
import { NewOracleDialogContent } from "./NewOracleDialogContent";

export interface LinkedDialogContentProps {
id?: string;
handleBack: () => void;
handleClose: () => void;
isLastItem: boolean;
newVersion?: boolean;
}

export function LinkedDialogContent(props: LinkedDialogContentProps) {
const { id, handleBack, handleClose, isLastItem } = props;
const { id, handleBack, handleClose, isLastItem, newVersion } = props;

if (id?.startsWith("ironsworn/moves") || id?.startsWith("starforged/moves")) {
return (
Expand All @@ -26,8 +28,19 @@ export function LinkedDialogContent(props: LinkedDialogContentProps) {

if (
id?.startsWith("ironsworn/oracles") ||
id?.startsWith("starforged/oracles")
id?.startsWith("starforged/oracles") ||
(newVersion && id?.startsWith("starforged/collections/oracles"))
) {
if (newVersion) {
return (
<NewOracleDialogContent
id={id}
handleBack={handleBack}
handleClose={handleClose}
isLastItem={isLastItem}
/>
);
}
return (
<OracleDialogContent
id={id}
Expand All @@ -41,6 +54,7 @@ export function LinkedDialogContent(props: LinkedDialogContentProps) {
return (
<>
<LinkedDialogContentTitle
id={id ?? ""}
handleBack={handleBack}
handleClose={handleClose}
isLastItem={isLastItem}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,52 @@
import { IconButton } from "@mui/material";
import { IconButton, Tooltip } from "@mui/material";
import { PropsWithChildren, ReactNode } from "react";
import BackIcon from "@mui/icons-material/ChevronLeft";
import CopyIcon from "@mui/icons-material/CopyAll";
import { DialogTitleWithCloseButton } from "components/shared/DialogTitleWithCloseButton";
import { getIsLocalEnvironment } from "functions/getGameSystem";
import { useSnackbar } from "providers/SnackbarProvider";

export interface LinkedDialogContentTitleProps extends PropsWithChildren {
id: string;
handleBack: () => void;
handleClose: () => void;
isLastItem: boolean;
actions?: ReactNode;
}
export function LinkedDialogContentTitle(props: LinkedDialogContentTitleProps) {
const { children, handleBack, handleClose, isLastItem, actions } = props;
const { children, id, handleBack, handleClose, isLastItem, actions } = props;

const { success } = useSnackbar();

const handleCopy = () => {
navigator.clipboard.writeText(id).then(() => {
success("Copied ID to clipboard");
});
};

return (
<DialogTitleWithCloseButton
onClose={handleClose}
actions={
<>
{actions}
{getIsLocalEnvironment() && (
<Tooltip title={"Copy Id"}>
<IconButton onClick={handleCopy}>
<CopyIcon />
</IconButton>
</Tooltip>
)}
{!isLastItem && (
<IconButton
aria-label={"Back"}
onClick={() => handleBack()}
sx={{ flexShrink: 0, marginLeft: 1 }}
>
<BackIcon />
</IconButton>
<Tooltip title={"Back"}>
<IconButton
aria-label={"Back"}
onClick={() => handleBack()}
sx={{ flexShrink: 0, marginLeft: 1 }}
>
<BackIcon />
</IconButton>
</Tooltip>
)}
</>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export function MoveDialogContent(props: MoveDialogContentProps) {
return (
<>
<LinkedDialogContentTitle
id={id}
handleBack={handleBack}
handleClose={handleClose}
isLastItem={isLastItem}
Expand Down Expand Up @@ -80,6 +81,7 @@ export function MoveDialogContent(props: MoveDialogContentProps) {
return (
<>
<LinkedDialogContentTitle
id={id}
handleBack={handleBack}
handleClose={handleClose}
isLastItem={isLastItem}
Expand Down
Loading

0 comments on commit 1aca4a4

Please sign in to comment.