[Gekidou] gallery footer and video (#6512)
This commit is contained in:
parent
b5dc0b02a7
commit
4e70961303
4 changed files with 43 additions and 10 deletions
|
|
@ -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 () => {
|
||||
|
|
|
|||
|
|
@ -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}),
|
||||
}));
|
||||
|
||||
|
|
|
|||
|
|
@ -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}),
|
||||
}));
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue