diff --git a/src/components/index.js b/src/components/index.js
index 459ff3f4c..55747394c 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -93,6 +93,7 @@ import { ForegroundNotification } from './foregroundNotification';
import { PostHtmlRenderer } from './postHtmlRenderer';
import { QuickProfileModal } from './organisms';
import QuickReplyModal from './quickReplyModal/quickReplyModalView';
+import VideoPlayer from './videoPlayer/videoPlayerView';
// Basic UI Elements
import {
@@ -234,4 +235,5 @@ export {
PostHtmlRenderer,
QuickProfileModal,
QuickReplyModal,
+ VideoPlayer,
};
diff --git a/src/components/postHtmlRenderer/postHtmlRenderer.tsx b/src/components/postHtmlRenderer/postHtmlRenderer.tsx
index 88437cb71..3853c94b7 100644
--- a/src/components/postHtmlRenderer/postHtmlRenderer.tsx
+++ b/src/components/postHtmlRenderer/postHtmlRenderer.tsx
@@ -1,27 +1,31 @@
-import React, { memo, } from "react";
-import RenderHTML, { CustomRendererProps, Element, TNode } from "react-native-render-html";
-import styles from "./postHtmlRendererStyles";
-import { LinkData, parseLinkData } from "./linkDataParser";
-import VideoThumb from "./videoThumb";
-import { AutoHeightImage } from "../autoHeightImage/autoHeightImage";
-import { useHtmlIframeProps,iframeModel } from '@native-html/iframe-plugin';
-import WebView from "react-native-webview";
+import React, { memo } from 'react';
+import RenderHTML, { CustomRendererProps, Element, TNode } from 'react-native-render-html';
+import styles from './postHtmlRendererStyles';
+import { LinkData, parseLinkData } from './linkDataParser';
+import VideoThumb from './videoThumb';
+import { AutoHeightImage } from '../autoHeightImage/autoHeightImage';
+import { useHtmlIframeProps, iframeModel } from '@native-html/iframe-plugin';
+import WebView from 'react-native-webview';
+import { View } from 'react-native';
+import YoutubeIframe from 'react-native-youtube-iframe';
+import { VideoPlayer } from '..';
interface PostHtmlRendererProps {
- contentWidth:number;
- body:string;
- onLoaded?:()=>void;
- setSelectedImage:(imgUrl:string)=>void;
- setSelectedLink:(url:string)=>void;
- onElementIsImage:(imgUrl:string)=>void;
- handleOnPostPress:(permlink:string, authro:string)=>void;
- handleOnUserPress:(username:string)=>void;
- handleTagPress:(tag:string, filter?:string)=>void;
- handleVideoPress:(videoUrl:string)=>void;
- handleYoutubePress:(videoId:string, startTime:number)=>void;
+ contentWidth: number;
+ body: string;
+ onLoaded?: () => void;
+ setSelectedImage: (imgUrl: string) => void;
+ setSelectedLink: (url: string) => void;
+ onElementIsImage: (imgUrl: string) => void;
+ handleOnPostPress: (permlink: string, authro: string) => void;
+ handleOnUserPress: (username: string) => void;
+ handleTagPress: (tag: string, filter?: string) => void;
+ handleVideoPress: (videoUrl: string) => void;
+ handleYoutubePress: (videoId: string, startTime: number) => void;
}
-export const PostHtmlRenderer = memo(({
+export const PostHtmlRenderer = memo(
+ ({
contentWidth,
body,
onLoaded,
@@ -33,209 +37,174 @@ export const PostHtmlRenderer = memo(({
handleTagPress,
handleVideoPress,
handleYoutubePress,
- }:PostHtmlRendererProps) => {
+ }: PostHtmlRendererProps) => {
+ //new renderer functions
+ body = body.replace(/
/g, '').replace(/<\/center>/g, '
');
- //new renderer functions
- body = body.replace(//g, '').replace(/<\/center>/g,'
');
+ console.log('Comment body:', body);
- console.log("Comment body:", body);
-
- const _handleOnLinkPress = (data:LinkData) => {
-
- if(!data){
- return;
- }
-
- const {
- type,
- href,
- author,
- permlink,
- tag,
- youtubeId,
- startTime,
- filter,
- videoHref,
- community
- } = data;
-
- try {
-
- switch (type) {
- case '_external':
- case 'markdown-external-link':
- setSelectedLink(href);
- break;
- case 'markdown-author-link':
- if (handleOnUserPress) {
- handleOnUserPress(author);
- }
- break;
- case 'markdown-post-link':
- if (handleOnPostPress) {
- handleOnPostPress(permlink, author);
- }
- break;
- case 'markdown-tag-link':
- if(handleTagPress){
- handleTagPress(tag, filter);
- }
- break;
-
- case 'markdown-video-link':
- if(handleVideoPress){
- handleVideoPress(videoHref)
- }
- break;
- case 'markdown-video-link-youtube':
- if(handleYoutubePress){
- handleYoutubePress(youtubeId, startTime)
- }
-
- break;
-
- //unused cases
- case 'markdown-witnesses-link':
- setSelectedLink(href);
- break;
-
- case 'markdown-proposal-link':
- setSelectedLink(href);
- break;
-
- case 'markdown-community-link':
- //tag press also handles community by default
- if(handleTagPress){
- handleTagPress(community, filter)
- }
- break;
-
- default:
- break;
+ const _handleOnLinkPress = (data: LinkData) => {
+ if (!data) {
+ return;
}
- } catch (error) {}
- };
-
-
- const _onElement = (element:Element) => {
- if(element.tagName === 'img' && element.attribs.src){
+
+ const {
+ type,
+ href,
+ author,
+ permlink,
+ tag,
+ youtubeId,
+ startTime,
+ filter,
+ videoHref,
+ community,
+ } = data;
+
+ try {
+ switch (type) {
+ case '_external':
+ case 'markdown-external-link':
+ setSelectedLink(href);
+ break;
+ case 'markdown-author-link':
+ if (handleOnUserPress) {
+ handleOnUserPress(author);
+ }
+ break;
+ case 'markdown-post-link':
+ if (handleOnPostPress) {
+ handleOnPostPress(permlink, author);
+ }
+ break;
+ case 'markdown-tag-link':
+ if (handleTagPress) {
+ handleTagPress(tag, filter);
+ }
+ break;
+
+ case 'markdown-video-link':
+ if (handleVideoPress) {
+ handleVideoPress(videoHref);
+ }
+ break;
+ case 'markdown-video-link-youtube':
+ if (handleYoutubePress) {
+ handleYoutubePress(youtubeId, startTime);
+ }
+
+ break;
+
+ //unused cases
+ case 'markdown-witnesses-link':
+ setSelectedLink(href);
+ break;
+
+ case 'markdown-proposal-link':
+ setSelectedLink(href);
+ break;
+
+ case 'markdown-community-link':
+ //tag press also handles community by default
+ if (handleTagPress) {
+ handleTagPress(community, filter);
+ }
+ break;
+
+ default:
+ break;
+ }
+ } catch (error) {}
+ };
+
+ const _onElement = (element: Element) => {
+ if (element.tagName === 'img' && element.attribs.src) {
const imgUrl = element.attribs.src;
- console.log("img element detected", imgUrl);
- onElementIsImage(imgUrl)
+ console.log('img element detected', imgUrl);
+ onElementIsImage(imgUrl);
}
};
-
- const _anchorRenderer = ({
- InternalRenderer,
- tnode,
- ...props
- }:CustomRendererProps) => {
-
+ const _anchorRenderer = ({ InternalRenderer, tnode, ...props }: CustomRendererProps) => {
+ const parsedTnode = parseLinkData(tnode);
const _onPress = () => {
- console.log("Link Pressed:", tnode)
+ console.log('Link Pressed:', tnode);
const data = parseLinkData(tnode);
_handleOnLinkPress(data);
};
- if (tnode.classes?.indexOf('markdown-video-link') >= 0) {
- // get video src
- let videoHref = tnode.attributes['data-embed-src'] || tnode.attributes['data-video-href'] || tnode.children[0].attributes['src'];
-
+ if (tnode.classes?.indexOf('markdown-video-link-youtube') >= 0) {
return (
- {
- console.log('load end');
- }}
- onLoadStart={() => {
- console.log('load start');
- }}
- source={{ uri: videoHref }}
- style={{ width: contentWidth, height: (contentWidth * 9) / 16 }}
- startInLoadingState={true}
- onShouldStartLoadWithRequest={() => true}
- mediaPlaybackRequiresUserAction={true}
- allowsInlineMediaPlayback={true}
+
);
}
- if(tnode.classes?.indexOf('markdown-video-link') >= 0){
- const imgElement = tnode.children.find((child)=>{
- return child.classes.indexOf('video-thumbnail') > 0 ? true:false
- })
- if(!imgElement){
- return (
-
- )
+ if (tnode.classes?.indexOf('markdown-video-link') >= 0) {
+ return (
+
+ );
+ }
+ if (tnode.classes?.indexOf('markdown-video-link') >= 0) {
+ const imgElement = tnode.children.find((child) => {
+ return child.classes.indexOf('video-thumbnail') > 0 ? true : false;
+ });
+ if (!imgElement) {
+ return ;
}
}
-
-
- return (
-
- )
- }
+
+ return ;
+ };
//this method checks if image is a child of table column
//and calculates img width accordingly,
//returns full width if img is not part of table
- const getMaxImageWidth = (tnode:TNode)=>{
-
+ const getMaxImageWidth = (tnode: TNode) => {
//return full width if not parent exist
- if(!tnode.parent || tnode.parent.tagName === 'body'){
+ if (!tnode.parent || tnode.parent.tagName === 'body') {
return contentWidth;
}
//return divided width based on number td tags
- if(tnode.parent.tagName === 'td'){
- const cols = tnode.parent.parent.children.length
- return contentWidth/cols;
+ if (tnode.parent.tagName === 'td') {
+ const cols = tnode.parent.parent.children.length;
+ return contentWidth / cols;
}
//check next parent
return getMaxImageWidth(tnode.parent);
- }
-
-
- const _imageRenderer = ({
- tnode,
- }:CustomRendererProps) => {
-
+ };
+
+ const _imageRenderer = ({ tnode }: CustomRendererProps) => {
const imgUrl = tnode.attributes.src;
const _onPress = () => {
- console.log("Image Pressed:", imgUrl)
+ console.log('Image Pressed:', imgUrl);
setSelectedImage(imgUrl);
};
-
+
const isVideoThumb = tnode.classes?.indexOf('video-thumbnail') >= 0;
const isAnchored = tnode.parent?.tagName === 'a';
-
- if(isVideoThumb){
- return ;
- }
- else {
+ if (isVideoThumb) {
+ return ;
+ } else {
const maxImgWidth = getMaxImageWidth(tnode);
return (
-
- )
+ );
}
-
- }
-
+ };
/**
* the para renderer is designd to remove margins from para
@@ -243,31 +212,18 @@ export const PostHtmlRenderer = memo(({
* a weired misalignment of bullet and content
* @returns Default Renderer
*/
- const _paraRenderer = ({
- TDefaultRenderer,
- ...props
- }:CustomRendererProps) => {
+ const _paraRenderer = ({ TDefaultRenderer, ...props }: CustomRendererProps) => {
+ props.style = props.tnode.parent.tagName === 'li' ? styles.pLi : styles.p;
- props.style = props.tnode.parent.tagName === 'li'
- ? styles.pLi
- : styles.p
+ return ;
+ };
- return (
-
- )
- }
-
// iframe renderer for rendering iframes in body
const _iframeRenderer = function IframeRenderer(props) {
const iframeProps = useHtmlIframeProps(props);
- // console.log('iframeProps : ', iframeProps);
const checkSrcRegex = /(.*?)\.(mp4|webm|ogg)$/gi;
const isVideoType = iframeProps.source.uri.match(checkSrcRegex);
- // check if source contain video source then wrap it with video tag
- // else pass the source directly to webview
const src = isVideoType
? {
html: `
@@ -300,55 +256,57 @@ export const PostHtmlRenderer = memo(({
/>
);
};
-
- return (
-
- )
- }, (next, prev)=>next.body === prev.body)
+
+ return (
+
+ );
+ },
+ (next, prev) => next.body === prev.body,
+);
diff --git a/src/components/videoPlayer/videoPlayerStyles.ts b/src/components/videoPlayer/videoPlayerStyles.ts
new file mode 100644
index 000000000..b64e4c5cf
--- /dev/null
+++ b/src/components/videoPlayer/videoPlayerStyles.ts
@@ -0,0 +1,5 @@
+import EStyleSheet from 'react-native-extended-stylesheet';
+
+export default EStyleSheet.create({
+
+});
diff --git a/src/components/videoPlayer/videoPlayerView.tsx b/src/components/videoPlayer/videoPlayerView.tsx
new file mode 100644
index 000000000..500aa5fbf
--- /dev/null
+++ b/src/components/videoPlayer/videoPlayerView.tsx
@@ -0,0 +1,98 @@
+import React, { useState } from 'react';
+import style from './videoPlayerStyles';
+import { Dimensions } from 'react-native';
+import { View, StyleSheet, ActivityIndicator } from 'react-native';
+import WebView from 'react-native-webview';
+import YoutubeIframe, { InitialPlayerParams } from 'react-native-youtube-iframe';
+
+interface VideoPlayerProps {
+ youtubeVideoId?: string;
+ videoUrl?: string;
+ startTime?: number;
+ contentWidth?: number;
+}
+
+const VideoPlayer = ({ youtubeVideoId, videoUrl, startTime, contentWidth }: VideoPlayerProps) => {
+ const PLAYER_HEIGHT = Dimensions.get('screen').width * (9 / 16);
+
+ const [shouldPlay, setShouldPlay] = useState(false);
+ const [loading, setLoading] = useState(true);
+
+ const _onReady = () => {
+ setLoading(false);
+ setShouldPlay(true);
+ console.log('ready');
+ };
+
+ const _onChangeState = (event: string) => {
+ console.log(event);
+ setShouldPlay(!(event == 'paused' || event == 'ended'));
+ };
+
+ const _onError = () => {
+ console.log('error!');
+ setLoading(false);
+ };
+
+ const initialParams: InitialPlayerParams = {
+ start: startTime,
+ };
+
+ return (
+
+ {youtubeVideoId && (
+
+
+
+ )}
+ {videoUrl && (
+
+ {
+ setLoading(false);
+ }}
+ onLoadStart={() => {
+ setLoading(true);
+ }}
+ source={{ uri: videoUrl }}
+ style={{ width: contentWidth, height: (contentWidth * 9) / 16 }}
+ startInLoadingState={true}
+ onShouldStartLoadWithRequest={() => true}
+ mediaPlaybackRequiresUserAction={true}
+ allowsInlineMediaPlayback={true}
+ />
+
+ )}
+ {loading && }
+
+ );
+};
+
+export default VideoPlayer;
+
+const styles = StyleSheet.create({
+ container: {
+ paddingVertical: 16,
+ },
+ activityIndicator: {
+ position: 'absolute',
+ alignItems: 'center',
+ justifyContent: 'center',
+ top: 0,
+ bottom: 0,
+ left: 0,
+ right: 0,
+ },
+});