From cf5ba35e73f1d703badb8ac31b823606fc4c9c30 Mon Sep 17 00:00:00 2001 From: aurimasmi Date: Wed, 31 May 2023 23:39:12 +0300 Subject: [PATCH 1/3] make scale animation on androidtv cover over top of other items --- packages/app-harness/src/screens/row.tsx | 2 +- .../components/FlashList/index.native.tv.tsx | 37 +++++++++++++++++-- packages/create/src/focusManager/events.ts | 2 + .../create/src/focusManager/model/view.ts | 28 +++++++++++--- packages/create/src/focusManager/types.ts | 6 ++- packages/create/src/hooks/useCombinedRef.ts | 6 +-- 6 files changed, 67 insertions(+), 14 deletions(-) diff --git a/packages/app-harness/src/screens/row.tsx b/packages/app-harness/src/screens/row.tsx index 36c680c76..8e161535a 100644 --- a/packages/app-harness/src/screens/row.tsx +++ b/packages/app-harness/src/screens/row.tsx @@ -75,7 +75,7 @@ const styles = StyleSheet.create({ // borderColor: 'red', // borderWidth: 1, marginHorizontal: 5, - // marginVertical: Ratio(50), + marginVertical: Ratio(50), // borderWidth: 2, // top: 100, }, diff --git a/packages/create/src/components/FlashList/index.native.tv.tsx b/packages/create/src/components/FlashList/index.native.tv.tsx index c0388f37c..800326898 100644 --- a/packages/create/src/components/FlashList/index.native.tv.tsx +++ b/packages/create/src/components/FlashList/index.native.tv.tsx @@ -1,13 +1,14 @@ import React, { useEffect, useRef, useState } from 'react'; import { View as RNView } from 'react-native'; -import { FlashList as FlashListComp, ListRenderItemInfo } from '@flexn/shopify-flash-list'; - +import { FlashList as FlashListComp, ListRenderItemInfo, CellContainer } from '@flexn/shopify-flash-list'; +import { isPlatformAndroidtv, isPlatformFiretv } from '@rnv/renative'; import Grid from '../../focusManager/model/grid'; import List from '../../focusManager/model/list'; import Row from '../../focusManager/model/row'; -import { FlashListProps } from '../../focusManager/types'; +import { FlashListProps, CellContainerProps } from '../../focusManager/types'; import useOnLayout from '../../hooks/useOnLayout'; import useOnRefChange from '../../hooks/useOnRefChange'; +import { useCombinedRefs } from '../../hooks/useCombinedRef'; import useFocusAwareComponentRegister from '../../hooks/useOnComponentLifeCycle'; import Event, { EVENT_TYPES } from '../../focusManager/events'; @@ -85,6 +86,35 @@ const FlashList = ({ }); }; + const ItemContainer = React.forwardRef((props: CellContainerProps, ref: any) => { + const { style, children } = props; + const target = useCombinedRefs({ refs: [ref], model: null }); + + useEffect(() => { + const eventFocus = Event.subscribe(model, EVENT_TYPES.ON_CELL_CONTAINER_FOCUS, (idx) => { + if (idx === props.index) { + target.current?.setNativeProps({ zIndex: 1 }); + } + }); + const eventBlur = Event.subscribe(model, EVENT_TYPES.ON_CELL_CONTAINER_BLUR, (idx) => { + if (idx === props.index) { + target.current?.setNativeProps({ zIndex: 0 }); + } + }); + + return () => { + eventFocus(); + eventBlur(); + }; + }, [props.index]); + + return ( + + {children} + + ); + }); + return ( {measured && ( @@ -93,6 +123,7 @@ const FlashList = ({ data={data} renderItem={rowRendererWithProps} horizontal={horizontal} + CellRendererComponent={isPlatformAndroidtv || isPlatformFiretv ? ItemContainer : undefined} {...props} overrideProps={{ ...scrollViewProps, diff --git a/packages/create/src/focusManager/events.ts b/packages/create/src/focusManager/events.ts index 3eb8fe175..667434455 100644 --- a/packages/create/src/focusManager/events.ts +++ b/packages/create/src/focusManager/events.ts @@ -7,6 +7,8 @@ export const EVENT_TYPES = { ON_UNMOUNT: 'onUnMount', ON_LAYOUT: 'onLayout', ON_LAYOUT_MEASURE_COMPLETED: 'onLayoutMeasureCompleted', + ON_CELL_CONTAINER_FOCUS: 'onCellContainerFocus', + ON_CELL_CONTAINER_BLUR: 'onCellContainerBlur', }; const events: { [key: string]: { [key: string]: { [key: string]: { [key: string]: (...args: any) => void } } } } = {}; diff --git a/packages/create/src/focusManager/model/view.ts b/packages/create/src/focusManager/model/view.ts index 0cef059ef..9520c5436 100644 --- a/packages/create/src/focusManager/model/view.ts +++ b/packages/create/src/focusManager/model/view.ts @@ -6,6 +6,8 @@ import Event, { EVENT_TYPES } from '../events'; import { measureAsync } from '../layoutManager'; import Row from './row'; import ViewGroup from './viewGroup'; +import Grid from './grid'; +import List from './list'; class View extends FocusModel { private _parentRecyclerView?: Recycler; @@ -17,9 +19,9 @@ class View extends FocusModel { private _verticalContentContainerGap: number; private _repeatContext: | { - focusContext: FocusModel; - index: number; - } + focusContext: FocusModel; + index: number; + } | undefined; private _onPress?: () => void; @@ -36,7 +38,7 @@ class View extends FocusModel { onPress, focusKey, hasPreferredFocus, - verticalContentContainerGap = 0 + verticalContentContainerGap = 0, } = params; const id = CoreManager.generateID(8); @@ -102,6 +104,18 @@ class View extends FocusModel { // END EVENTS + public onBlur(): void { + const parent = this.getParent(); + + if (this._onBlur) { + this._onBlur(); + } + + if (parent instanceof Row || parent instanceof Grid || parent instanceof List) { + Event.emit(parent, EVENT_TYPES.ON_CELL_CONTAINER_BLUR, this.getRepeatContext()?.index); + } + } + public onFocus(): void { const parent = this.getParent(); @@ -111,6 +125,10 @@ class View extends FocusModel { if (parent instanceof Row) { parent.setFocusedView(this); } + + if (parent instanceof Row || parent instanceof Grid || parent instanceof List) { + Event.emit(parent, EVENT_TYPES.ON_CELL_CONTAINER_FOCUS, this.getRepeatContext()?.index); + } } public isFocusable(): boolean { @@ -208,7 +226,7 @@ class View extends FocusModel { } return group || this.getScreen()?.getGroup(); - }; + } } export default View; diff --git a/packages/create/src/focusManager/types.ts b/packages/create/src/focusManager/types.ts index 2a4c201af..bb58c16e0 100644 --- a/packages/create/src/focusManager/types.ts +++ b/packages/create/src/focusManager/types.ts @@ -44,7 +44,7 @@ export type PressableFocusOptions = { nextFocusRight?: string | string[]; nextFocusUp?: string | string[]; nextFocusDown?: string | string[]; - group?: string + group?: string; }; export type ScreenFocusOptions = { @@ -144,4 +144,8 @@ export interface FlashListProps extends FLProps { onFocus?: () => void; } +export interface CellContainerProps extends ViewProps { + index: number; +} + export type FocusContext = FocusModel; diff --git a/packages/create/src/hooks/useCombinedRef.ts b/packages/create/src/hooks/useCombinedRef.ts index 17fbbf821..9773aae7d 100644 --- a/packages/create/src/hooks/useCombinedRef.ts +++ b/packages/create/src/hooks/useCombinedRef.ts @@ -1,4 +1,4 @@ -import { useEffect, MutableRefObject, ForwardedRef, LegacyRef } from 'react'; +import { useEffect, MutableRefObject, ForwardedRef } from 'react'; import FocusModel from '../focusManager/model/FocusModel'; import useOnRefChange from './useOnRefChange'; @@ -8,10 +8,8 @@ export function useCombinedRefs({ }: { refs: MutableRefObject[] | ForwardedRef[]; model: FocusModel | null; -}): MutableRefObject | LegacyRef { - // const targetRef = useRef>(); +}): MutableRefObject { const { targetRef } = useOnRefChange(model); - // const targetRef = useRef>(); useEffect(() => { refs.forEach((ref: any) => { From 703b8b0fc4827ddaa7807f64f3af15553c06474c Mon Sep 17 00:00:00 2001 From: aurimasmi Date: Wed, 31 May 2023 23:41:08 +0300 Subject: [PATCH 2/3] chore: rename property --- .../create/src/components/FlashList/index.native.tv.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/create/src/components/FlashList/index.native.tv.tsx b/packages/create/src/components/FlashList/index.native.tv.tsx index 800326898..12ccd9715 100644 --- a/packages/create/src/components/FlashList/index.native.tv.tsx +++ b/packages/create/src/components/FlashList/index.native.tv.tsx @@ -91,13 +91,13 @@ const FlashList = ({ const target = useCombinedRefs({ refs: [ref], model: null }); useEffect(() => { - const eventFocus = Event.subscribe(model, EVENT_TYPES.ON_CELL_CONTAINER_FOCUS, (idx) => { - if (idx === props.index) { + const eventFocus = Event.subscribe(model, EVENT_TYPES.ON_CELL_CONTAINER_FOCUS, (index) => { + if (index === props.index) { target.current?.setNativeProps({ zIndex: 1 }); } }); - const eventBlur = Event.subscribe(model, EVENT_TYPES.ON_CELL_CONTAINER_BLUR, (idx) => { - if (idx === props.index) { + const eventBlur = Event.subscribe(model, EVENT_TYPES.ON_CELL_CONTAINER_BLUR, (index) => { + if (index === props.index) { target.current?.setNativeProps({ zIndex: 0 }); } }); From 90ed04a78607a99b9d1d15295ffa8a314c5f682e Mon Sep 17 00:00:00 2001 From: aurimasmi Date: Wed, 31 May 2023 23:43:54 +0300 Subject: [PATCH 3/3] chore: simplify props --- .../create/src/components/FlashList/index.native.tv.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/create/src/components/FlashList/index.native.tv.tsx b/packages/create/src/components/FlashList/index.native.tv.tsx index 12ccd9715..d59bdc704 100644 --- a/packages/create/src/components/FlashList/index.native.tv.tsx +++ b/packages/create/src/components/FlashList/index.native.tv.tsx @@ -87,7 +87,6 @@ const FlashList = ({ }; const ItemContainer = React.forwardRef((props: CellContainerProps, ref: any) => { - const { style, children } = props; const target = useCombinedRefs({ refs: [ref], model: null }); useEffect(() => { @@ -108,11 +107,7 @@ const FlashList = ({ }; }, [props.index]); - return ( - - {children} - - ); + return ; }); return (