video react native

 avatar
odi
plain_text
2 years ago
3.9 kB
5
Indexable
import { ResizeMode, Video } from 'expo-av';
import { UserServiceClient } from 'fitbeat.api-clients';
import { buildWeightAndColor } from 'fitbeat.gym-core';
import { EquipmentWeight } from 'fitbeat.models';
import React, { useEffect, useState } from 'react';
import { ActivityIndicator, StyleSheet, Text, View } from 'react-native';
import { getApiConfig } from '../config';
import theme from '../theme';
import { AuthTokenBuilder } from '../utils';
import { Logger } from '../utils/Logger';
import { defaultScale, scaleText } from '../utils/scaling';

interface IProps {
  videoName: string;
  suggestedStartingWeight: EquipmentWeight;
  navigation: any;
}

export const ExplainExercise: React.FC<IProps> = ({
  navigation,
  videoName,
  suggestedStartingWeight,
}) => {
  const video = React.useRef(null);
  const [isVideoLoading, setIsVideoLoading] = useState(false);
  const [videoUrl, setVideoUrl] = useState(null);

  useEffect(() => {
    const authenticatedUserServiceClient = new UserServiceClient(
      getApiConfig(),
      fetch,
      Logger.debug,
      new AuthTokenBuilder(),
    );
    const getVideoRespose = async () => {
      const videoRespone = await authenticatedUserServiceClient.getVideoUrlFor(
        videoName,
      );
      setVideoUrl(videoRespone.videoUrl);
    };
    getVideoRespose();
  }, []);

  useEffect(() => {
    const willBlurSubscription = navigation.addListener('willBlur', () => {
      if (video.current) {
        video.current.pauseAsync();
      }
    });

    return () => {
      willBlurSubscription.remove();
    };
  }, [navigation]);

  const showLoadingIndicator = !videoUrl || isVideoLoading;
  const showVideo = !!videoUrl;
  const startingWeightAndColor = buildWeightAndColor(suggestedStartingWeight);
  return (
    <View style={styles.container}>
      <View style={styles.videoContainer}>
        <View style={styles.loadingContainer}>
          {showLoadingIndicator && (
            <ActivityIndicator
              size='small'
              color={theme.ORANGE}
              animating={true}
            />
          )}
        </View>
        {showVideo && (
          <Video
            ref={video}
            style={styles.video}
            source={{
              uri: videoUrl,
            }}
            useNativeControls
            resizeMode={ResizeMode.CONTAIN}
            onLoad={() => {
              setIsVideoLoading(false);
            }}
            onLoadStart={() => {
              setIsVideoLoading(true);
            }}
          />
        )}
      </View>
      <View style={styles.suggestedWeightContainer}>
        <>
          <Text style={styles.suggestionText}>Starting suggestion</Text>
          <View
            style={[
              styles.suggestedStartingWeight,
              { backgroundColor: startingWeightAndColor.color },
            ]}
          >
            <Text style={styles.weightText}>{suggestedStartingWeight}</Text>
          </View>
        </>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  videoContainer: {
    width: '100%',
    height: defaultScale(320),
    position: 'relative',
    marginTop: defaultScale(15),
  },
  suggestedWeightContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  suggestedStartingWeight: {
    width: defaultScale(220),
    height: defaultScale(45),
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: 'red',
  },
  suggestionText: {
    ...theme.textStyle.heading2,
    marginBottom: defaultScale(10),
  },
  weightText: {
    ...theme.textStyle.display1Bold,
    color: theme.WHITE,
    fontWeight: '800',
    fontSize: scaleText(25),
  },
  video: {
    width: '100%',
    height: '100%',
  },
  loadingContainer: {
    ...StyleSheet.absoluteFillObject,
    justifyContent: 'center',
    alignItems: 'center',
  },
});
Editor is loading...