expo-share-multi-intent
Version:
use native share intent for ios and android with expo
126 lines • 4.75 kB
JavaScript
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