@applicaster/zapp-react-native-utils
Version:
Applicaster Zapp React Native utilities package
215 lines (176 loc) • 5.38 kB
text/typescript
/// <reference types="@applicaster/applicaster-types" />
import * as R from "ramda";
import * as React from "react";
import { Platform } from "react-native";
import createRef from "create-react-ref/lib/createRef";
import { addLifeCycleMethods, wrapInClass, isClassComponent } from "./helpers";
/**
* Invokes the proper function to attach lifecycle methods to any React component (stateless or class)
* @export
* @param {Object} lifecycleMethods map where the key is the lifecycle hook, and the value is the method
* @returns {Function}
*/
export function attachLifeCycleMethods(lifecycleMethods) {
return R.compose(
addLifeCycleMethods(lifecycleMethods),
R.unless(isClassComponent, wrapInClass)
);
}
/**
* creates a React Ref. if the version of React doesn't
* have this API, will use a polyfill instead
*/
export function createReactRef() {
return React.createRef && typeof React.createRef === "function"
? React.createRef()
: createRef();
}
/**
* Clone the children and merge each of the cloned elements with otherProps.
* @param {React.Children} children to clone
* @param {React.Props} otherProps to merge into each of the cloned children
* @returns {React.Children} cloned children with merged props
*/
export function mergeChildrenProps(children, otherProps) {
return React.Children.map(children, (child) =>
React.cloneElement(child, { ...child.props, ...otherProps })
);
}
function getEnvironment(): string {
switch (Platform.OS as QuickBrickPlatforms) {
case "ios":
case "android":
return "native";
case "web":
case "samsung_tv":
case "lg_tv":
return "web";
default:
return "";
}
}
export function isWeb(): boolean {
return getEnvironment() === "web";
}
export function isTV(): boolean {
const platformOS = Platform.OS as QuickBrickPlatforms;
if (
platformOS === "samsung_tv" ||
platformOS === "lg_tv" ||
platformOS === "web"
) {
return true;
}
return Platform.isTV;
}
export function getPlatform(): string {
switch (Platform.OS) {
case "ios":
return isTV() ? "tvos" : "ios";
case "android":
return isTV() ? "android_tv" : "android";
default:
return Platform.OS;
}
}
type PlatformProps = Partial<
Record<QuickBrickPlatforms | QuickBrickEnvironments | "default", unknown>
>;
export function platformSelect(properties: PlatformProps) {
const platform = getPlatform();
const env = getEnvironment();
if (!R.isNil(properties?.[platform])) return properties[platform];
if (!R.isNil(properties?.[env])) return properties[env];
if (!R.isNil(properties?.default)) return properties.default;
}
export const isApplePlatform = () => Platform.OS === "ios";
export const isAndroidPlatform = () => Platform.OS === "android";
export const isTvOSPlatform = () => getPlatform() === "tvos";
export const isAndroidTVPlatform = () => getPlatform() === "android_tv";
declare global {
interface Window {
VIZIO?: {
Chromevox: {
play: (text: string) => void;
};
exitApplication: () => void;
setClosedCaptionHandler: (
callback: (isCCEnabled: boolean) => void
) => void;
};
}
}
/**
* Platforms found in userAgent string, please note that simulators
* might not have the same agents that the devices have
*/
export const PLATFORMS = {
webos: "Web0S",
tizen: "Tizen",
samsung: "SMART-TV",
mac: "Mac",
win: "Win",
linux: "Linux",
iphone: "iPhone",
android: "Android",
mobile: "Mobile",
vizio: "VIZIO",
smartcast: "SmartCast",
conjure: "Conjure",
};
/**
* Simple way of identifying if we have access to the tizen APIs
*/
export const hasTizen = typeof window?.tizen !== "undefined";
/**
* Simple way of identifying if we have access to the webOS APIs
*/
export const hasWebOS = typeof window?.webOS !== "undefined";
export const getUserAgent = () => window?.navigator?.userAgent;
export const isLgPlatform = () => {
const userAgent = getUserAgent();
if (!userAgent) {
return false;
}
// Note: LG uses the number 0 in their userAgent, possibly because of Palm WebOS
return hasWebOS || userAgent.includes(PLATFORMS.webos);
};
export const isSamsungPlatform = () => {
const userAgent = getUserAgent();
if (!userAgent) {
return false;
}
return (
hasTizen ||
userAgent.includes(PLATFORMS.samsung) ||
userAgent.includes(PLATFORMS.tizen)
);
};
/**
* Checks if we are on the Vizio platform by using the userAgent string
*
* Use this method when you need to identify the platform on runtime
* before the VIZIO Companion Library has loaded
*/
export const isVizioPlatform = () => {
const userAgent = getUserAgent();
if (!userAgent) {
return false;
}
const isVizioAgent =
userAgent.includes(PLATFORMS.vizio) ||
userAgent.includes(PLATFORMS.smartcast) ||
userAgent.includes(PLATFORMS.conjure);
return isVizioAgent;
};
/**
* Checks if we are on the Vizio platform by checking for the global VIZIO object
* and the VIZIO Companion Library. This method does not use the userAgent string,
* because it mainly checks whether we have access to apis, which may not be available yet
*/
export const hasVizioAPIs = () => {
const hasAPIs =
typeof window.VIZIO !== "undefined" &&
window?.applicaster?.vizioLibraryDidLoad;
return hasAPIs;
};