mirror of
https://github.com/Steffo99/festa.git
synced 2024-12-23 07:04:22 +00:00
100 lines
2.8 KiB
TypeScript
100 lines
2.8 KiB
TypeScript
import { Reducer, useCallback, useReducer } from "react"
|
|
import { PostcardContextContents, PostcardSource, PostcardVisibility } from "./base"
|
|
|
|
|
|
/**
|
|
* Action of {@link usePostcardStorage} changing the current postcard to a new one.
|
|
*/
|
|
type UsePostcardStorageActionChange = { type: "change", src: PostcardSource }
|
|
|
|
/**
|
|
* Action of {@link usePostcardStorage} changing the visibility of the current postcard.
|
|
*/
|
|
type UsePostcardStorageActionDisplay = { type: "display", visibility: PostcardVisibility }
|
|
|
|
/**
|
|
* All possible actions of the reducer of {@link usePostcardStorage}.
|
|
*/
|
|
type UsePostcardStorageAction = UsePostcardStorageActionChange | UsePostcardStorageActionDisplay
|
|
|
|
/**
|
|
* The state of the reducer of {@link usePostcardStorage}.
|
|
*/
|
|
type UsePostcardStorageState = {
|
|
visibility: PostcardVisibility,
|
|
currentSrc: PostcardSource,
|
|
previousSrc: PostcardSource,
|
|
}
|
|
|
|
/**
|
|
* Reducer for {@link usePostcardStorage}.
|
|
*/
|
|
function reducerUsePostcardStorage(prev: UsePostcardStorageState, action: UsePostcardStorageAction): UsePostcardStorageState {
|
|
switch (action.type) {
|
|
case "change":
|
|
if (action.src !== prev.currentSrc) {
|
|
return { ...prev, previousSrc: prev.currentSrc, currentSrc: action.src }
|
|
}
|
|
else {
|
|
return prev
|
|
}
|
|
case "display":
|
|
return { ...prev, visibility: action.visibility }
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Convert a {@link PostcardSource} to a string suitable for use in `<img>` tags.
|
|
*/
|
|
function getProperSrc(obj: PostcardSource): string {
|
|
if (typeof obj === "string") {
|
|
return obj
|
|
}
|
|
else {
|
|
return obj.src
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Hook holding as state the {@link PostcardContextContents}.
|
|
*/
|
|
export function usePostcardStorage(defaultPostcard: PostcardSource): PostcardContextContents {
|
|
const [{ previousSrc, currentSrc, visibility }, dispatch] = useReducer<Reducer<UsePostcardStorageState, UsePostcardStorageAction>>(
|
|
reducerUsePostcardStorage,
|
|
{
|
|
visibility: PostcardVisibility.BACKGROUND,
|
|
previousSrc: defaultPostcard,
|
|
currentSrc: defaultPostcard
|
|
}
|
|
)
|
|
|
|
const changePostcard = useCallback(
|
|
(src: PostcardSource) => {
|
|
dispatch({ type: "change", src })
|
|
},
|
|
[dispatch]
|
|
)
|
|
|
|
const resetPostcard = useCallback(
|
|
() => {
|
|
changePostcard(defaultPostcard)
|
|
},
|
|
[changePostcard, defaultPostcard]
|
|
)
|
|
|
|
const changeVisibility = useCallback(
|
|
(visibility: PostcardVisibility) => {
|
|
dispatch({ type: "display", visibility })
|
|
},
|
|
[dispatch]
|
|
)
|
|
|
|
return {
|
|
previousSrc: getProperSrc(previousSrc),
|
|
currentSrc: getProperSrc(currentSrc),
|
|
changePostcard,
|
|
resetPostcard,
|
|
changeVisibility,
|
|
visibility,
|
|
};
|
|
}
|