UNPKG

@applicaster/quick-brick-core

Version:

Core package for Applicaster's Quick Brick App

222 lines (181 loc) 6.21 kB
import { useActions } from "@applicaster/zapp-react-native-redux/hooks"; import * as R from "ramda"; import * as React from "react"; import axios from "axios"; import { useDispatch } from "react-redux"; import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks"; import { useFeedLoader } from "@applicaster/zapp-react-native-utils/reactHooks/feed/useFeedLoader"; import { sessionStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/SessionStorage"; import { loadAppContextData } from "@applicaster/zapp-react-native-redux"; import { noop } from "@applicaster/zapp-react-native-utils/functionUtils"; import { setAppNotReady, setAppReady, } from "@applicaster/zapp-react-native-redux/appState"; import { findRiver, getKeyFromStorage, handlePresentNavigation, isInternalUrl, } from "../../helpers"; import { log_error, log_info } from "../../logger"; import { useRivers } from "@applicaster/zapp-react-native-utils/reactHooks/state"; const getFeed = (query) => ({ content: { src: query.data_source }, screen_type: query.screen_id, }); export function usePresentSchemeHandler({ query, url, onFinish, }: UrlSchemeHandlerArgs) { const { screen_id, data_source, entry_id, rivers_configuration_id, resumeTime, link_url, show_nav_bar, content_type, } = query; React.useEffect(() => { log_info(`Handling present url ${url}`, { query }); }, []); const navigator = useNavigation(); const { data: feedData } = useFeedLoader({ feedUrl: data_source, }); const rivers = useRivers(); const screenRiver = findRiver({ screen_id, rivers }); const dispatch = useDispatch(); const actions = useActions({ setAppReady, setAppNotReady, }); const navigateTo = React.useCallback( (data) => { onFinish((done) => { handlePresentNavigation({ data, navigator, pushScreen: isInternalUrl(url) || link_url, }); done?.(); }); }, [onFinish, navigator, rivers, url] ); const setCustomLayout = React.useCallback( async ({ rivers_configuration_id }) => { let sessionData: Partial<SessionStorageKeys> = {}; try { sessionData = await sessionStorage.getAllItems("applicaster.v2"); // ios returns accountsAccountID, while android has accountsAccountId // until this is aligned, we're pulling both values and use the one that // isn't undefined const accountKey = sessionData.accountsAccountId ? "accountsAccountId" : "zapp_account_id"; // @ts-ignore - to be fixed on iOS side // key accountsAccountID should be accountsAccountId const accountId = getKeyFromStorage<string>(accountKey, sessionData); const appBundleIdentifier = getKeyFromStorage<string>( "bundleIdentifier", sessionData ); const versionName = getKeyFromStorage<string>( "version_name", sessionData ); const familyId = getKeyFromStorage<string>( "app_family_id", sessionData ); const storeKey = getKeyFromStorage<string>("store", sessionData); const riversUrl = `https://assets-secure.applicaster.com/zapp/accounts/${accountId}/apps/${appBundleIdentifier}/${storeKey}/${versionName}/layouts/${rivers_configuration_id}.json`; const cellStylesUrl = `https://assets-secure.applicaster.com/zapp/accounts/${accountId}/app_families/${familyId}/layouts/${rivers_configuration_id}/cell_styles.json`; const presetsMappingUrl = `https://assets-secure.applicaster.com/zapp/accounts/${accountId}/app_families/${familyId}/layouts/${rivers_configuration_id}/presets_mapping.json`; actions?.setAppNotReady(); const { data: newRivers } = await axios.get(riversUrl); const { data: cellStyles } = await axios.get(cellStylesUrl); const presetsMapping = await axios .get(presetsMappingUrl) .then(({ data }) => data) .catch(noop); loadAppContextData(dispatch, { cellStyles, rivers: newRivers, contentTypes: newRivers.content_types, presetsMapping, }); const homeRiver = R.compose( R.find(R.propEq("home", true)), R.ifElse(R.has("screens"), R.prop("screens"), R.values) )(newRivers); await sessionStorage.setItem( "rivers_configuration_id", rivers_configuration_id ); onFinish((done) => { actions?.setAppReady(); navigator.replace(homeRiver); done?.(); }); } catch (error) { log_error(`Cannot handle present url ${url}`, { query, error: error.message, sessionData, }); onFinish((done) => { actions?.setAppReady(); navigator.goHome(); done?.(); }); } }, [] ); const getFeedEntry = React.useCallback( () => query.entry_id ? R.compose( R.when( () => resumeTime, R.assocPath(["extensions", "resumeTime"], resumeTime) ), R.find(R.propEq("id", entry_id)) )(feedData?.entry || []) : getFeed(query), [feedData, query] ); const getLinkEntry = React.useCallback(() => { const linkEntry: ZappEntry = { id: "url_scheme_entry", type: { value: content_type || "link" }, link: { type: "text/html", href: decodeURIComponent(link_url), }, extensions: { showNavBar: show_nav_bar === "true", }, }; if (screenRiver) { linkEntry.screen_type = screenRiver.id; } return linkEntry; }, [show_nav_bar, link_url]); if (link_url) { navigateTo(getLinkEntry()); } else if (rivers_configuration_id) { setCustomLayout({ rivers_configuration_id }); } else if ((data_source || entry_id) && feedData) { navigateTo(getFeedEntry()); } else if (screenRiver) { navigateTo(screenRiver); } else if (!!screen_id && !screenRiver) { throw new Error("сan not proceed this URL"); } }