UNPKG

@applicaster/zapp-react-native-utils

Version:

Applicaster Zapp React Native utilities package

80 lines (67 loc) 2.25 kB
import { ReplaySubject, Subject } from "rxjs"; import { filter, first, switchMap } from "rxjs/operators"; import { BUTTON_PREFIX } from "@applicaster/zapp-react-native-ui-components/Components/MasterCell/DefaultComponents/tv/TvActionButtons/const"; import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager/index.ios"; type FocusableID = string; type RegistrationEvent = { id: FocusableID; registered: boolean; }; const isFocusableButton = (id: Option<FocusableID>): boolean => id && id.includes?.(BUTTON_PREFIX); const registeredSubject$ = new ReplaySubject<RegistrationEvent>(1); export const focusableButtonsRegistration$ = (focusableGroupId: string) => registeredSubject$.pipe( filter( (value) => value.registered && focusManager.isChildOf(value.id, focusableGroupId) ) ); const focusableViewRegistrationSubject$ = new Subject<{ id: FocusableID; parentId: FocusableID; }>(); let focusableGroupRegistrationSubject$ = new ReplaySubject<{ id: FocusableID; }>(); export const resetFocusableGroupRegistration = () => { // complete the old subject so subscribers are notified and resources are freed focusableGroupRegistrationSubject$.complete(); focusableGroupRegistrationSubject$ = new ReplaySubject<{ id: FocusableID; }>(); }; export const firstFocusableViewRegistration$ = focusableViewRegistrationSubject$.pipe( first(), // we care about only first FocusableView registration switchMap(({ parentId }) => // start waiting registration of its parent focusableGroupRegistrationSubject$.pipe( filter(({ id }) => id === parentId) ) ), first() ); export const emitRegistered = ({ id, parentId, isGroup, }: { id: Option<FocusableID>; parentId: Option<FocusableID>; isGroup: boolean; }): void => { if (isFocusableButton(id)) { registeredSubject$.next({ id, registered: true }); } if (!isGroup) { focusableViewRegistrationSubject$.next({ id, parentId }); } else { focusableGroupRegistrationSubject$.next({ id }); } }; export const emitUnregistered = (id: Option<FocusableID>): void => { if (isFocusableButton(id)) { registeredSubject$.next({ id, registered: false }); } };