51 lines
1.4 KiB
TypeScript
51 lines
1.4 KiB
TypeScript
|
|
import { createContext, useContext, type ReactNode } from "react";
|
||
|
|
import type { SightingWidgetType } from "../types/types";
|
||
|
|
import { useSightingFeed } from "../hooks/useSightingFeed";
|
||
|
|
|
||
|
|
type SightingFeedContextType = {
|
||
|
|
items: (SightingWidgetType | null | undefined)[];
|
||
|
|
selectedRef: number | null;
|
||
|
|
setSelectedRef: (ref: number | null) => void;
|
||
|
|
effectiveSelected: SightingWidgetType | null;
|
||
|
|
};
|
||
|
|
|
||
|
|
type SightingFeedProviderProps = {
|
||
|
|
baseUrl: string;
|
||
|
|
entries?: number;
|
||
|
|
pollMs?: number;
|
||
|
|
autoSelectLatest?: boolean;
|
||
|
|
children: ReactNode;
|
||
|
|
};
|
||
|
|
|
||
|
|
const SightingFeedContext = createContext<SightingFeedContextType | undefined>(
|
||
|
|
undefined
|
||
|
|
);
|
||
|
|
|
||
|
|
export const SightingFeedProvider = ({
|
||
|
|
baseUrl,
|
||
|
|
entries = 7,
|
||
|
|
pollMs = 500,
|
||
|
|
autoSelectLatest = true,
|
||
|
|
children,
|
||
|
|
}: SightingFeedProviderProps) => {
|
||
|
|
const { items, selectedRef, setSelectedRef, effectiveSelected } =
|
||
|
|
useSightingFeed(baseUrl, { limit: entries, pollMs, autoSelectLatest });
|
||
|
|
return (
|
||
|
|
<SightingFeedContext.Provider
|
||
|
|
value={{ items, selectedRef, setSelectedRef, effectiveSelected }}
|
||
|
|
>
|
||
|
|
{children}
|
||
|
|
</SightingFeedContext.Provider>
|
||
|
|
);
|
||
|
|
};
|
||
|
|
|
||
|
|
// eslint-disable-next-line react-refresh/only-export-components
|
||
|
|
export const useSightingFeedContext = () => {
|
||
|
|
const ctx = useContext(SightingFeedContext);
|
||
|
|
if (!ctx)
|
||
|
|
throw new Error(
|
||
|
|
"useSightingFeedContext must be used within SightingFeedProvider"
|
||
|
|
);
|
||
|
|
return ctx;
|
||
|
|
};
|