Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

107-ui-controls #116

Merged
merged 6 commits into from
Aug 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .prettierrc.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module.exports = {
bracketSpacing: false,
bracketSameLine: true,
bracketSameLine: false,
singleQuote: true,
trailingComma: 'all',
};
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ This monorepo contains the `react-native-media-console` modules (`./packages/*`)

Issues, pull request, and discussion are all welcome. See the [Contribution Guidelines](CONTRIBUTING.md) for details, and please reach out to [the author](https://github.com/LunatiqueCoder) if you would like to participate more significantly.

Active contributors are eligible to receive a license for all JetBrains Products that can be used for open source development.
<br>

## 🏆 Sponsors
Expand Down
3 changes: 2 additions & 1 deletion examples/MyTVProject/app/(tabs)/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,15 @@
marginBottom: 0,
},
headerShown: false,
}}>
}}
>
<Tabs.Screen
name="index"
options={{
title: 'Home',
tabBarButton,
tabBarLabelStyle: textStyles.default,
tabBarIcon: ({color, focused}) => (

Check warning on line 46 in examples/MyTVProject/app/(tabs)/_layout.tsx

View workflow job for this annotation

GitHub Actions / build

Do not define components during render. React will see a new component type on every render and destroy the entire subtree’s DOM nodes and state (https://reactjs.org/docs/reconciliation.html#elements-of-different-types). Instead, move this component definition out of the parent component “TabLayout” and pass data as props. If you want to allow component creation in props, set allowAsProps option to true

Check warning on line 46 in examples/MyTVProject/app/(tabs)/_layout.tsx

View workflow job for this annotation

GitHub Actions / build

Do not define components during render. React will see a new component type on every render and destroy the entire subtree’s DOM nodes and state (https://reactjs.org/docs/reconciliation.html#elements-of-different-types). Instead, move this component definition out of the parent component “TabLayout” and pass data as props. If you want to allow component creation in props, set allowAsProps option to true
<TabBarIcon
name={focused ? 'home' : 'home-outline'}
color={color}
Expand All @@ -56,7 +57,7 @@
title: 'Explore',
tabBarButton,
tabBarLabelStyle: textStyles.default,
tabBarIcon: ({color, focused}) => (

Check warning on line 60 in examples/MyTVProject/app/(tabs)/_layout.tsx

View workflow job for this annotation

GitHub Actions / build

Do not define components during render. React will see a new component type on every render and destroy the entire subtree’s DOM nodes and state (https://reactjs.org/docs/reconciliation.html#elements-of-different-types). Instead, move this component definition out of the parent component “TabLayout” and pass data as props. If you want to allow component creation in props, set allowAsProps option to true

Check warning on line 60 in examples/MyTVProject/app/(tabs)/_layout.tsx

View workflow job for this annotation

GitHub Actions / build

Do not define components during render. React will see a new component type on every render and destroy the entire subtree’s DOM nodes and state (https://reactjs.org/docs/reconciliation.html#elements-of-different-types). Instead, move this component definition out of the parent component “TabLayout” and pass data as props. If you want to allow component creation in props, set allowAsProps option to true
<TabBarIcon
name={focused ? 'code-slash' : 'code-slash-outline'}
color={color}
Expand All @@ -70,7 +71,7 @@
title: 'TV event demo',
tabBarButton,
tabBarLabelStyle: textStyles.default,
tabBarIcon: ({color, focused}) => (

Check warning on line 74 in examples/MyTVProject/app/(tabs)/_layout.tsx

View workflow job for this annotation

GitHub Actions / build

Do not define components during render. React will see a new component type on every render and destroy the entire subtree’s DOM nodes and state (https://reactjs.org/docs/reconciliation.html#elements-of-different-types). Instead, move this component definition out of the parent component “TabLayout” and pass data as props. If you want to allow component creation in props, set allowAsProps option to true

Check warning on line 74 in examples/MyTVProject/app/(tabs)/_layout.tsx

View workflow job for this annotation

GitHub Actions / build

Do not define components during render. React will see a new component type on every render and destroy the entire subtree’s DOM nodes and state (https://reactjs.org/docs/reconciliation.html#elements-of-different-types). Instead, move this component definition out of the parent component “TabLayout” and pass data as props. If you want to allow component creation in props, set allowAsProps option to true
<TabBarIcon
name={focused ? 'code-slash' : 'code-slash-outline'}
color={color}
Expand Down
3 changes: 2 additions & 1 deletion examples/MyTVProject/app/(tabs)/explore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
name="code-slash"
style={styles.headerImage}
/>
}>
}
>
<ThemedView style={styles.titleContainer}>
<ThemedText type="title">Explore</ThemedText>
</ThemedView>
Expand Down Expand Up @@ -64,7 +65,7 @@
</ThemedText>
<Image
source={require('@/assets/images/react-logo.png')}
style={{alignSelf: 'center'}}

Check warning on line 68 in examples/MyTVProject/app/(tabs)/explore.tsx

View workflow job for this annotation

GitHub Actions / build

Inline style: { alignSelf: 'center' }

Check warning on line 68 in examples/MyTVProject/app/(tabs)/explore.tsx

View workflow job for this annotation

GitHub Actions / build

Inline style: { alignSelf: 'center' }
/>
<ExternalLink href="https://reactnative.dev/docs/images">
<ThemedText type="link">Learn more</ThemedText>
Expand All @@ -74,7 +75,7 @@
<ThemedText>
Open <ThemedText type="defaultSemiBold">app/_layout.tsx</ThemedText>{' '}
to see how to load{' '}
<ThemedText style={{fontFamily: 'SpaceMono'}}>

Check warning on line 78 in examples/MyTVProject/app/(tabs)/explore.tsx

View workflow job for this annotation

GitHub Actions / build

Inline style: { fontFamily: 'SpaceMono' }

Check warning on line 78 in examples/MyTVProject/app/(tabs)/explore.tsx

View workflow job for this annotation

GitHub Actions / build

Inline style: { fontFamily: 'SpaceMono' }
custom fonts such as this one.
</ThemedText>
</ThemedText>
Expand Down
3 changes: 2 additions & 1 deletion examples/MyTVProject/app/(tabs)/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
source={require('@/assets/images/partial-react-logo.png')}
style={styles.reactLogo}
/>
}>
}
>
<View style={{height: 300}}>

Check warning on line 22 in examples/MyTVProject/app/(tabs)/index.tsx

View workflow job for this annotation

GitHub Actions / build

Inline style: { height: 300 }

Check warning on line 22 in examples/MyTVProject/app/(tabs)/index.tsx

View workflow job for this annotation

GitHub Actions / build

Inline style: { height: 300 }
<VideoPlayer source={{uri: 'https://vjs.zencdn.net/v/oceans.mp4'}} />
</View>
<ThemedView style={styles.titleContainer}>
Expand Down
3 changes: 2 additions & 1 deletion examples/MyTVProject/app/(tabs)/tv_focus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ export default function FocusDemoScreen() {
name="tv-outline"
style={styles.headerImage}
/>
}>
}
>
<ThemedView style={styles.titleContainer}>
<ThemedText type="title">TV event handling demo</ThemedText>
</ThemedView>
Expand Down
3 changes: 2 additions & 1 deletion examples/MyTVProject/components/Collapsible.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ export function Collapsible({
<TouchableOpacity
style={styles.heading}
onPress={() => setIsOpen((value) => !value)}
activeOpacity={0.6}>
activeOpacity={0.6}
>
<Ionicons
name={isOpen ? 'chevron-down' : 'chevron-forward-outline'}
size={18}
Expand Down
12 changes: 8 additions & 4 deletions examples/MyTVProject/components/EventHandlingDemo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ const PressableButton = (props: {
}
style={({pressed, focused}) =>
pressed || focused ? styles.pressableFocused : styles.pressable
}>
}
>
{({focused}) => {
return (
<ThemedText style={styles.pressableText}>
Expand Down Expand Up @@ -135,7 +136,8 @@ const TouchableOpacityButton = (props: {
event.eventKeyAction === 0 ? 'start' : 'end'
}`,
)
}>
}
>
<Text style={styles.pressableText}>{props.title}</Text>
</TouchableOpacity>
);
Expand All @@ -161,7 +163,8 @@ const TouchableHighlightButton = (props: {
event.eventKeyAction === 0 ? 'start' : 'end'
}`,
)
}>
}
>
<Text style={styles.pressableText}>{props.title}</Text>
</TouchableHighlight>
);
Expand All @@ -185,7 +188,8 @@ const TouchableNativeFeedbackButton = (props: {
event.eventKeyAction === 0 ? 'start' : 'end'
}`,
)
}>
}
>
<View style={styles.pressable}>
<Text style={styles.pressableText}>{props.title}</Text>
</View>
Expand Down
3 changes: 2 additions & 1 deletion examples/MyTVProject/components/ExternalLink.tv.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
return (
<Pressable
onPress={() =>
Linking.openURL(href).catch((reason) => alert(`${reason}`))

Check warning on line 12 in examples/MyTVProject/components/ExternalLink.tv.tsx

View workflow job for this annotation

GitHub Actions / build

Unexpected alert

Check warning on line 12 in examples/MyTVProject/components/ExternalLink.tv.tsx

View workflow job for this annotation

GitHub Actions / build

Unexpected alert
}
style={({pressed, focused}) => ({
opacity: pressed || focused ? 0.6 : 1.0,
})}>
})}
>
{rest.children}
</Pressable>
);
Expand Down
3 changes: 2 additions & 1 deletion examples/MyTVProject/components/ParallaxScrollView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ export default function ParallaxScrollView({
styles.header,
{backgroundColor: headerBackgroundColor[colorScheme]},
headerAnimatedStyle,
]}>
]}
>
{headerImage}
</Animated.View>
<ThemedView style={styles.content}>{children}</ThemedView>
Expand Down
3 changes: 2 additions & 1 deletion packages/media-console/src/OSSupport/PlatformSupport.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ export const PlatformSupport = ({
<TouchableWithoutFeedback
testID={testID}
onPress={onScreenTouch}
style={[_styles.player.container, containerStyles]}>
style={[_styles.player.container, containerStyles]}
>
{children}
</TouchableWithoutFeedback>
);
Expand Down
3 changes: 2 additions & 1 deletion packages/media-console/src/VideoPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,8 @@ const AnimatedVideoPlayer = (
showControls={showControls}
containerStyles={styles.containerStyle}
onScreenTouch={events.onScreenTouch}
testID={testID}>
testID={testID}
>
<View style={[_styles.player.container, styles.containerStyle]}>
<Video
{...props}
Expand Down
2 changes: 1 addition & 1 deletion packages/media-console/src/components/Back/Back.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ interface BackProps {

export const Back = ({onBack, showControls}: BackProps) => {
return (
<Control callback={onBack} disabled={!showControls}>
<Control onPress={onBack} disabled={!showControls}>
<Image source={require('../../assets/img/back.png')} />
</Control>
);
Expand Down
9 changes: 6 additions & 3 deletions packages/media-console/src/components/BottomControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ export const BottomControls = ({
<Timer
resetControlTimeout={resetControlTimeout}
toggleTimer={toggleTimer}
showControls={showControls}>
showControls={showControls}
>
{calculateTime({
showDuration,
showHours,
Expand Down Expand Up @@ -106,11 +107,13 @@ export const BottomControls = ({
_styles.bottom,
animations.controlsOpacity,
animations.bottomControl,
]}>
]}
>
<ImageBackground
source={require('../assets/img/bottom-vignette.png')}
style={[styles.column]}
imageStyle={[styles.vignette]}>
imageStyle={[styles.vignette]}
>
<SafeAreaView style={[styles.row, _styles.bottomControlGroup]}>
{timerControl}
<Title title={title} />
Expand Down
56 changes: 29 additions & 27 deletions packages/media-console/src/components/Control.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,47 @@
import React, {ReactNode, RefObject, useState} from 'react';
import {TouchableHighlight, ViewProps} from 'react-native';
import React, {ReactNode, RefObject} from 'react';
import {
TouchableHighlight,
Pressable,
PressableProps,
ViewStyle,
StyleProp,
} from 'react-native';
import {styles} from './styles';

interface ControlProps extends ViewProps {
const focusedStyle = {opacity: 1};
const pressedStyle = {opacity: 0.25};

interface ControlProps extends PressableProps {
children: ReactNode;
callback?: () => void;
controlRef?: RefObject<TouchableHighlight>;
disabled?: boolean;
style?: any;
resetControlTimeout?: () => void;
style?: StyleProp<ViewStyle>;
}

export const Control = ({
children,
callback,
controlRef,
disabled,
style = {},
onPress,
resetControlTimeout,
style,
...props
}: ControlProps) => {
const [focused, setFocused] = useState(false);

const setFocusedState = () => setFocused(true);
const cancelFocusedState = () => setFocused(false);

const focusedStyle = focused ? {opacity: 1} : {};

return (
<TouchableHighlight
onFocus={setFocusedState}
onBlur={cancelFocusedState}
disabled={disabled}
<Pressable
ref={controlRef}
underlayColor="transparent"
activeOpacity={1}
onPress={() => {
callback && callback();
onPress={(evt) => {
onPress?.(evt);
resetControlTimeout?.();
}}
style={[styles.control, style, focused && focusedStyle]}
{...props}>
style={({focused, pressed}) => [
styles.control,
style,
focused && focusedStyle,
pressed && pressedStyle,
]}
{...props}
>
{children}
</TouchableHighlight>
</Pressable>
);
};
5 changes: 3 additions & 2 deletions packages/media-console/src/components/Fullscreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ export const Fullscreen = ({
: require('../assets/img/expand.png');
return (
<Control
callback={toggleFullscreen}
onPress={toggleFullscreen}
resetControlTimeout={resetControlTimeout}
style={styles.fullscreen}
disabled={!showControls}>
disabled={!showControls}
>
<Image source={source} />
</Control>
);
Expand Down
49 changes: 28 additions & 21 deletions packages/media-console/src/components/PlayPause/PlayPause.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, {createRef} from 'react';
import {Image, Platform, TouchableHighlight} from 'react-native';
import {View, Image, Platform, TouchableHighlight} from 'react-native';
import {Control} from '../Control';
import {NullControl} from '../NullControl';
import type {VideoAnimations} from '../../types';
Expand Down Expand Up @@ -48,34 +48,41 @@ export const PlayPause = ({
return (
<AnimatedView
pointerEvents={'box-none'}
style={[styles.container, animatedStyles, animations.controlsOpacity]}>
style={[styles.container, animatedStyles, animations.controlsOpacity]}
>
{!disableSeekButtons ? (
<Control
disabled={!showControls}
callback={onPressRewind}
resetControlTimeout={resetControlTimeout}>
<Image source={rewind} resizeMode={'contain'} style={styles.rewind} />
onPress={onPressRewind}
resetControlTimeout={resetControlTimeout}
>
<Image source={rewind} resizeMode={'contain'} />
</Control>
) : null}
<Control
disabled={!showControls}
callback={togglePlayPause}
resetControlTimeout={resetControlTimeout}
style={styles.playContainer}
controlRef={playPauseRef}
{...(Platform.isTV ? {hasTVPreferredFocus: showControls} : {})}>
<Image source={source} resizeMode={'contain'} style={styles.play} />
</Control>

{/*
* Useless <View />, I know. But it fixes this bug:
* https://github.com/LunatiqueCoder/react-native-media-console/issues/107
*/}
<View style={styles.playContainer}>
<Control
disabled={!showControls}
onPress={togglePlayPause}
resetControlTimeout={resetControlTimeout}
style={styles.play}
controlRef={playPauseRef}
{...(Platform.isTV ? {hasTVPreferredFocus: showControls} : {})}
>
<Image source={source} resizeMode={'contain'} />
</Control>
</View>
{!disableSeekButtons ? (
<Control
disabled={!showControls}
callback={onPressForward}
resetControlTimeout={resetControlTimeout}>
<Image
source={forward}
resizeMode={'contain'}
style={styles.rewind}
/>
onPress={onPressForward}
resetControlTimeout={resetControlTimeout}
>
<Image source={forward} resizeMode={'contain'} />
</Control>
) : null}
</AnimatedView>
Expand Down
4 changes: 2 additions & 2 deletions packages/media-console/src/components/PlayPause/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ export const styles = StyleSheet.create({
},
playContainer: {
width: '10%',
},
play: {
alignItems: 'center',
},
play: {},
rewind: {},
});
6 changes: 4 additions & 2 deletions packages/media-console/src/components/Seekbar/Seekbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ export const Seekbar = ({
<View
style={styles.track}
onLayout={(event) => setSeekerWidth(event.nativeEvent.layout.width)}
pointerEvents={'none'}>
pointerEvents={'none'}
>
<View
style={[
styles.fill,
Expand All @@ -36,7 +37,8 @@ export const Seekbar = ({
</View>
<View
style={[styles.handle, {left: seekerPosition}]}
pointerEvents={'none'}>
pointerEvents={'none'}
>
<View
style={[styles.circle, {backgroundColor: seekColor || '#FFF'}]}
pointerEvents={'none'}
Expand Down
5 changes: 3 additions & 2 deletions packages/media-console/src/components/Timer/Timer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ export const Timer = ({
}: TimerProps) => {
return (
<Control
callback={toggleTimer}
onPress={toggleTimer}
resetControlTimeout={resetControlTimeout}
style={styles.timer}
disabled={!showControls}>
disabled={!showControls}
>
<Text style={styles.timerText}>{children}</Text>
</Control>
);
Expand Down
3 changes: 2 additions & 1 deletion packages/media-console/src/components/TopControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ export const TopControls = memo(
<ImageBackground
source={require('../assets/img/top-vignette.png')}
style={[styles.column]}
imageStyle={[styles.vignette]}>
imageStyle={[styles.vignette]}
>
<SafeAreaView style={_styles.topControlGroup}>
{backControl}
<View style={_styles.pullRight}>{volumeControl}</View>
Expand Down
Loading
Loading