Typescript

This commit is contained in:
Mitchell McCaffrey 2021-07-17 18:39:49 +10:00
parent a4363e542c
commit 029a992381
20 changed files with 61 additions and 47 deletions

View File

@ -43,7 +43,6 @@ function SortableTilesDragOverlay({
const dragBounce = useSpring({
transform: !!dragId ? "scale(0.9)" : "scale(1)",
config: config.wobbly,
position: "relative",
});
function renderDragOverlays() {
@ -75,7 +74,7 @@ function SortableTilesDragOverlay({
transform: `translate(${coords[index].x}%, ${coords[index].y}%)`,
}}
>
<animated.div style={dragBounce}>
<animated.div style={{ ...dragBounce, position: "relative" }}>
{renderTile(group)}
{index === selectedIndices.length - 1 &&
selectedGroupIds.length > 1 && (

View File

@ -18,7 +18,7 @@ function TileActionBar({ onAdd, addTitle }: TileActionBarProps) {
const {
selectMode,
onSelectModeChange,
onGroupSelect,
onClearSelection,
filter,
onFilterChange,
} = useGroup();
@ -37,7 +37,7 @@ function TileActionBar({ onAdd, addTitle }: TileActionBarProps) {
outlineOffset: "0px",
},
}}
onFocus={() => onGroupSelect(undefined)}
onFocus={() => onClearSelection()}
>
<Search value={filter} onChange={(e) => onFilterChange(e.target.value)} />
<Flex

View File

@ -10,7 +10,7 @@ import useResponsiveLayout from "../../hooks/useResponsiveLayout";
import Droppable from "../drag/Droppable";
function TilesContainer({ children }: { children: React.ReactNode }) {
const { onGroupSelect } = useGroup();
const { onClearSelection } = useGroup();
const { theme } = useThemeUI();
@ -23,7 +23,7 @@ function TilesContainer({ children }: { children: React.ReactNode }) {
height: layout.tileContainerHeight,
backgroundColor: theme.colors?.muted as string,
}}
onClick={() => onGroupSelect(undefined)}
onClick={() => onClearSelection()}
>
<Grid
p={3}

View File

@ -24,8 +24,13 @@ type TilesOverlayProps = {
};
function TilesOverlay({ modalSize, children }: TilesOverlayProps) {
const { groups, openGroupId, onGroupClose, onGroupSelect, onGroupsChange } =
useGroup();
const {
groups,
openGroupId,
onGroupClose,
onClearSelection,
onGroupsChange,
} = useGroup();
const { theme } = useThemeUI();
@ -48,7 +53,7 @@ function TilesOverlay({ modalSize, children }: TilesOverlayProps) {
const [isGroupNameModalOpen, setIsGroupNameModalOpen] = useState(false);
function handleGroupNameChange(name: string) {
if (openGroupId) {
onGroupsChange(renameGroup(groups, openGroupId, name), undefined);
onGroupsChange(renameGroup(groups, openGroupId, name));
setIsGroupNameModalOpen(false);
}
}
@ -134,7 +139,7 @@ function TilesOverlay({ modalSize, children }: TilesOverlayProps) {
marginBottom: "8px",
backgroundColor: theme.colors?.muted as string,
}}
onClick={() => onGroupSelect(undefined)}
onClick={() => onClearSelection()}
>
<Grid
sx={{

View File

@ -116,6 +116,7 @@ function TokenPreview({ token }: TokenPreviewProps) {
bottomRight: { x: 1, y: 1 },
},
type: "square",
measurement: { type: "chebyshev", scale: "5ft" },
}}
width={gridWidth}
height={gridHeight}

View File

@ -16,13 +16,14 @@ export type GetAssetEventHanlder = (
export type AddAssetsEventHandler = (assets: Asset[]) => Promise<void>;
export type PutAssetEventsHandler = (asset: Asset) => Promise<void>;
type AssetsContext = {
type AssetsContextValue = {
getAsset: GetAssetEventHanlder;
addAssets: AddAssetsEventHandler;
putAsset: PutAssetEventsHandler;
};
const AssetsContext = React.createContext<AssetsContext | undefined>(undefined);
const AssetsContext =
React.createContext<AssetsContextValue | undefined>(undefined);
// 100 MB max cache size
const maxCacheSize = 1e8;

View File

@ -2,12 +2,13 @@ import React, { useState, useEffect, useContext } from "react";
import FakeStorage from "../helpers/FakeStorage";
type AuthContext = {
type AuthContextValue = {
password: string;
setPassword: React.Dispatch<React.SetStateAction<string>>;
};
const AuthContext = React.createContext<AuthContext | undefined>(undefined);
const AuthContext =
React.createContext<AuthContextValue | undefined>(undefined);
let storage: Storage | FakeStorage;
try {

View File

@ -12,7 +12,7 @@ import { DatabaseWorkerService } from "../workers/DatabaseWorker";
export type DatabaseStatus = "loading" | "disabled" | "upgrading" | "loaded";
type DatabaseContext = {
type DatabaseContextValue = {
database: Dexie | undefined;
databaseStatus: DatabaseStatus;
databaseError: Error | undefined;
@ -20,7 +20,7 @@ type DatabaseContext = {
};
const DatabaseContext =
React.createContext<DatabaseContext | undefined>(undefined);
React.createContext<DatabaseContextValue | undefined>(undefined);
const worker: Comlink.Remote<DatabaseWorkerService> = Comlink.wrap(
new DatabaseWorker()
@ -127,7 +127,7 @@ export function DatabaseProvider({ children }: { children: React.ReactNode }) {
);
}
export function useDatabase(): DatabaseContext {
export function useDatabase() {
const context = useContext(DatabaseContext);
if (context === undefined) {
throw new Error("useDatabase must be used within a DatabaseProvider");

View File

@ -3,14 +3,14 @@ import React, { useState, useContext, ReactChild } from "react";
export type AssetLoadStartEventHandler = () => void;
export type AssetLoadFinishEventHandler = () => void;
type DiceLoadingContext = {
type DiceLoadingContextValue = {
assetLoadStart: AssetLoadStartEventHandler;
assetLoadFinish: AssetLoadFinishEventHandler;
isLoading: boolean;
};
const DiceLoadingContext =
React.createContext<DiceLoadingContext | undefined>(undefined);
React.createContext<DiceLoadingContextValue | undefined>(undefined);
export function DiceLoadingProvider({ children }: { children: ReactChild }) {
const [loadingAssetCount, setLoadingAssetCount] = useState(0);
@ -38,7 +38,7 @@ export function DiceLoadingProvider({ children }: { children: ReactChild }) {
);
}
export function useDiceLoading(): DiceLoadingContext {
export function useDiceLoading() {
const context = useContext(DiceLoadingContext);
if (context === undefined) {
throw new Error("useDiceLoading must be used within a DiceLoadingProvider");

View File

@ -26,7 +26,7 @@ export type GroupClearSelectionEventHandler = () => void;
export type GroupFilterChangeEventHandler = (filter: string) => void;
export type GroupClearFilterEventHandler = () => void;
type GroupContext = {
type GroupContextValue = {
groups: Group[];
activeGroups: Group[] | GroupItem[];
openGroupId: string | undefined;
@ -46,7 +46,8 @@ type GroupContext = {
onFilterClear: GroupClearFilterEventHandler;
};
const GroupContext = React.createContext<GroupContext | undefined>(undefined);
const GroupContext =
React.createContext<GroupContextValue | undefined>(undefined);
type GroupProviderProps = {
groups: Group[];
@ -249,7 +250,7 @@ export function GroupProvider({
useBlur(handleBlur);
const value: GroupContext = {
const value = {
groups,
activeGroups,
openGroupId,

View File

@ -33,7 +33,7 @@ export type GetMapStateEventHandler = (
export type GetMapEventHandler = (id: string) => Promise<Map | undefined>;
export type UpdateMapGroupsEventHandler = (groups: Group[]) => Promise<void>;
type MapDataContext = {
type MapDataContextValue = {
maps: Array<Map>;
mapStates: MapState[];
/** Adds a map to the database, also adds an assosiated state and group for that map */
@ -51,7 +51,7 @@ type MapDataContext = {
};
const MapDataContext =
React.createContext<MapDataContext | undefined>(undefined);
React.createContext<MapDataContextValue | undefined>(undefined);
const defaultMapState: Omit<MapState, "mapId"> = {
tokens: {},

View File

@ -9,7 +9,7 @@ type MapLoadingProgressUpdate = MapLoadingProgress & {
id: string;
};
type MapLoadingContext = {
type MapLoadingContextValue = {
isLoading: boolean;
assetLoadStart: (id: string) => void;
assetProgressUpdate: (update: MapLoadingProgressUpdate) => void;
@ -17,7 +17,7 @@ type MapLoadingContext = {
};
const MapLoadingContext =
React.createContext<MapLoadingContext | undefined>(undefined);
React.createContext<MapLoadingContextValue | undefined>(undefined);
export function MapLoadingProvider({
children,

View File

@ -4,13 +4,13 @@ import { getSettings } from "../settings";
import { Settings } from "../types/Settings";
type SettingsContext = {
type SettingsContextValue = {
settings: Settings;
setSettings: React.Dispatch<React.SetStateAction<Settings>>;
};
const SettingsContext =
React.createContext<SettingsContext | undefined>(undefined);
React.createContext<SettingsContextValue | undefined>(undefined);
const settingsProvider = getSettings();

View File

@ -29,7 +29,7 @@ export type UpdateTokensHiddenEventHandler = (
hideInSidebar: boolean
) => Promise<void>;
type TokenDataContext = {
type TokenDataContextValue = {
tokens: Token[];
addToken: AddTokenEventHandler;
tokenGroups: Group[];
@ -43,7 +43,7 @@ type TokenDataContext = {
};
const TokenDataContext =
React.createContext<TokenDataContext | undefined>(undefined);
React.createContext<TokenDataContextValue | undefined>(undefined);
export function TokenDataProvider({ children }: { children: React.ReactNode }) {
const { database } = useDatabase();
@ -152,7 +152,7 @@ export function TokenDataProvider({ children }: { children: React.ReactNode }) {
);
}, [tokens]);
const value: TokenDataContext = {
const value = {
tokens,
addToken,
tokenGroups,
@ -172,7 +172,7 @@ export function TokenDataProvider({ children }: { children: React.ReactNode }) {
);
}
export function useTokenData(): TokenDataContext {
export function useTokenData() {
const context = useContext(TokenDataContext);
if (context === undefined) {
throw new Error("useTokenData must be used within a TokenDataProvider");

1
src/global.d.ts vendored
View File

@ -19,3 +19,4 @@ declare module "*.bin" {
export default source;
}
declare module "react-router-hash-link";
declare module "intersection-observer";

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect, useRef } from "react";
import { useState, useEffect, useRef } from "react";
import Konva from "konva";
import { Line, Group, Path, Circle } from "react-konva";
import Color from "color";

View File

@ -1,5 +1,7 @@
import Case from "case";
import { Map, MapState } from "../components/map/Map";
import { DefaultMap } from "../types/Map";
import { MapState } from "../types/MapState";
import blankImage from "./Blank.jpg";
import grassImage from "./Grass.jpg";
@ -19,15 +21,18 @@ export const mapSources = {
wood: woodImage,
};
export function getDefaultMaps(userId: string) : {maps: Map[], mapStates: MapState[]} {
export function getDefaultMaps(userId: string): {
maps: DefaultMap[];
mapStates: MapState[];
} {
const mapKeys = Object.keys(mapSources);
let maps = [];
let mapStates = [];
let maps: DefaultMap[] = [];
let mapStates: MapState[] = [];
for (let i = 0; i < mapKeys.length; i++) {
const key = mapKeys[i];
const name = Case.capital(key);
const id = `__default-${name}`;
const map = {
const map: DefaultMap = {
id,
key,
name,
@ -45,10 +50,9 @@ export function getDefaultMaps(userId: string) : {maps: Map[], mapStates: MapSta
lastModified: Date.now(),
showGrid: key !== "stone",
snapToGrid: true,
group: "",
};
maps.push(map);
const state = {
const state: MapState = {
mapId: id,
tokens: {},
drawShapes: {},

View File

@ -94,7 +94,7 @@ function ImportExportModal({
await worker.importData(
file,
importDBName,
Comlink.proxy(handleDBProgress)
Comlink.proxy(handleDBProgress) as any
);
setIsLoading(false);
@ -387,7 +387,7 @@ function ImportExportModal({
try {
const buffer = await worker.exportData(
Comlink.proxy(handleDBProgress),
Comlink.proxy(handleDBProgress) as any,
mapIds,
tokenIds
);

View File

@ -1,4 +1,5 @@
import Case from "case";
import { DefaultToken } from "../types/Token";
import aberration from "./Aberration.png";
import artificer from "./Artificer.png";
@ -80,13 +81,13 @@ function getDefaultTokenSize(key: string) {
}
}
export function getDefaultTokens(userId: string) {
export function getDefaultTokens(userId: string): DefaultToken[] {
const tokenKeys = Object.keys(tokenSources);
let tokens = [];
let tokens: DefaultToken[] = [];
for (let i = 0; i < tokenKeys.length; i++) {
const key = tokenKeys[i];
const name = Case.capital(key);
const token = {
const token: DefaultToken = {
key,
name,
id: `__default-${name}`,

View File

@ -93,7 +93,7 @@ let service = {
assetIds.push(map.file);
assetIds.push(map.thumbnail);
for (let res of Object.values(map.resolutions)) {
assetIds.push(res);
res && assetIds.push(res);
}
}
}