@ledgerhq/live-common
Version:
Common ground for the Ledger Live apps
122 lines • 4.64 kB
JavaScript
import React, { useContext, useEffect, createContext, useMemo, useState, useCallback } from "react";
import api from "./api";
import useIsMounted from "../../../hooks/useIsMounted";
import useEnv from "../../../hooks/useEnv";
const initialState = {
isLoading: false,
value: null,
error: null,
};
const initialProvider = "production";
const initialParams = {
branches: ["stable", "soon"],
};
export const liveAppContext = createContext({
state: initialState,
provider: initialProvider,
setProvider: () => { },
updateManifests: () => Promise.resolve(),
});
export function useRemoteLiveAppManifest(appId) {
const liveAppRegistry = useContext(liveAppContext).state;
if (!liveAppRegistry.value || !appId) {
return undefined;
}
return (liveAppRegistry.value.liveAppFilteredById[appId] || liveAppRegistry.value.liveAppById[appId]);
}
export function useRemoteLiveAppContext() {
return useContext(liveAppContext);
}
export function useManifests(options = {}) {
const ctx = useRemoteLiveAppContext();
return useMemo(() => {
const liveAppFiltered = ctx.state?.value?.liveAppFiltered ?? [];
if (Object.keys(options).length === 0) {
return liveAppFiltered;
}
return liveAppFiltered.filter(manifest => Object.entries(options).some(([key, val]) => {
switch (key) {
case "visibility":
return val.includes(manifest[key]);
default:
return manifest[key] === val;
}
}));
}, [options, ctx]);
}
export function RemoteLiveAppProvider({ children, parameters, updateFrequency, }) {
const isMounted = useIsMounted();
const [state, setState] = useState(initialState);
const [provider, setProvider] = useState(initialProvider);
const { allowExperimentalApps, allowDebugApps, apiVersions, platform, llVersion, lang } = parameters;
// apiVersion renamed without (s) because param
const apiVersion = apiVersions ? apiVersions : ["1.0.0", "2.0.0"];
const envProviderURL = useEnv("PLATFORM_MANIFEST_API_URL");
const providerURL = provider === "production" ? envProviderURL : provider;
const updateManifests = useCallback(async () => {
setState(currentState => ({
...currentState,
isLoading: true,
error: null,
}));
const branches = [...(initialParams.branches || [])];
allowExperimentalApps && branches.push("experimental");
allowDebugApps && branches.push("debug");
try {
const allManifests = await api.fetchLiveAppManifests(providerURL);
const catalogManifests = await api.fetchLiveAppManifests(providerURL, {
apiVersion,
branches,
platform,
private: false,
llVersion,
lang: lang ? lang : "en",
});
if (!isMounted())
return;
setState(() => ({
isLoading: false,
value: {
liveAppByIndex: allManifests,
liveAppFiltered: catalogManifests,
liveAppFilteredById: catalogManifests.reduce((acc, liveAppManifest) => {
acc[liveAppManifest.id] = liveAppManifest;
return acc;
}, {}),
liveAppById: allManifests.reduce((acc, liveAppManifest) => {
acc[liveAppManifest.id] = liveAppManifest;
return acc;
}, {}),
},
error: null,
}));
}
catch (error) {
if (!isMounted())
return;
setState(currentState => ({
...currentState,
isLoading: false,
error,
}));
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [allowDebugApps, allowExperimentalApps, providerURL, lang, isMounted]);
const value = useMemo(() => ({
state,
provider,
setProvider,
updateManifests,
}), [state, provider, setProvider, updateManifests]);
useEffect(() => {
const interval = setInterval(() => {
updateManifests();
}, updateFrequency);
updateManifests();
return () => {
clearInterval(interval);
};
}, [updateFrequency, updateManifests]);
return React.createElement(liveAppContext.Provider, { value: value }, children);
}
//# sourceMappingURL=index.js.map