/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);
};
+
+ //process video link
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){
+ if(isComment){
+ const imgElement = tnode.children.find((child) => {
+ return child.classes.indexOf('video-thumbnail') > 0 ? true : false;
+ });
+ if (!imgElement) {
+ return ;
+ }
+ } else {
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
@@ -218,58 +212,90 @@ 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 (
-
- )
- }
-
-
- return (
-
- )
- }, (next, prev)=>next.body === prev.body)
+
+ // iframe renderer for rendering iframes in body
+ const _iframeRenderer = function IframeRenderer(props) {
+ const iframeProps = useHtmlIframeProps(props);
+ const checkSrcRegex = /(.*?)\.(mp4|webm|ogg)$/gi;
+ const isVideoFormat = iframeProps.source.uri.match(checkSrcRegex);
+
+ //this hack help avoid autoplaying fullscreened iframe videos;
+ const src = isVideoFormat ?
+ {
+ html: `
+ `,
+ }:{
+ uri: iframeProps.source.uri,
+ };
+
+ return (
+
+ );
+ };
+
+ return (
+
+ );
+ },
+ (next, prev) => next.body === prev.body,
+);
diff --git a/src/components/postView/view/postDisplayView.js b/src/components/postView/view/postDisplayView.js
index e75028763..d2643216f 100644
--- a/src/components/postView/view/postDisplayView.js
+++ b/src/components/postView/view/postDisplayView.js
@@ -2,7 +2,6 @@ import React, { useCallback, useEffect, useRef, useState, Fragment } from 'react
import { View, Text, ScrollView, Dimensions, SafeAreaView, RefreshControl } from 'react-native';
import { injectIntl } from 'react-intl';
import get from 'lodash/get';
-import ActionSheet from 'react-native-actionsheet';
// Providers
import { userActivity } from '../../../providers/ecency/ePoint';
@@ -20,6 +19,7 @@ import { ParentPost } from '../../parentPost';
// Styles
import styles from './postDisplayStyles';
+import { OptionsModal } from '../../atoms';
const HEIGHT = Dimensions.get('window').width;
@@ -251,7 +251,7 @@ const PostDisplayView = ({
)}
{post && _getTabBar(true)}
-
- item.id} renderItem={_renderItem} />
{`v${appVersion}, ${buildVersion}${storageT}`}
- {
+
+ const PLAYER_HEIGHT = contentWidth * (9 / 16);
+
+ const [shouldPlay, setShouldPlay] = useState(false);
+ const [loading, setLoading] = useState(true);
+
+ const _onReady = () => {
+ setLoading(false);
+ setShouldPlay(disableAutoplay ? false : 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 (
+
+ {mode === 'youtube' && youtubeVideoId && (
+
+
+
+ )}
+ {((mode === 'source' && source) || (mode === 'url' && videoUrl)) && (
+
+ {
+ setLoading(false);
+ }}
+ onLoadStart={() => {
+ setLoading(true);
+ }}
+ source={source || { uri: videoUrl }}
+ style={{ width: contentWidth, height: PLAYER_HEIGHT}}
+ 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,
+ },
+});
diff --git a/src/screens/profileEdit/screen/profileEditScreen.js b/src/screens/profileEdit/screen/profileEditScreen.js
index fa71e0702..5b5df2897 100644
--- a/src/screens/profileEdit/screen/profileEditScreen.js
+++ b/src/screens/profileEdit/screen/profileEditScreen.js
@@ -2,11 +2,11 @@ import React, { PureComponent, Fragment } from 'react';
import { StatusBar } from 'react-native';
import { injectIntl } from 'react-intl';
import get from 'lodash/get';
-import ActionSheet from 'react-native-actionsheet';
import { ProfileEditContainer } from '../../../containers';
import { AvatarHeader, ProfileEditForm } from '../../../components';
+import { OptionsModal } from '../../../components/atoms';
class ProfileEditScreen extends PureComponent {
/* Props
@@ -81,7 +81,7 @@ class ProfileEditScreen extends PureComponent {
handleOnSubmit={handleOnSubmit}
/>
-
-
- (index === 0 ? this._handleTransferAction() : null)}
/>
-
-
- (this.ActionSheet = o)}
options={[
intl.formatMessage({ id: 'alert.confirm' }),
diff --git a/src/utils/editor.ts b/src/utils/editor.ts
index c2c8df62e..ffabb7aa0 100644
--- a/src/utils/editor.ts
+++ b/src/utils/editor.ts
@@ -44,6 +44,28 @@ export const generatePermlink = (title, random = false) => {
return perm;
};
+export const extractWordAtIndex = (text:string, index:number) => {
+ const END_REGEX = /[\s,]/
+ let word = '';
+ for(let i = index; i >= 0 && (!END_REGEX.test(text[i]) || i === index); i--){
+ if(text[i]){
+ word += text[i];
+ }
+ }
+ word = word.split('').reverse().join('');
+
+ if(!END_REGEX.test(text[index])){
+ for(let i = index + 1; i < text.length && !END_REGEX.test(text[i]); i++){
+ if(text[i]){
+ word += text[i];
+ }
+ }
+ }
+
+ return word;
+
+}
+
export const generateReplyPermlink = (toAuthor) => {
if (!toAuthor) {
return '';
diff --git a/yarn.lock b/yarn.lock
index 1ea70a4fb..c1a4ef4b8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1118,6 +1118,11 @@
resolved "https://registry.yarnpkg.com/@formatjs/intl-utils/-/intl-utils-2.3.0.tgz#2dc8c57044de0340eb53a7ba602e59abf80dc799"
integrity sha512-KWk80UPIzPmUg+P0rKh6TqspRw0G6eux1PuJr+zz47ftMaZ9QDwbGzHZbtzWkl5hgayM/qrKRutllRC7D/vVXQ==
+"@formidable-webview/webshell@^2.6.0":
+ version "2.6.0"
+ resolved "https://registry.yarnpkg.com/@formidable-webview/webshell/-/webshell-2.6.0.tgz#64704c0b513206e71b23118b3c9d096f0d545005"
+ integrity sha512-FwQQDajg1xs7W3CUiUNJMvdjgLjKLDGzs0XPzoVg0Dunhold1Jg7w5pihUdvVugFlNtkSpXMA+du9QDHE8lmpg==
+
"@hapi/address@2.x.x":
version "2.1.4"
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5"
@@ -1412,6 +1417,21 @@
css-to-react-native "^3.0.0"
csstype "^3.0.8"
+"@native-html/iframe-plugin@^2.6.1":
+ version "2.6.1"
+ resolved "https://registry.yarnpkg.com/@native-html/iframe-plugin/-/iframe-plugin-2.6.1.tgz#5b9c36d9d500f82f0bcf654bc005922df4211158"
+ integrity sha512-PM2vFNT44n/UkCm9+OUn+cNSKgiMjaw7c7/2JnnztHDLVMtPIf52K/86miWNpQpxFoy1ouoLVOvfjFRhoPXjag==
+ dependencies:
+ "@formidable-webview/webshell" "^2.6.0"
+ "@native-html/plugins-core" "1.3.0"
+ "@types/prop-types" "^15.7.4"
+ prop-types "^15.7.2"
+
+"@native-html/plugins-core@1.3.0":
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/@native-html/plugins-core/-/plugins-core-1.3.0.tgz#f1f24622097551930d9dab0214c4929d00f7446e"
+ integrity sha512-vce35gqGJKa2oPDZVa2sKjucFFVK+3g8quLayeXiJtj5LzuS8TWGrBFTS5O4ToUtE02AJkCDOLwAguCzK2HWdQ==
+
"@native-html/transient-render-engine@^9.2.2":
version "9.2.2"
resolved "https://registry.yarnpkg.com/@native-html/transient-render-engine/-/transient-render-engine-9.2.2.tgz#00691518926ea47709185c3a25a786472c99a1f0"
@@ -1784,6 +1804,11 @@
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7"
integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==
+"@types/prop-types@^15.7.4":
+ version "15.7.4"
+ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11"
+ integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==
+
"@types/ramda@^0.27.40":
version "0.27.44"
resolved "https://registry.yarnpkg.com/@types/ramda/-/ramda-0.27.44.tgz#ba2283d67fcff366f7e68bd5124a0466e467967f"
@@ -8599,10 +8624,10 @@ react-native-matomo-sdk@feruzm/react-native-matomo-sdk:
version "0.4.1"
resolved "https://codeload.github.com/feruzm/react-native-matomo-sdk/tar.gz/392b1cfca771b28005821ef909ffb9a2082156d9"
-react-native-modal-dropdown@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/react-native-modal-dropdown/-/react-native-modal-dropdown-1.0.1.tgz#24a9396dcb5dadf92feea1deae1089bcef054b20"
- integrity sha512-7QAuKvdsIMvz5N2FnRGrZKb+JR3bYFFelONdmfwp1UW3acOyrhF32H06aMD09x2PdBz3VaR5+3iApt9FYClktQ==
+react-native-modal-dropdown@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/react-native-modal-dropdown/-/react-native-modal-dropdown-1.0.2.tgz#3e1efae5a5eacc42f44ac96468ea2f1b5bb0d759"
+ integrity sha512-X13RbwoQdaOb9Ffi7fjRVwh9OXauXIJhum0uXGzYZLMyoCQ5yt5cxf27P/YZbdh80Fb7bdPx6vTA4PTpUK2WDQ==
dependencies:
prop-types "^15.6.0"