* MM-31202 | MM-30866 fix: Video playback button & hide header footer on playback
* Feedback review
(cherry picked from commit 9abc89129b)
Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
This commit is contained in:
parent
20496f5a4f
commit
29a12c152a
6 changed files with 62 additions and 48 deletions
|
|
@ -129,6 +129,7 @@ const Footer = forwardRef<FooterRef, FooterProps>((props: FooterProps, ref) => {
|
|||
|
||||
useImperativeHandle(ref, () => ({
|
||||
isVisible,
|
||||
setVisible,
|
||||
toggle,
|
||||
}), [visible]);
|
||||
|
||||
|
|
|
|||
|
|
@ -128,8 +128,15 @@ export default class Gallery extends PureComponent {
|
|||
this.setState({index}, this.initHeader);
|
||||
};
|
||||
|
||||
handleTapped = () => {
|
||||
const visible = this.footer.current?.getWrappedInstance()?.toggle();
|
||||
handleTapped = (display) => {
|
||||
let visible;
|
||||
if (display === undefined) {
|
||||
visible = this.footer.current?.getWrappedInstance()?.toggle();
|
||||
} else {
|
||||
visible = display;
|
||||
this.footer.current?.getWrappedInstance()?.setVisible(display);
|
||||
}
|
||||
|
||||
const options = {
|
||||
topBar: {
|
||||
background: {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import {GalleryItemProps} from 'types/screens/gallery';
|
|||
|
||||
import VideoControls, {VideoControlsRef} from './video_controls';
|
||||
|
||||
const GalleryVideo = ({file, deviceHeight, deviceWidth, intl, isActive, onDoubleTap, theme}: GalleryItemProps) => {
|
||||
const GalleryVideo = ({file, deviceHeight, deviceWidth, intl, isActive, showHideHeaderFooter, theme}: GalleryItemProps) => {
|
||||
const statusBar = DeviceTypes.IS_IPHONE_WITH_INSETS ? 0 : 20;
|
||||
const width = deviceWidth;
|
||||
const height = deviceHeight - statusBar;
|
||||
|
|
@ -25,16 +25,6 @@ const GalleryVideo = ({file, deviceHeight, deviceWidth, intl, isActive, onDouble
|
|||
const [paused, setPaused] = useState(true);
|
||||
const videoRef = useRef<Video>(null);
|
||||
const controlsRef = useRef<VideoControlsRef>(null);
|
||||
const doubleTapRef = useRef<TapGestureHandler>(null);
|
||||
|
||||
const doubleTap = (e: TapGestureHandlerStateChangeEvent) => {
|
||||
if (e.nativeEvent.state === State.ACTIVE) {
|
||||
if (onDoubleTap) {
|
||||
onDoubleTap();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const onPlayPause = () => {
|
||||
setPaused(!paused);
|
||||
};
|
||||
|
|
@ -120,30 +110,21 @@ const GalleryVideo = ({file, deviceHeight, deviceWidth, intl, isActive, onDouble
|
|||
<TapGestureHandler
|
||||
numberOfTaps={1}
|
||||
onHandlerStateChange={singleTap}
|
||||
waitFor={doubleTapRef}
|
||||
>
|
||||
<View>
|
||||
<TapGestureHandler
|
||||
ref={doubleTapRef}
|
||||
numberOfTaps={2}
|
||||
onHandlerStateChange={doubleTap}
|
||||
>
|
||||
<View>
|
||||
<Video
|
||||
ref={videoRef}
|
||||
style={{width, height}}
|
||||
resizeMode='contain'
|
||||
source={{uri}}
|
||||
volume={1.0}
|
||||
paused={paused}
|
||||
controls={false}
|
||||
onEnd={videoEnded}
|
||||
onLoad={videoLoaded}
|
||||
onProgress={videoProgress}
|
||||
onError={videoError}
|
||||
/>
|
||||
</View>
|
||||
</TapGestureHandler>
|
||||
<Video
|
||||
ref={videoRef}
|
||||
style={{width, height}}
|
||||
resizeMode='contain'
|
||||
source={{uri}}
|
||||
volume={1.0}
|
||||
paused={paused}
|
||||
controls={false}
|
||||
onEnd={videoEnded}
|
||||
onLoad={videoLoaded}
|
||||
onProgress={videoProgress}
|
||||
onError={videoError}
|
||||
/>
|
||||
</View>
|
||||
</TapGestureHandler>
|
||||
<VideoControls
|
||||
|
|
@ -153,6 +134,7 @@ const GalleryVideo = ({file, deviceHeight, deviceWidth, intl, isActive, onDouble
|
|||
paused={paused}
|
||||
onPlayPause={onPlayPause}
|
||||
onSeek={onSeek}
|
||||
showHideHeaderFooter={showHideHeaderFooter}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -18,8 +18,12 @@ import GalleryImage from './gallery_image';
|
|||
import GalleryVideo from './gallery_video';
|
||||
|
||||
const itemTopStyle = (props: GalleryProps): number => {
|
||||
if (Platform.OS === 'android' && props.footerVisible) {
|
||||
return props.isLandscape ? -64 : -99;
|
||||
if (Platform.OS === 'android') {
|
||||
if (props.footerVisible) {
|
||||
return props.isLandscape ? -64 : -99;
|
||||
}
|
||||
|
||||
return props.isLandscape ? -6 : -41;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -161,7 +165,7 @@ const GalleryViewer = (props: GalleryProps) => {
|
|||
>
|
||||
<GalleryVideo
|
||||
isActive={currentIndex === i}
|
||||
onDoubleTap={props.onTap}
|
||||
showHideHeaderFooter={props.onTap}
|
||||
theme={props.theme}
|
||||
{...itemProps}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ interface VideoControlsProps {
|
|||
paused: boolean;
|
||||
onPlayPause(): void;
|
||||
onSeek(value: number): void;
|
||||
showHideHeaderFooter?(display: boolean): void;
|
||||
}
|
||||
|
||||
export interface VideoControlsRef {
|
||||
|
|
@ -97,6 +98,8 @@ const humanizeVideoDuration = (seconds: number) => {
|
|||
return date.toISOString().substr(begin, end);
|
||||
};
|
||||
|
||||
let animation: Animated.CompositeAnimation;
|
||||
|
||||
const VideoControls = forwardRef<VideoControlsRef, VideoControlsProps>((props: VideoControlsProps, ref) => {
|
||||
const opacity = useRef(new Animated.Value(0)).current;
|
||||
const [duration, setDuration] = useState(0);
|
||||
|
|
@ -105,12 +108,21 @@ const VideoControls = forwardRef<VideoControlsRef, VideoControlsProps>((props: V
|
|||
const styles = getStyles(props.isLandscape);
|
||||
|
||||
const fadeControls = (toValue: number, delay = 0, callback?: CallbackFunctionWithoutArguments) => {
|
||||
Animated.timing(opacity, {
|
||||
if (animation) {
|
||||
animation.stop();
|
||||
}
|
||||
animation = Animated.timing(opacity, {
|
||||
toValue,
|
||||
duration: 250,
|
||||
delay,
|
||||
useNativeDriver: true,
|
||||
}).start(callback);
|
||||
});
|
||||
|
||||
animation.start((result: Animated.EndResult) => {
|
||||
if (callback && result.finished) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -123,12 +135,18 @@ const VideoControls = forwardRef<VideoControlsRef, VideoControlsProps>((props: V
|
|||
videoProgress,
|
||||
}), []);
|
||||
|
||||
const showControls = (playing: boolean) => {
|
||||
setVisible(true);
|
||||
const display = (show: boolean) => {
|
||||
setVisible(show);
|
||||
if (props.showHideHeaderFooter) {
|
||||
props.showHideHeaderFooter(show);
|
||||
}
|
||||
};
|
||||
|
||||
const showControls = (playing: boolean) => {
|
||||
display(true);
|
||||
if (playing) {
|
||||
fadeControls(1, 0, () => {
|
||||
fadeControls(0, 1000, () => setVisible(false));
|
||||
fadeControls(0, 1000, () => display(false));
|
||||
});
|
||||
} else {
|
||||
fadeControls(1, 0);
|
||||
|
|
@ -137,9 +155,9 @@ const VideoControls = forwardRef<VideoControlsRef, VideoControlsProps>((props: V
|
|||
|
||||
const playPause = () => {
|
||||
if (props.paused) {
|
||||
fadeControls(0, 250, () => setVisible(false));
|
||||
fadeControls(0, 250, () => display(false));
|
||||
} else {
|
||||
fadeControls(1, 250, () => setVisible(true));
|
||||
fadeControls(1, 250, () => display(true));
|
||||
}
|
||||
|
||||
props.onPlayPause();
|
||||
|
|
@ -149,7 +167,7 @@ const VideoControls = forwardRef<VideoControlsRef, VideoControlsProps>((props: V
|
|||
props.onSeek(value);
|
||||
setProgress(value);
|
||||
if (!props.paused) {
|
||||
fadeControls(0, 1000, () => setVisible(false));
|
||||
fadeControls(0, 1000, () => display(false));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -159,7 +177,7 @@ const VideoControls = forwardRef<VideoControlsRef, VideoControlsProps>((props: V
|
|||
|
||||
const seekStart = () => {
|
||||
opacity.stopAnimation();
|
||||
setVisible(true);
|
||||
display(true);
|
||||
};
|
||||
|
||||
const videoDuration = (value: number) => {
|
||||
|
|
@ -195,6 +213,7 @@ const VideoControls = forwardRef<VideoControlsRef, VideoControlsProps>((props: V
|
|||
<SafeAreaView
|
||||
edges={['left', 'right']}
|
||||
mode='margin'
|
||||
pointerEvents='box-none'
|
||||
style={styles.progressColumnContainer}
|
||||
>
|
||||
<View style={[styles.controlsRow, styles.progressContainer]}>
|
||||
|
|
|
|||
3
types/screens/gallery.d.ts
vendored
3
types/screens/gallery.d.ts
vendored
|
|
@ -55,6 +55,7 @@ export interface FooterProps {
|
|||
export interface FooterRef {
|
||||
toggle(): boolean;
|
||||
isVisible(): boolean;
|
||||
setVisible(visible: boolean): void;
|
||||
}
|
||||
|
||||
export interface GalleryProps {
|
||||
|
|
@ -76,7 +77,7 @@ export interface GalleryItemProps {
|
|||
deviceWidth: number;
|
||||
intl?: typeof intlShape;
|
||||
isActive?: boolean;
|
||||
onDoubleTap?: CallbackFunctionWithoutArguments;
|
||||
showHideHeaderFooter?(display: boolean): void;
|
||||
style?: StyleProp<Animated.AnimateStyle>;
|
||||
theme?: Theme;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue