[Gekidou] gallery footer and video (#6512)

This commit is contained in:
Elias Nahum 2022-07-27 09:25:01 -04:00 committed by GitHub
parent b5dc0b02a7
commit 4e70961303
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 10 deletions

View file

@ -34,6 +34,7 @@ function Typing({
const typingHeight = useSharedValue(0);
const typing = useRef<Array<{id: string; now: number; username: string}>>([]);
const timeoutToDisappear = useRef<NodeJS.Timeout>();
const mounted = useRef(false);
const [refresh, setRefresh] = useState(0);
const theme = useTheme();
@ -63,7 +64,9 @@ function Typing({
clearTimeout(timeoutToDisappear.current);
timeoutToDisappear.current = undefined;
}
setRefresh(Date.now());
if (mounted.current) {
setRefresh(Date.now());
}
}, [channelId, rootId]);
const onUserStopTyping = useCallback((msg: any) => {
@ -85,14 +88,23 @@ function Typing({
if (typing.current.length === 0) {
timeoutToDisappear.current = setTimeout(() => {
setRefresh(Date.now());
if (mounted.current) {
setRefresh(Date.now());
}
timeoutToDisappear.current = undefined;
}, 500);
} else {
} else if (mounted.current) {
setRefresh(Date.now());
}
}, []);
useEffect(() => {
mounted.current = true;
return () => {
mounted.current = false;
};
}, []);
useEffect(() => {
const listener = DeviceEventEmitter.addListener(Events.USER_TYPING, onUserStartTyping);
return () => {

View file

@ -6,6 +6,7 @@ import React, {useEffect, useRef, useState} from 'react';
import {useIntl} from 'react-intl';
import {StyleSheet} from 'react-native';
import {useAnimatedStyle, withTiming} from 'react-native-reanimated';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import {fetchPublicLink} from '@actions/remote/file';
import Toast from '@components/toast';
@ -29,13 +30,14 @@ const styles = StyleSheet.create({
const CopyPublicLink = ({item, setAction}: Props) => {
const {formatMessage} = useIntl();
const serverUrl = useServerUrl();
const insets = useSafeAreaInsets();
const [showToast, setShowToast] = useState<boolean|undefined>();
const [error, setError] = useState('');
const mounted = useRef(false);
const animatedStyle = useAnimatedStyle(() => ({
position: 'absolute',
bottom: GALLERY_FOOTER_HEIGHT + 8,
bottom: GALLERY_FOOTER_HEIGHT + 8 + insets.bottom,
opacity: withTiming(showToast ? 1 : 0, {duration: 300}),
}));

View file

@ -10,6 +10,7 @@ import FileViewer from 'react-native-file-viewer';
import FileSystem from 'react-native-fs';
import {TouchableOpacity} from 'react-native-gesture-handler';
import {useAnimatedStyle, withTiming} from 'react-native-reanimated';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import Share from 'react-native-share';
import {downloadFile} from '@actions/remote/file';
@ -66,6 +67,7 @@ const styles = StyleSheet.create({
const DownloadWithAction = ({action, item, onDownloadSuccess, setAction}: Props) => {
const intl = useIntl();
const serverUrl = useServerUrl();
const insets = useSafeAreaInsets();
const [showToast, setShowToast] = useState<boolean|undefined>();
const [error, setError] = useState('');
const [saved, setSaved] = useState(false);
@ -110,7 +112,7 @@ const DownloadWithAction = ({action, item, onDownloadSuccess, setAction}: Props)
const animatedStyle = useAnimatedStyle(() => ({
position: 'absolute',
bottom: GALLERY_FOOTER_HEIGHT + 8,
bottom: GALLERY_FOOTER_HEIGHT + 8 + insets.bottom,
opacity: withTiming(showToast ? 1 : 0, {duration: 300}),
}));

View file

@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useCallback, useEffect, useMemo, useState} from 'react';
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
import {useIntl} from 'react-intl';
import {Alert, DeviceEventEmitter, Platform, StyleSheet, useWindowDimensions} from 'react-native';
import Animated, {Easing, useAnimatedRef, useAnimatedStyle, useSharedValue, withTiming, WithTimingConfig} from 'react-native-reanimated';
@ -57,6 +57,7 @@ const VideoRenderer = ({height, index, initialIndex, item, isPageActive, onShoul
const {formatMessage} = useIntl();
const serverUrl = useServerUrl();
const videoRef = useAnimatedRef<Video>();
const showControls = useRef(!(initialIndex === index));
const [paused, setPaused] = useState(!(initialIndex === index));
const [videoReady, setVideoReady] = useState(false);
const [videoUri, setVideoUri] = useState(item.uri);
@ -75,6 +76,7 @@ const VideoRenderer = ({height, index, initialIndex, item, isPageActive, onShoul
const onEnd = useCallback(() => {
setFullscreen(false);
onShouldHideControls(true);
showControls.current = true;
setPaused(true);
videoRef.current?.dismissFullscreenPlayer();
}, [onShouldHideControls]);
@ -96,12 +98,14 @@ const VideoRenderer = ({height, index, initialIndex, item, isPageActive, onShoul
const onFullscreenPlayerWillDismiss = useCallback(() => {
setFullscreen(false);
onShouldHideControls(!paused);
showControls.current = !paused;
onShouldHideControls(showControls.current);
}, [paused, onShouldHideControls]);
const onFullscreenPlayerWillPresent = useCallback(() => {
setFullscreen(true);
onShouldHideControls(true);
showControls.current = true;
}, [onShouldHideControls]);
const onPlay = useCallback(() => {
@ -111,6 +115,7 @@ const VideoRenderer = ({height, index, initialIndex, item, isPageActive, onShoul
const onPlaybackRateChange = useCallback(({playbackRate}: OnPlaybackRateData) => {
if (isPageActive.value) {
const isPlaying = Boolean(playbackRate);
showControls.current = isPlaying;
onShouldHideControls(isPlaying);
setPaused(!isPlaying);
}
@ -120,6 +125,11 @@ const VideoRenderer = ({height, index, initialIndex, item, isPageActive, onShoul
setVideoReady(true);
}, []);
const handleTouchStart = useCallback(() => {
showControls.current = !showControls.current;
onShouldHideControls(showControls.current);
}, [onShouldHideControls]);
const setGalleryAction = useCallback((action: GalleryAction) => {
DeviceEventEmitter.emit(Events.GALLERY_ACTIONS, action);
if (action === 'none') {
@ -130,16 +140,20 @@ const VideoRenderer = ({height, index, initialIndex, item, isPageActive, onShoul
const animatedStyle = useAnimatedStyle(() => {
let w = width;
let h = height - (VIDEO_INSET + GALLERY_FOOTER_HEIGHT + bottom);
if (fullscreen.value) {
w = dimensions.width;
h = dimensions.height;
} else if (dimensions.width > dimensions.height) {
w = h;
h = width;
}
return {
width: withTiming(w, timingConfig),
height: withTiming(h, timingConfig),
};
}, [dimensions.height]);
}, [dimensions]);
useEffect(() => {
if (initialIndex === index && videoReady) {
@ -157,7 +171,10 @@ const VideoRenderer = ({height, index, initialIndex, item, isPageActive, onShoul
}, [isPageActive.value, paused]);
return (
<>
<Animated.View
onTouchStart={handleTouchStart}
style={styles.video}
>
<AnimatedVideo
ref={videoRef}
source={source}
@ -191,7 +208,7 @@ const VideoRenderer = ({height, index, initialIndex, item, isPageActive, onShoul
item={item}
/>
}
</>
</Animated.View>
);
};