Merge pull request #2279 from ecency/nt/glitch-fix

Scroll Glitch
This commit is contained in:
Feruz M 2022-04-29 06:30:19 +03:00 committed by GitHub
commit 51cd21b748
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 90 additions and 67 deletions

View File

@ -2,21 +2,24 @@ import React, { useEffect, useState } from "react";
import { Image } from "react-native"; import { Image } from "react-native";
import EStyleSheet from "react-native-extended-stylesheet"; import EStyleSheet from "react-native-extended-stylesheet";
import FastImage from "react-native-fast-image"; import FastImage from "react-native-fast-image";
import { TouchableWithoutFeedback } from "react-native-gesture-handler"; import { TouchableOpacity } from "react-native-gesture-handler";
interface AutoHeightImageProps {
contentWidth:number,
imgUrl:string,
isAnchored:boolean,
activeOpacity?:number,
onPress:()=>void,
}
export const AutoHeightImage = ({ export const AutoHeightImage = ({
contentWidth, contentWidth,
imgUrl, imgUrl,
isAnchored, isAnchored,
activeOpacity,
onPress onPress
}:{ }:AutoHeightImageProps) => {
contentWidth:number,
imgUrl:string,
isAnchored:boolean,
onPress:()=>void,
}) => {
const [imgWidth, setImgWidth] = useState(contentWidth); const [imgWidth, setImgWidth] = useState(contentWidth);
@ -47,14 +50,14 @@ import { TouchableWithoutFeedback } from "react-native-gesture-handler";
} }
return ( return (
<TouchableWithoutFeedback onPress={onPress} disabled={isAnchored}> <TouchableOpacity onPress={onPress} disabled={isAnchored} activeOpacity={activeOpacity || 1}>
<FastImage <FastImage
style={imgStyle} style={imgStyle}
source={{uri:imgUrl}} source={{uri:imgUrl}}
resizeMode={FastImage.resizeMode.contain} resizeMode={FastImage.resizeMode.contain}
onLoad={_onLoad} onLoad={_onLoad}
/> />
</TouchableWithoutFeedback> </TouchableOpacity>
) )
} }

View File

@ -7,7 +7,7 @@ import { AutoHeightImage } from '../autoHeightImage/autoHeightImage';
import { useHtmlIframeProps, iframeModel } from '@native-html/iframe-plugin'; import { useHtmlIframeProps, iframeModel } from '@native-html/iframe-plugin';
import WebView from 'react-native-webview'; import WebView from 'react-native-webview';
import { VideoPlayer } from '..'; import { VideoPlayer } from '..';
import {useHtmlTableProps } from '@native-html/table-plugin'; import { useHtmlTableProps } from '@native-html/table-plugin';
import { ScrollView } from 'react-native-gesture-handler'; import { ScrollView } from 'react-native-gesture-handler';
interface PostHtmlRendererProps { interface PostHtmlRendererProps {
@ -118,52 +118,7 @@ export const PostHtmlRenderer = memo(
default: default:
break; break;
} }
} catch (error) {} } 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);
}
};
const _anchorRenderer = ({ InternalRenderer, tnode, ...props }: CustomRendererProps<TNode>) => {
const parsedTnode = parseLinkData(tnode);
const _onPress = () => {
console.log('Link Pressed:', tnode);
const data = parseLinkData(tnode);
_handleOnLinkPress(data);
};
//process video link
if(tnode.classes?.indexOf('markdown-video-link') >= 0){
if(isComment){
const imgElement = tnode.children.find((child) => {
return child.classes.indexOf('video-thumbnail') > 0 ? true : false;
});
if (!imgElement) {
return <VideoThumb contentWidth={contentWidth} onPress={_onPress} />;
}
} else {
return (
<VideoPlayer
mode={parsedTnode.youtubeId ? 'youtube' : 'uri'}
contentWidth={contentWidth}
uri={parsedTnode.videoHref}
youtubeVideoId={parsedTnode.youtubeId}
startTime={parsedTnode.startTime}
disableAutoplay={true}
/>
);
}
}
return <InternalRenderer tnode={tnode} onPress={_onPress} {...props} />;
}; };
@ -186,6 +141,70 @@ export const PostHtmlRenderer = memo(
return getMaxImageWidth(tnode.parent); return getMaxImageWidth(tnode.parent);
}; };
const _onElement = (element: Element) => {
if (element.tagName === 'img' && element.attribs.src) {
const imgUrl = element.attribs.src;
console.log('img element detected', imgUrl);
onElementIsImage(imgUrl);
}
};
const _anchorRenderer = ({ InternalRenderer, tnode, ...props }: CustomRendererProps<TNode>) => {
const parsedTnode = parseLinkData(tnode);
const _onPress = () => {
console.log('Link Pressed:', tnode);
const data = parseLinkData(tnode);
_handleOnLinkPress(data);
};
//process video link
if (tnode.classes?.indexOf('markdown-video-link') >= 0) {
if (isComment) {
const imgElement = tnode.children.find((child) => {
return child.classes.indexOf('video-thumbnail') > 0 ? true : false;
});
if (!imgElement) {
return <VideoThumb contentWidth={contentWidth} onPress={_onPress} />;
}
} else {
return (
<VideoPlayer
mode={parsedTnode.youtubeId ? 'youtube' : 'uri'}
contentWidth={contentWidth}
uri={parsedTnode.videoHref}
youtubeVideoId={parsedTnode.youtubeId}
startTime={parsedTnode.startTime}
disableAutoplay={true}
/>
);
}
}
if (tnode.children.length === 1 && tnode.children[0].tagName === 'img') {
const maxImgWidth = getMaxImageWidth(tnode);
return <AutoHeightImage
contentWidth={maxImgWidth}
imgUrl={tnode.children[0].attributes.src}
isAnchored={false}
activeOpacity={0.8}
onPress={_onPress}
/>
}
return <InternalRenderer tnode={tnode} onPress={_onPress} {...props} />;
};
const _imageRenderer = ({ tnode }: CustomRendererProps<TNode>) => { const _imageRenderer = ({ tnode }: CustomRendererProps<TNode>) => {
const imgUrl = tnode.attributes.src; const imgUrl = tnode.attributes.src;
const _onPress = () => { const _onPress = () => {
@ -225,25 +244,26 @@ export const PostHtmlRenderer = memo(
//based on number of columns a table have, sets scroll enabled or disable, also adjust table full width //based on number of columns a table have, sets scroll enabled or disable, also adjust table full width
const _tableRenderer = ({TDefaultRenderer, ...props}:CustomRendererProps<TNode>) => { const _tableRenderer = ({ TDefaultRenderer, ...props }: CustomRendererProps<TNode>) => {
const tableProps = useHtmlTableProps(props); const tableProps = useHtmlTableProps(props);
const isScrollable = tableProps.numOfColumns > 3; const isScrollable = tableProps.numOfColumns > 3;
const _tableWidth = isScrollable ? tableProps.numOfColumns * _minTableColWidth: contentWidth; const _tableWidth = isScrollable ? tableProps.numOfColumns * _minTableColWidth : contentWidth;
props.style = {width:_tableWidth}; props.style = { width: _tableWidth };
return ( return (
<ScrollView horizontal={true} scrollEnabled={isScrollable}> <ScrollView horizontal={true} scrollEnabled={isScrollable}>
<TDefaultRenderer {...props} /> <TDefaultRenderer {...props} />
</ScrollView> </ScrollView>
)} )
}
// iframe renderer for rendering iframes in body // iframe renderer for rendering iframes in body
const _iframeRenderer = function IframeRenderer(props) { const _iframeRenderer = function IframeRenderer(props) {
const iframeProps = useHtmlIframeProps(props); const iframeProps = useHtmlIframeProps(props);
if(isComment){ if (isComment) {
const _onPress = () => { const _onPress = () => {
console.log('iframe thumb Pressed:', iframeProps); console.log('iframe thumb Pressed:', iframeProps);
if (handleVideoPress) { if (handleVideoPress) {
@ -253,7 +273,7 @@ export const PostHtmlRenderer = memo(
return ( return (
<VideoThumb contentWidth={contentWidth} onPress={_onPress} /> <VideoThumb contentWidth={contentWidth} onPress={_onPress} />
) )
}else{ } else {
return ( return (
<VideoPlayer <VideoPlayer
mode='uri' mode='uri'
@ -281,9 +301,9 @@ export const PostHtmlRenderer = memo(
img: styles.img, img: styles.img,
table: styles.table, table: styles.table,
tr: { ...styles.tr, width: contentWidth }, //center tag causes tr to have 0 width if not exclusivly set, contentWidth help avoid that tr: { ...styles.tr, width: contentWidth }, //center tag causes tr to have 0 width if not exclusivly set, contentWidth help avoid that
th: { ...styles.th, minWidth: _minTableColWidth}, th: { ...styles.th, minWidth: _minTableColWidth },
td: { ...styles.td, minWidth: _minTableColWidth}, td: { ...styles.td, minWidth: _minTableColWidth },
div: { ...styles.div, maxWidth:contentWidth }, //makes sure width covers the available horizontal space for view and not exceed the contentWidth if parent bound id not defined div: { ...styles.div, maxWidth: contentWidth }, //makes sure width covers the available horizontal space for view and not exceed the contentWidth if parent bound id not defined
blockquote: styles.blockquote, blockquote: styles.blockquote,
code: styles.code, code: styles.code,
li: styles.li, li: styles.li,