UNPKG

expo-share-multi-intent

Version:

use native share intent for ios and android with expo

126 lines 4.75 kB
import { useLinkingURL } from "expo-linking"; import { useEffect, useRef, useState } from "react"; import { AppState, Platform } from "react-native"; import ExpoShareIntentModule from "./ExpoShareIntentModule"; import { getScheme, getShareExtensionKey, parseShareIntent } from "./utils"; export const SHAREINTENT_DEFAULTVALUE = { files: null, text: null, webUrl: null, type: null, }; export const SHAREINTENT_OPTIONS_DEFAULT = { debug: false, resetOnBackground: true, disabled: Platform.OS === "web", }; const isValueAvailable = (shareIntent) => !!(shareIntent?.text || shareIntent?.webUrl || shareIntent?.files); export default function useShareIntent(options = SHAREINTENT_OPTIONS_DEFAULT) { const url = useLinkingURL(); const appState = useRef(AppState.currentState); const [shareIntent, setSharedIntent] = useState(SHAREINTENT_DEFAULTVALUE); const [error, setError] = useState(null); const [isReady, setIsReady] = useState(false); const resetShareIntent = (clearNativeModule = true) => { if (options.disabled) return; setError(null); clearNativeModule && ExpoShareIntentModule?.clearShareIntent(getShareExtensionKey(options)); if (isValueAvailable(shareIntent)) { setSharedIntent(SHAREINTENT_DEFAULTVALUE); options.onResetShareIntent?.(); } }; /** * Call native module on universal linking url change */ const refreshShareIntent = () => { options.debug && console.debug("useShareIntent[refresh]", url); if (url?.includes(`${getScheme(options)}://dataUrl=`)) { // iOS only ExpoShareIntentModule?.getShareIntent(url); } else if (Platform.OS === "android") { ExpoShareIntentModule?.getShareIntent(""); } else if (Platform.OS === "ios") { options.debug && console.debug("useShareIntent[refresh] not a valid refresh url"); } }; useEffect(() => { if (options.disabled) return; options.debug && console.debug("useShareIntent[mount]", getScheme(options), options); refreshShareIntent(); }, [url, options.disabled]); /** * Handle application state (active, background, inactive) */ useEffect(() => { if (options.disabled) return; const subscription = AppState.addEventListener("change", (nextAppState) => { if (nextAppState === "active") { options.debug && console.debug("useShareIntent[active] refresh intent"); refreshShareIntent(); } else if (options.resetOnBackground !== false && appState.current === "active" && ["inactive", "background"].includes(nextAppState)) { options.debug && console.debug("useShareIntent[to-background] reset intent"); resetShareIntent(); } appState.current = nextAppState; }); return () => { subscription.remove(); }; }, [url, shareIntent, options.disabled]); /** * Detect Native Module response */ useEffect(() => { if (options.disabled) { options.debug && console.debug("expo-share-intent module is disabled by configuration!"); return; } else if (!ExpoShareIntentModule) { options.debug && console.warn("expo-share-intent module is disabled: ExpoShareIntentModule not found!"); return; } const changeSubscription = ExpoShareIntentModule.addListener("onChange", (event) => { options.debug && console.debug("useShareIntent[onChange]", JSON.stringify(event, null, 2)); try { setSharedIntent(parseShareIntent(event.value, options)); } catch (e) { options.debug && console.error("useShareIntent[onChange]", e); setError("Cannot parse share intent value !"); } }); const errorSubscription = ExpoShareIntentModule.addListener("onError", (event) => { options.debug && console.debug("useShareIntent[error]", event?.value); setError(event?.value); }); setIsReady(true); return () => { changeSubscription.remove(); errorSubscription.remove(); }; }, [options.disabled]); return { isReady, hasShareIntent: isValueAvailable(shareIntent), shareIntent, resetShareIntent, error, }; } //# sourceMappingURL=useShareIntent.js.map