// Import necessary dependencies import React, { useState, useEffect } from 'react'; import { View, TouchableHighlight, StyleSheet, FlatList, TouchableWithoutFeedback, TouchableOpacity, Share, Dimensions, PixelRatio } from 'react-native'; import { Button, Text, ProgressBar } from 'react-native-paper'; import API from './../API.js'; import VideoPlayer from './VideoPlayer.js'; import VimeoPlayer from './VimeoPlayer.js'; import { WebView } from 'react-native-webview'; import { useSnapshot } from 'valtio'; import GlobalState from '../contexts/GlobalState.js'; import Moment from 'moment'; import { useNavigation } from '@react-navigation/native'; import { Image } from 'expo-image'; // Import Image from expo-image import * as FileSystem from 'expo-file-system'; import * as Sharing from 'expo-sharing'; import i18n from "../i18nMessages.js"; // Extract Vimeo video ID from content string const videoIdF = (content) => { let vimeoTag = content.match(/@vimeo:[0-9]+/); if (!vimeoTag) return []; let tag = vimeoTag; tag = tag[0].substring(1); return tag.split(':'); }; // Extract YouTube video ID from content string const youtubeIdF = (content) => { // Accept classic 11-char IDs and common ID-safe chars. let youtubeTag = content.match(/@youtube:([A-Za-z0-9_-]+)/); if (!youtubeTag) return ''; return youtubeTag[1]; }; // Extract HLS URL from content string const hlsIdF = (content) => { let hslTag = content.match(/@hls:.+\w/); if (!hslTag) return ''; let tag = hslTag; tag = tag[0].substring(5); return tag; }; // Extract image tags from content string const imagesTagF = (content, width = 1000, height = 1000) => { let images = content.match(/@image:[0-z|/|.|]+/g); if (!images) return []; let Tags = []; images.forEach(i => { let tag = i.substring(1); let parts = [tag.substring(1, tag.indexOf(":")), tag.substring(tag.indexOf(":") + 1)]; if (parts[1].substring(0, 4) != "http") parts[1] = `https://social.emmint.com/${parts[1]}?width=${width}&height=${height}`; Tags.push(parts); }); return Tags; }; // Extract iframe source from content string const iframeTagF = (content) => { let iframeMatch = content.match(/@iframe:.+\w/g); if (!iframeMatch) return []; let tag = iframeMatch[0].substring(1); let parts = [tag.substring(1, tag.indexOf(":")), tag.substring(tag.indexOf(":") + 1)]; return parts; }; // Media Component let Media = (props) => { const gState = useSnapshot(GlobalState); const viewer = gState.me; // Extracting tags from content const screenWidth = Dimensions.get('window').width; const requestedImageWidth = props.imageWidth || Math.max(1200, Math.ceil(screenWidth * PixelRatio.get() * 1.2)); const requestedImageHeight = props.imageHeight || requestedImageWidth; const imagesTag = imagesTagF(props.content, requestedImageWidth, requestedImageHeight); const imagesTagLimited = imagesTag.slice(0, 10); const isImagesCapped = imagesTag.length > imagesTagLimited.length; const imageStyle = imagesTag.length === 1 ? styles.image : styles.multipleImage; const videosId = videoIdF(props.content); const hlsUrl = hlsIdF(props.content); const iframeSrc = iframeTagF(props.content) || []; const youtubeId = youtubeIdF(props.content); const [videosFiles, setVideosFiles] = useState([]); const [poster, setPoster] = useState(''); const [loaded, setLoaded] = useState(false); const navigation = useNavigation(); let interactive = props.interactive || true; // Fetch video data from API useEffect(() => { let subscribed = true; let getData = async () => { if (!videosId[1]) return; let videoObj = await API.getVideo(videosId[1]); if (videoObj && videoObj.files && subscribed) { setVideosFiles(videoObj.files); setPoster(videoObj.pictures.sizes[4].link); } }; getData(); return () => { subscribed = false; }; }, [props.content]); // Render video component const renderVideo = () => { if (videosFiles.length && !props.skiptVideo) { return loaded ? ( ) : ( setLoaded(true)}> ); } if (videosId.length) { return ; } return null; }; // Render HLS video component const renderHlsVideo = () => { if (hlsUrl && !props.skiptVideo) { return loaded ? ( ) : ( { GlobalState.currentMedia = hlsUrl; GlobalState.mediaPost = props.post; }}> {poster ? ( ) : (