From c83f9025e13337862c7f38a27d80e320fd5c8e6a Mon Sep 17 00:00:00 2001
From: Sadaqat Ali
Date: Fri, 21 Jan 2022 10:45:15 +0500
Subject: [PATCH 01/23] added iframe support
---
ios/Podfile.lock | 2 +-
package.json | 1 +
.../postHtmlRenderer/postHtmlRenderer.tsx | 59 +++++++++++++++++--
yarn.lock | 25 ++++++++
4 files changed, 81 insertions(+), 6 deletions(-)
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index a160089bc..c052bc551 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -772,4 +772,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 9c48318ea254e2c78005a7a0c2d8bfc14ddd783d
-COCOAPODS: 1.10.1
+COCOAPODS: 1.11.2
diff --git a/package.json b/package.json
index 2595cf0f5..75b70516b 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
"@esteemapp/react-native-multi-slider": "^1.1.0",
"@esteemapp/react-native-slider": "^0.12.0",
"@hiveio/dhive": "^1.0.1",
+ "@native-html/iframe-plugin": "^2.6.1",
"@react-native-community/async-storage": "^1.11.0",
"@react-native-community/cameraroll": "^1.3.0",
"@react-native-community/cli-platform-ios": "^4.10.1",
diff --git a/src/components/postHtmlRenderer/postHtmlRenderer.tsx b/src/components/postHtmlRenderer/postHtmlRenderer.tsx
index 1f0bd0e41..b51853058 100644
--- a/src/components/postHtmlRenderer/postHtmlRenderer.tsx
+++ b/src/components/postHtmlRenderer/postHtmlRenderer.tsx
@@ -1,10 +1,11 @@
-import React, { memo } from "react";
+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 IframeRenderer, { iframeModel } from '@native-html/iframe-plugin';
+import WebView from "react-native-webview";
interface PostHtmlRendererProps {
contentWidth:number;
@@ -37,6 +38,14 @@ export const PostHtmlRenderer = memo(({
//new renderer functions
body = body.replace(//g, '').replace(/<\/center>/g,'
');
+// body = `
+//
+//
+//
+//
Demo Text
+//
+//
+//
`
console.log("Comment body:", body);
@@ -137,7 +146,30 @@ export const PostHtmlRenderer = memo(({
const data = parseLinkData(tnode);
_handleOnLinkPress(data);
};
-
+ console.log("parseLinkData(tnode) : ", parseLinkData(tnode));
+
+ if (tnode.classes?.indexOf('markdown-video-link') >= 0) {
+ return (
+ {
+ console.log('load end');
+ }}
+ onLoadStart={() => {
+ console.log('load start');
+ }}
+ source={{ uri: parseLinkData(tnode).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
@@ -156,7 +188,7 @@ export const PostHtmlRenderer = memo(({
onPress={_onPress}
{...props}
/>
- );
+ )
}
//this method checks if image is a child of table column
@@ -264,12 +296,29 @@ export const PostHtmlRenderer = memo(({
renderers={{
img:_imageRenderer,
a:_anchorRenderer,
- p:_paraRenderer
+ p:_paraRenderer,
+ iframe: IframeRenderer
}}
onHTMLLoaded={onLoaded && onLoaded}
defaultTextProps={{
selectable:true
}}
+ customHTMLElementModels={{
+ iframe: iframeModel
+ }}
+ renderersProps={{
+ iframe: {
+ scalesPageToFit: true,
+ webViewProps: {
+ startInLoadingState:true,
+ onShouldStartLoadWithRequest: () => true ,
+ mediaPlaybackRequiresUserAction: true,
+ allowsFullscreenVideo: false,
+ /* Any prop you want to pass to iframe WebViews */
+ }
+ }
+ }}
+ WebView={WebView}
/>
)
}, (next, prev)=>next.body === prev.body)
diff --git a/yarn.lock b/yarn.lock
index 82d76faf5..f2bb770ca 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"
From 68a94dd2c13541ab5c11b77430c98f66fc35f9d5 Mon Sep 17 00:00:00 2001
From: Sadaqat Ali
Date: Fri, 21 Jan 2022 16:09:30 +0500
Subject: [PATCH 02/23] added custom iframe renderer
---
.../postHtmlRenderer/postHtmlRenderer.tsx | 58 ++++++++++++++-----
1 file changed, 43 insertions(+), 15 deletions(-)
diff --git a/src/components/postHtmlRenderer/postHtmlRenderer.tsx b/src/components/postHtmlRenderer/postHtmlRenderer.tsx
index b51853058..ef8ee54b2 100644
--- a/src/components/postHtmlRenderer/postHtmlRenderer.tsx
+++ b/src/components/postHtmlRenderer/postHtmlRenderer.tsx
@@ -4,7 +4,7 @@ import styles from "./postHtmlRendererStyles";
import { LinkData, parseLinkData } from "./linkDataParser";
import VideoThumb from "./videoThumb";
import { AutoHeightImage } from "../autoHeightImage/autoHeightImage";
-import IframeRenderer, { iframeModel } from '@native-html/iframe-plugin';
+import { useHtmlIframeProps,iframeModel } from '@native-html/iframe-plugin';
import WebView from "react-native-webview";
interface PostHtmlRendererProps {
@@ -38,15 +38,6 @@ export const PostHtmlRenderer = memo(({
//new renderer functions
body = body.replace(//g, '').replace(/<\/center>/g,'
');
-// body = `
-//
-//
-//
-//
Demo Text
-//
-//
-//
`
-
console.log("Comment body:", body);
const _handleOnLinkPress = (data:LinkData) => {
@@ -266,6 +257,47 @@ export const PostHtmlRenderer = memo(({
)
}
+ // 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: `
+
+ `,
+ }
+ : {
+ uri: iframeProps.source.uri,
+ };
+ return (
+ {
+ console.log('load end');
+ }}
+ onLoadStart={() => {
+ console.log('load start');
+ }}
+ source={src}
+ style={{ width: contentWidth, height: (contentWidth * 9) / 16 }}
+ startInLoadingState={true}
+ onShouldStartLoadWithRequest={() => true}
+ mediaPlaybackRequiresUserAction={true}
+ allowsInlineMediaPlayback={true}
+ />
+ );
+ };
return (
true ,
- mediaPlaybackRequiresUserAction: true,
- allowsFullscreenVideo: false,
/* Any prop you want to pass to iframe WebViews */
}
}
From 8b4e2ea013c661cb4f03d881e255eb3fdadfd670 Mon Sep 17 00:00:00 2001
From: Sadaqat Ali
Date: Fri, 21 Jan 2022 18:30:20 +0500
Subject: [PATCH 03/23] changed uri source to support all videos in anchor
renderer
---
src/components/postHtmlRenderer/postHtmlRenderer.tsx | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/components/postHtmlRenderer/postHtmlRenderer.tsx b/src/components/postHtmlRenderer/postHtmlRenderer.tsx
index ef8ee54b2..88437cb71 100644
--- a/src/components/postHtmlRenderer/postHtmlRenderer.tsx
+++ b/src/components/postHtmlRenderer/postHtmlRenderer.tsx
@@ -137,9 +137,11 @@ export const PostHtmlRenderer = memo(({
const data = parseLinkData(tnode);
_handleOnLinkPress(data);
};
- console.log("parseLinkData(tnode) : ", parseLinkData(tnode));
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'];
+
return (
{
console.log('load start');
}}
- source={{ uri: parseLinkData(tnode).videoHref }}
+ source={{ uri: videoHref }}
style={{ width: contentWidth, height: (contentWidth * 9) / 16 }}
startInLoadingState={true}
onShouldStartLoadWithRequest={() => true}
From 9c3f12e06e4b52dac0c3328382f12dbfc6f828bc Mon Sep 17 00:00:00 2001
From: Sadaqat Ali
Date: Sat, 22 Jan 2022 15:32:19 +0500
Subject: [PATCH 04/23] refactored video player
---
src/components/index.js | 2 +
.../postHtmlRenderer/postHtmlRenderer.tsx | 452 ++++++++----------
.../videoPlayer/videoPlayerStyles.ts | 5 +
.../videoPlayer/videoPlayerView.tsx | 98 ++++
4 files changed, 310 insertions(+), 247 deletions(-)
create mode 100644 src/components/videoPlayer/videoPlayerStyles.ts
create mode 100644 src/components/videoPlayer/videoPlayerView.tsx
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..2d94b0754 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 (parsedTnode.type === 'markdown-video-link-youtube') {
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,
+ },
+});
From ddd4de5b37be593abd9c6df9fb159ef72fe20d73 Mon Sep 17 00:00:00 2001
From: Sadaqat Ali
Date: Sat, 22 Jan 2022 16:10:01 +0500
Subject: [PATCH 05/23] changed condition causing crash
---
src/components/postHtmlRenderer/postHtmlRenderer.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/postHtmlRenderer/postHtmlRenderer.tsx b/src/components/postHtmlRenderer/postHtmlRenderer.tsx
index 2d94b0754..3853c94b7 100644
--- a/src/components/postHtmlRenderer/postHtmlRenderer.tsx
+++ b/src/components/postHtmlRenderer/postHtmlRenderer.tsx
@@ -133,7 +133,7 @@ export const PostHtmlRenderer = memo(
_handleOnLinkPress(data);
};
- if (parsedTnode.type === 'markdown-video-link-youtube') {
+ if (tnode.classes?.indexOf('markdown-video-link-youtube') >= 0) {
return (
Date: Sun, 23 Jan 2022 01:11:17 +0500
Subject: [PATCH 06/23] unified video player component
---
.../body/view/commentBodyView.tsx | 11 ++-
.../postElements/body/view/postBodyView.js | 6 +-
.../body/view/videoPlayerSheet.tsx | 83 -------------------
.../postHtmlRenderer/postHtmlRenderer.tsx | 52 +++++-------
.../videoPlayer/videoPlayerView.tsx | 26 ++++--
5 files changed, 48 insertions(+), 130 deletions(-)
delete mode 100644 src/components/postElements/body/view/videoPlayerSheet.tsx
diff --git a/src/components/postElements/body/view/commentBodyView.tsx b/src/components/postElements/body/view/commentBodyView.tsx
index bf7b79d29..52b518d5e 100644
--- a/src/components/postElements/body/view/commentBodyView.tsx
+++ b/src/components/postElements/body/view/commentBodyView.tsx
@@ -13,7 +13,7 @@ import { navigate } from '../../../../navigation/service';
// Constants
import { default as ROUTES } from '../../../../constants/routeNames';
-import { PostHtmlRenderer, TextButton } from '../../..';
+import { PostHtmlRenderer, TextButton, VideoPlayer } from '../../..';
// Styles
import styles from './commentBodyStyles';
@@ -21,14 +21,12 @@ import styles from './commentBodyStyles';
// Services and Actions
import { writeToClipboard } from '../../../../utils/clipboard';
import { toastNotification } from '../../../../redux/actions/uiAction';
-import VideoPlayerSheet from './videoPlayerSheet';
import { LongPressGestureHandler, State } from 'react-native-gesture-handler';
import { useCallback } from 'react';
import { OptionsModal } from '../../../atoms';
import { useAppDispatch } from '../../../../hooks';
import { isCommunity } from '../../../../utils/communityValidation';
import { GLOBAL_POST_FILTERS_VALUE } from '../../../../constants/options/filters';
-import { startsWith } from 'core-js/core/string';
const WIDTH = Dimensions.get('window').width;
@@ -368,7 +366,12 @@ const CommentBody = ({
setVideoUrl(null);
}}
>
-
+
);
diff --git a/src/components/postElements/body/view/postBodyView.js b/src/components/postElements/body/view/postBodyView.js
index 052931d6b..8979014ad 100644
--- a/src/components/postElements/body/view/postBodyView.js
+++ b/src/components/postElements/body/view/postBodyView.js
@@ -15,11 +15,10 @@ import { toastNotification } from '../../../../redux/actions/uiAction';
// Constants
import { default as ROUTES } from '../../../../constants/routeNames';
-import VideoPlayerSheet from './videoPlayerSheet';
import { OptionsModal } from '../../../atoms';
import { isCommunity } from '../../../../utils/communityValidation';
import { GLOBAL_POST_FILTERS_VALUE } from '../../../../constants/options/filters';
-import { PostHtmlRenderer } from '../../..';
+import { PostHtmlRenderer, VideoPlayer } from '../../..';
const WIDTH = Dimensions.get('window').width;
@@ -294,7 +293,8 @@ const PostBody = ({ navigation, body, dispatch, onLoadEnd }) => {
setVideoUrl(null);
}}
>
- {
-
- 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);
- }
-
- const _onChangeState = (event:string) => {
- setShouldPlay(!(event == 'paused' || event == 'ended'));
- }
-
- const _onError = () => {
- setLoading(false)
- }
-
- const initialParams:InitialPlayerParams = {
- start:startTime
- }
-
- return (
-
-
- {youtubeVideoId &&
-
-
- }{
- videoUrl &&
-
- {
- setLoading(false);
- }}
- onLoadStart={()=>{
- setLoading(true);
- }}
- source={{uri:videoUrl}}
- />
-
-
- }
- {loading && }
-
- );
-};
-
-export default VideoPlayerSheet;
-
-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/components/postHtmlRenderer/postHtmlRenderer.tsx b/src/components/postHtmlRenderer/postHtmlRenderer.tsx
index 3853c94b7..a66dfdff9 100644
--- a/src/components/postHtmlRenderer/postHtmlRenderer.tsx
+++ b/src/components/postHtmlRenderer/postHtmlRenderer.tsx
@@ -218,43 +218,31 @@ export const PostHtmlRenderer = memo(
return ;
};
+
// iframe renderer for rendering iframes in body
const _iframeRenderer = function IframeRenderer(props) {
const iframeProps = useHtmlIframeProps(props);
const checkSrcRegex = /(.*?)\.(mp4|webm|ogg)$/gi;
- const isVideoType = iframeProps.source.uri.match(checkSrcRegex);
+ const isVideoFormat = iframeProps.source.uri.match(checkSrcRegex);
- const src = isVideoType
- ? {
- html: `
-
- `,
- }
- : {
- uri: iframeProps.source.uri,
- };
- return (
- {
- console.log('load end');
- }}
- onLoadStart={() => {
- console.log('load start');
- }}
- source={src}
- style={{ width: contentWidth, height: (contentWidth * 9) / 16 }}
- startInLoadingState={true}
- onShouldStartLoadWithRequest={() => true}
- mediaPlaybackRequiresUserAction={true}
- allowsInlineMediaPlayback={true}
- />
- );
+ //this hack help avoid autoplaying fullscreened iframe videos;
+ const src = isVideoFormat ?
+ {
+ html: `
+ `,
+ }:{
+ uri: iframeProps.source.uri,
+ };
+
+ return (
+
+ );
};
return (
diff --git a/src/components/videoPlayer/videoPlayerView.tsx b/src/components/videoPlayer/videoPlayerView.tsx
index 500aa5fbf..65e9dfc91 100644
--- a/src/components/videoPlayer/videoPlayerView.tsx
+++ b/src/components/videoPlayer/videoPlayerView.tsx
@@ -1,19 +1,29 @@
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';
+import { WebViewSource } from 'react-native-webview/lib/WebViewTypes';
interface VideoPlayerProps {
+ mode: 'source'|'youtube'|'url';
+ contentWidth?: number;
youtubeVideoId?: string;
videoUrl?: string;
startTime?: number;
- contentWidth?: number;
+ source?: WebViewSource;
}
-const VideoPlayer = ({ youtubeVideoId, videoUrl, startTime, contentWidth }: VideoPlayerProps) => {
- const PLAYER_HEIGHT = Dimensions.get('screen').width * (9 / 16);
+const VideoPlayer = ({
+ youtubeVideoId,
+ videoUrl,
+ startTime,
+ source,
+ contentWidth = Dimensions.get('screen').width,
+ mode
+ }: VideoPlayerProps) => {
+
+ const PLAYER_HEIGHT = contentWidth * (9 / 16);
const [shouldPlay, setShouldPlay] = useState(false);
const [loading, setLoading] = useState(true);
@@ -40,7 +50,7 @@ const VideoPlayer = ({ youtubeVideoId, videoUrl, startTime, contentWidth }: Vide
return (
- {youtubeVideoId && (
+ {mode === 'youtube' && youtubeVideoId && (
)}
- {videoUrl && (
+ {((mode === 'source' && source) || (mode === 'url' && videoUrl)) && (
{
setLoading(true);
}}
- source={{ uri: videoUrl }}
- style={{ width: contentWidth, height: (contentWidth * 9) / 16 }}
+ source={source || { uri: videoUrl }}
+ style={{ width: contentWidth, height: PLAYER_HEIGHT}}
startInLoadingState={true}
onShouldStartLoadWithRequest={() => true}
mediaPlaybackRequiresUserAction={true}
From aa963f5f8b219ee5fcb075d4ccf40c05cfe681f4 Mon Sep 17 00:00:00 2001
From: noumantahir
Date: Sun, 23 Jan 2022 01:12:11 +0500
Subject: [PATCH 07/23] cleaned up video link processor in anchorRenderer,
using sheet based players for comments
---
.../body/view/commentBodyView.tsx | 1 +
.../postHtmlRenderer/postHtmlRenderer.tsx | 57 +++++++++++--------
2 files changed, 33 insertions(+), 25 deletions(-)
diff --git a/src/components/postElements/body/view/commentBodyView.tsx b/src/components/postElements/body/view/commentBodyView.tsx
index 52b518d5e..730816e4d 100644
--- a/src/components/postElements/body/view/commentBodyView.tsx
+++ b/src/components/postElements/body/view/commentBodyView.tsx
@@ -335,6 +335,7 @@ const CommentBody = ({
void;
setSelectedImage: (imgUrl: string) => void;
setSelectedLink: (url: string) => void;
@@ -28,6 +27,7 @@ export const PostHtmlRenderer = memo(
({
contentWidth,
body,
+ isComment,
onLoaded,
setSelectedImage,
setSelectedLink,
@@ -133,35 +133,42 @@ export const PostHtmlRenderer = memo(
_handleOnLinkPress(data);
};
- if (tnode.classes?.indexOf('markdown-video-link-youtube') >= 0) {
- 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 ;
+
+ //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 ;
+ }
+ }
+ else if(tnode.classes?.indexOf('markdown-video-link-youtube') >= 0){
+ return (
+
+ );
+ } else {
+ 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
From 2f167af102872f260e945a7b1077ce02bbcf727b Mon Sep 17 00:00:00 2001
From: noumantahir
Date: Sun, 23 Jan 2022 01:22:13 +0500
Subject: [PATCH 08/23] improved player response and refined logic
---
.../postHtmlRenderer/postHtmlRenderer.tsx | 15 ++++-----------
src/components/videoPlayer/videoPlayerView.tsx | 8 ++++++--
2 files changed, 10 insertions(+), 13 deletions(-)
diff --git a/src/components/postHtmlRenderer/postHtmlRenderer.tsx b/src/components/postHtmlRenderer/postHtmlRenderer.tsx
index eacb47841..01d7c9430 100644
--- a/src/components/postHtmlRenderer/postHtmlRenderer.tsx
+++ b/src/components/postHtmlRenderer/postHtmlRenderer.tsx
@@ -143,22 +143,15 @@ export const PostHtmlRenderer = memo(
if (!imgElement) {
return ;
}
- }
- else if(tnode.classes?.indexOf('markdown-video-link-youtube') >= 0){
- return (
-
- );
} else {
return (
);
}
diff --git a/src/components/videoPlayer/videoPlayerView.tsx b/src/components/videoPlayer/videoPlayerView.tsx
index 65e9dfc91..60bd9fb67 100644
--- a/src/components/videoPlayer/videoPlayerView.tsx
+++ b/src/components/videoPlayer/videoPlayerView.tsx
@@ -12,6 +12,9 @@ interface VideoPlayerProps {
videoUrl?: string;
startTime?: number;
source?: WebViewSource;
+
+ //prop for youtube player
+ disableAutoplay?:boolean;
}
const VideoPlayer = ({
@@ -20,7 +23,8 @@ const VideoPlayer = ({
startTime,
source,
contentWidth = Dimensions.get('screen').width,
- mode
+ mode,
+ disableAutoplay
}: VideoPlayerProps) => {
const PLAYER_HEIGHT = contentWidth * (9 / 16);
@@ -30,7 +34,7 @@ const VideoPlayer = ({
const _onReady = () => {
setLoading(false);
- setShouldPlay(true);
+ setShouldPlay(disableAutoplay ? false : true);
console.log('ready');
};
From 153d99e86398eee722cdf12a7cd4c9dae1ec0017 Mon Sep 17 00:00:00 2001
From: noumantahir
Date: Sun, 23 Jan 2022 20:31:04 +0500
Subject: [PATCH 09/23] ability to extract word at selection index
---
.../markdownEditor/view/markdownEditorView.js | 8 ++++++++
src/utils/editor.ts | 17 +++++++++++++++++
2 files changed, 25 insertions(+)
diff --git a/src/components/markdownEditor/view/markdownEditorView.js b/src/components/markdownEditor/view/markdownEditorView.js
index 6d7241413..2c4419cba 100644
--- a/src/components/markdownEditor/view/markdownEditorView.js
+++ b/src/components/markdownEditor/view/markdownEditorView.js
@@ -46,6 +46,7 @@ import styles from './markdownEditorStyles';
import applySnippet from './formats/applySnippet';
import { MainButton } from '../../mainButton';
import isAndroidOreo from '../../../utils/isAndroidOreo';
+import { extractWordAtIndex } from '../../../utils/editor';
const MIN_BODY_INPUT_HEIGHT = 300;
@@ -104,6 +105,13 @@ const MarkdownEditorView = ({
}
}, [onLoadDraftPress]);
+ useEffect(() => {
+ if (selection.start === selection.end && text) {
+ const word = extractWordAtIndex(text, selection.start);
+ console.log('selection word is: ', word);
+ }
+ }, [text, selection]);
+
useEffect(() => {
if (text === '' && draftBody !== '') {
_setTextAndSelection({ selection: { start: 0, end: 0 }, text: draftBody });
diff --git a/src/utils/editor.ts b/src/utils/editor.ts
index c2c8df62e..c97fde485 100644
--- a/src/utils/editor.ts
+++ b/src/utils/editor.ts
@@ -44,6 +44,23 @@ export const generatePermlink = (title, random = false) => {
return perm;
};
+export const extractWordAtIndex = (text:string, index:number) => {
+ let word = '';
+ for(let i = index; i >= 0 && text[i] !== ' '; i--){
+ if(text[i]){
+ word += text[i];
+ }
+ }
+ word = word.split('').reverse().join('');
+ for(let i = index + 1; i < text.length && text[i] !== ' '; i++){
+ if(text[i]){
+ word += text[i];
+ }
+ }
+ return word;
+
+}
+
export const generateReplyPermlink = (toAuthor) => {
if (!toAuthor) {
return '';
From ae34c148702fed26769361f489453906d6e121d8 Mon Sep 17 00:00:00 2001
From: noumantahir
Date: Thu, 27 Jan 2022 13:25:35 +0500
Subject: [PATCH 10/23] searching for available users
---
.../markdownEditor/view/markdownEditorView.js | 27 +++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/src/components/markdownEditor/view/markdownEditorView.js b/src/components/markdownEditor/view/markdownEditorView.js
index 2c4419cba..c2153e911 100644
--- a/src/components/markdownEditor/view/markdownEditorView.js
+++ b/src/components/markdownEditor/view/markdownEditorView.js
@@ -47,6 +47,7 @@ import applySnippet from './formats/applySnippet';
import { MainButton } from '../../mainButton';
import isAndroidOreo from '../../../utils/isAndroidOreo';
import { extractWordAtIndex } from '../../../utils/editor';
+import { searchAccount } from '../../../providers/ecency/ecency';
const MIN_BODY_INPUT_HEIGHT = 300;
@@ -82,6 +83,7 @@ const MarkdownEditorView = ({
const [bodyInputHeight, setBodyInputHeight] = useState(MIN_BODY_INPUT_HEIGHT);
const [isSnippetsOpen, setIsSnippetsOpen] = useState(false);
const [showDraftLoadButton, setShowDraftLoadButton] = useState(false);
+ const [autoCompleteUsers, setAutoCompleteUsers] = useState([]);
const inputRef = useRef(null);
const galleryRef = useRef(null);
@@ -109,6 +111,9 @@ const MarkdownEditorView = ({
if (selection.start === selection.end && text) {
const word = extractWordAtIndex(text, selection.start);
console.log('selection word is: ', word);
+ if(word.startsWith('@')){
+ _handleUserSearch(word.substring(1));
+ }
}
}, [text, selection]);
@@ -192,6 +197,17 @@ const MarkdownEditorView = ({
dispatch(toggleAccountsBottomSheet(!isVisibleAccountsBottomSheet));
};
+
+ const _handleUserSearch = async (username) => {
+ let users = [];
+ if(username){
+ users = await searchAccount(username, 5);
+ console.log("result users", users)
+ }
+
+ setAutoCompleteUsers(users);
+ }
+
// eslint-disable-next-line react-hooks/exhaustive-deps
const _changeText = useCallback((input) => {
setText(input);
@@ -311,6 +327,16 @@ const MarkdownEditorView = ({
}
};
+ const _renderLookedUpAccounts = () => {
+ return {
+ return {user.name + ' '}
+ }}
+ />
+ }
+
const _renderEditorButtons = () => (
@@ -459,6 +485,7 @@ const MarkdownEditorView = ({
{isAndroidOreo() ? _renderEditorWithoutScroll() : _renderEditorWithScroll()}
{_renderFloatingDraftButton()}
+ {_renderLookedUpAccounts()}
{!isPreviewActive && _renderEditorButtons()}
Date: Thu, 27 Jan 2022 14:16:29 +0500
Subject: [PATCH 11/23] improved word extractor
---
src/utils/editor.ts | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/src/utils/editor.ts b/src/utils/editor.ts
index c97fde485..ffabb7aa0 100644
--- a/src/utils/editor.ts
+++ b/src/utils/editor.ts
@@ -45,18 +45,23 @@ export const generatePermlink = (title, random = false) => {
};
export const extractWordAtIndex = (text:string, index:number) => {
+ const END_REGEX = /[\s,]/
let word = '';
- for(let i = index; i >= 0 && text[i] !== ' '; i--){
+ 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('');
- for(let i = index + 1; i < text.length && text[i] !== ' '; i++){
- if(text[i]){
- word += text[i];
+
+ 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;
}
From e75d8d0415db184d4423349479df1f7996e714b1 Mon Sep 17 00:00:00 2001
From: noumantahir
Date: Thu, 27 Jan 2022 15:39:57 +0500
Subject: [PATCH 12/23] added users bar component for rendering searched users
---
.../markdownEditor/view/usersBar.tsx | 36 +++++++++++++++++++
1 file changed, 36 insertions(+)
create mode 100644 src/components/markdownEditor/view/usersBar.tsx
diff --git a/src/components/markdownEditor/view/usersBar.tsx b/src/components/markdownEditor/view/usersBar.tsx
new file mode 100644
index 000000000..feb7c56b5
--- /dev/null
+++ b/src/components/markdownEditor/view/usersBar.tsx
@@ -0,0 +1,36 @@
+import React from 'react';
+import { View, FlatList, Text } from "react-native"
+import { TouchableOpacity } from 'react-native-gesture-handler';
+import { UserAvatar } from '../..';
+import styles from './markdownEditorStyles';
+
+interface Props {
+ usernames:Array;
+ onUserSelect:(username:string)=>void;
+}
+
+export const UsersBar = ({usernames, onUserSelect}:Props) => {
+
+ const _renderItem = ({item}:{item:string}) => {
+ const username = item;
+ return (
+ {onUserSelect(username)}}>
+
+
+ {username}
+
+
+ )
+ }
+
+ return (
+
+
+
+ )
+ }
From 6422f1d3b8405bb3037d1a943ab844a49af1f95f Mon Sep 17 00:00:00 2001
From: noumantahir
Date: Thu, 27 Jan 2022 15:40:05 +0500
Subject: [PATCH 13/23] updated styles
---
.../view/markdownEditorStyles.js | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/src/components/markdownEditor/view/markdownEditorStyles.js b/src/components/markdownEditor/view/markdownEditorStyles.js
index 6a12e7f7e..db5c32267 100644
--- a/src/components/markdownEditor/view/markdownEditorStyles.js
+++ b/src/components/markdownEditor/view/markdownEditorStyles.js
@@ -110,4 +110,29 @@ export default EStyleSheet.create({
bottom: 56,
},
}),
+ searchAccountsContainer: Platform.select({
+ //absolute positioning makes button hide behind keyboard on ios
+ ios: {
+ marginBottom: 24,
+ },
+ //on android the appearing of button was causing momentary glitch with ios variant style
+ android: {
+ position: 'absolute',
+ bottom: 56,
+ },
+ }),
+ userBubble: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ marginHorizontal: 4,
+ paddingHorizontal: 8,
+ paddingVertical: 8,
+ backgroundColor: '$primaryBlue',
+ borderRadius: 24,
+ },
+ userBubbleText: {
+ fontSize: 16,
+ color: '$white',
+ marginHorizontal: 6,
+ },
});
From cefa54cb0b7aba4ccb4d86b3b4c1873bf4b83f87 Mon Sep 17 00:00:00 2001
From: noumantahir
Date: Thu, 27 Jan 2022 16:00:37 +0500
Subject: [PATCH 14/23] basic end to end implementation
---
.../markdownEditor/view/markdownEditorView.js | 40 +++++++++++--------
1 file changed, 23 insertions(+), 17 deletions(-)
diff --git a/src/components/markdownEditor/view/markdownEditorView.js b/src/components/markdownEditor/view/markdownEditorView.js
index c2153e911..f398da8f0 100644
--- a/src/components/markdownEditor/view/markdownEditorView.js
+++ b/src/components/markdownEditor/view/markdownEditorView.js
@@ -48,6 +48,7 @@ import { MainButton } from '../../mainButton';
import isAndroidOreo from '../../../utils/isAndroidOreo';
import { extractWordAtIndex } from '../../../utils/editor';
import { searchAccount } from '../../../providers/ecency/ecency';
+import { UsersBar } from './usersBar';
const MIN_BODY_INPUT_HEIGHT = 300;
@@ -111,8 +112,10 @@ const MarkdownEditorView = ({
if (selection.start === selection.end && text) {
const word = extractWordAtIndex(text, selection.start);
console.log('selection word is: ', word);
- if(word.startsWith('@')){
+ if (word.startsWith('@') && word.length > 3) {
_handleUserSearch(word.substring(1));
+ } else {
+ setAutoCompleteUsers([]);
}
}
}, [text, selection]);
@@ -197,16 +200,26 @@ const MarkdownEditorView = ({
dispatch(toggleAccountsBottomSheet(!isVisibleAccountsBottomSheet));
};
-
const _handleUserSearch = async (username) => {
let users = [];
- if(username){
+ if (username) {
users = await searchAccount(username, 5);
- console.log("result users", users)
+ console.log('result users', users);
}
setAutoCompleteUsers(users);
- }
+ };
+
+ const _onUserSelect = (username) => {
+ const word = extractWordAtIndex(text, selection.start);
+ const from = text.indexOf(word, selection.start - word.length);
+ const _text = text.slice(0, from) + text.slice(from).replace(word, '@' + username + ' ');
+
+ const sel = from + word.length + 2;
+ const _selection = { start: sel, end: sel };
+ _setTextAndSelection({ selection: _selection, text: _text });
+ setAutoCompleteUsers([]);
+ };
// eslint-disable-next-line react-hooks/exhaustive-deps
const _changeText = useCallback((input) => {
@@ -327,16 +340,6 @@ const MarkdownEditorView = ({
}
};
- const _renderLookedUpAccounts = () => {
- return {
- return {user.name + ' '}
- }}
- />
- }
-
const _renderEditorButtons = () => (
@@ -483,9 +486,12 @@ const MarkdownEditorView = ({
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
>
{isAndroidOreo() ? _renderEditorWithoutScroll() : _renderEditorWithScroll()}
-
+ user.name)}
+ onUserSelect={_onUserSelect}
+ />
{_renderFloatingDraftButton()}
- {_renderLookedUpAccounts()}
+
{!isPreviewActive && _renderEditorButtons()}
Date: Thu, 27 Jan 2022 18:55:01 +0500
Subject: [PATCH 15/23] Organised username insert code
---
.../view/formats/applyUsername.ts | 11 ++++++++++
.../markdownEditor/view/markdownEditorView.js | 22 ++++++-------------
2 files changed, 18 insertions(+), 15 deletions(-)
create mode 100644 src/components/markdownEditor/view/formats/applyUsername.ts
diff --git a/src/components/markdownEditor/view/formats/applyUsername.ts b/src/components/markdownEditor/view/formats/applyUsername.ts
new file mode 100644
index 000000000..9ff3454b1
--- /dev/null
+++ b/src/components/markdownEditor/view/formats/applyUsername.ts
@@ -0,0 +1,11 @@
+import { extractWordAtIndex } from '../../../../utils/editor';
+import {replaceBetween } from './utils';
+
+export default async ({ text, selection, setTextAndSelection, username}) => {
+ const _word = extractWordAtIndex(text, selection.start);
+ const _insertAt = text.indexOf(_word, selection.start - _word.length);
+ const _text = replaceBetween(text, {start:_insertAt, end:_insertAt + _word.length}, `@${username} `)
+ const _newPos = _insertAt + username.length + 2;
+ const _selection = { start: _newPos, end: _newPos };
+ setTextAndSelection({ selection: _selection, text: _text });
+};
\ No newline at end of file
diff --git a/src/components/markdownEditor/view/markdownEditorView.js b/src/components/markdownEditor/view/markdownEditorView.js
index f398da8f0..269cbf16c 100644
--- a/src/components/markdownEditor/view/markdownEditorView.js
+++ b/src/components/markdownEditor/view/markdownEditorView.js
@@ -49,6 +49,7 @@ import isAndroidOreo from '../../../utils/isAndroidOreo';
import { extractWordAtIndex } from '../../../utils/editor';
import { searchAccount } from '../../../providers/ecency/ecency';
import { UsersBar } from './usersBar';
+import applyUsername from './formats/applyUsername';
const MIN_BODY_INPUT_HEIGHT = 300;
@@ -84,7 +85,7 @@ const MarkdownEditorView = ({
const [bodyInputHeight, setBodyInputHeight] = useState(MIN_BODY_INPUT_HEIGHT);
const [isSnippetsOpen, setIsSnippetsOpen] = useState(false);
const [showDraftLoadButton, setShowDraftLoadButton] = useState(false);
- const [autoCompleteUsers, setAutoCompleteUsers] = useState([]);
+ const [searchedUsers, setSearchedUsers] = useState([]);
const inputRef = useRef(null);
const galleryRef = useRef(null);
@@ -115,7 +116,7 @@ const MarkdownEditorView = ({
if (word.startsWith('@') && word.length > 3) {
_handleUserSearch(word.substring(1));
} else {
- setAutoCompleteUsers([]);
+ setSearchedUsers([]);
}
}
}, [text, selection]);
@@ -207,18 +208,12 @@ const MarkdownEditorView = ({
console.log('result users', users);
}
- setAutoCompleteUsers(users);
+ setSearchedUsers(users);
};
const _onUserSelect = (username) => {
- const word = extractWordAtIndex(text, selection.start);
- const from = text.indexOf(word, selection.start - word.length);
- const _text = text.slice(0, from) + text.slice(from).replace(word, '@' + username + ' ');
-
- const sel = from + word.length + 2;
- const _selection = { start: sel, end: sel };
- _setTextAndSelection({ selection: _selection, text: _text });
- setAutoCompleteUsers([]);
+ applyUsername(text, selection, _setTextAndSelection, username);
+ setSearchedUsers([]);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
@@ -486,10 +481,7 @@ const MarkdownEditorView = ({
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
>
{isAndroidOreo() ? _renderEditorWithoutScroll() : _renderEditorWithScroll()}
- user.name)}
- onUserSelect={_onUserSelect}
- />
+ user.name)} onUserSelect={_onUserSelect} />
{_renderFloatingDraftButton()}
{!isPreviewActive && _renderEditorButtons()}
From 07574b6103c00ac06573505bbbe4be71b361bcea Mon Sep 17 00:00:00 2001
From: noumantahir
Date: Thu, 27 Jan 2022 18:55:29 +0500
Subject: [PATCH 16/23] improved usersBar styling
---
.../view/markdownEditorStyles.js | 3 ++-
.../markdownEditor/view/usersBar.tsx | 26 ++++++++++++-------
2 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/src/components/markdownEditor/view/markdownEditorStyles.js b/src/components/markdownEditor/view/markdownEditorStyles.js
index db5c32267..ee0ddd5d5 100644
--- a/src/components/markdownEditor/view/markdownEditorStyles.js
+++ b/src/components/markdownEditor/view/markdownEditorStyles.js
@@ -113,7 +113,8 @@ export default EStyleSheet.create({
searchAccountsContainer: Platform.select({
//absolute positioning makes button hide behind keyboard on ios
ios: {
- marginBottom: 24,
+ marginBottom: 12,
+ paddingTop: 8,
},
//on android the appearing of button was causing momentary glitch with ios variant style
android: {
diff --git a/src/components/markdownEditor/view/usersBar.tsx b/src/components/markdownEditor/view/usersBar.tsx
index feb7c56b5..9548c8c1f 100644
--- a/src/components/markdownEditor/view/usersBar.tsx
+++ b/src/components/markdownEditor/view/usersBar.tsx
@@ -1,6 +1,5 @@
import React from 'react';
-import { View, FlatList, Text } from "react-native"
-import { TouchableOpacity } from 'react-native-gesture-handler';
+import { View, FlatList, Text, TouchableOpacity } from "react-native"
import { UserAvatar } from '../..';
import styles from './markdownEditorStyles';
@@ -11,7 +10,12 @@ interface Props {
export const UsersBar = ({usernames, onUserSelect}:Props) => {
+ if(!usernames || usernames.length === 0){
+ return null;
+ }
+
const _renderItem = ({item}:{item:string}) => {
+
const username = item;
return (
{onUserSelect(username)}}>
@@ -24,13 +28,15 @@ export const UsersBar = ({usernames, onUserSelect}:Props) => {
}
return (
-
-
-
+
+
+
)
}
From 5d1290dbe3795c4696abdb1ec05e113d8fcd3352 Mon Sep 17 00:00:00 2001
From: noumantahir
Date: Thu, 27 Jan 2022 19:02:34 +0500
Subject: [PATCH 17/23] resolved wrong method call applyUsername
---
src/components/markdownEditor/view/markdownEditorView.js | 7 ++++++-
src/components/markdownEditor/view/usersBar.tsx | 1 -
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/components/markdownEditor/view/markdownEditorView.js b/src/components/markdownEditor/view/markdownEditorView.js
index 269cbf16c..642e37f8f 100644
--- a/src/components/markdownEditor/view/markdownEditorView.js
+++ b/src/components/markdownEditor/view/markdownEditorView.js
@@ -212,7 +212,12 @@ const MarkdownEditorView = ({
};
const _onUserSelect = (username) => {
- applyUsername(text, selection, _setTextAndSelection, username);
+ applyUsername({
+ text,
+ selection,
+ setTextAndSelection: _setTextAndSelection,
+ username,
+ });
setSearchedUsers([]);
};
diff --git a/src/components/markdownEditor/view/usersBar.tsx b/src/components/markdownEditor/view/usersBar.tsx
index 9548c8c1f..65a6363e0 100644
--- a/src/components/markdownEditor/view/usersBar.tsx
+++ b/src/components/markdownEditor/view/usersBar.tsx
@@ -30,7 +30,6 @@ export const UsersBar = ({usernames, onUserSelect}:Props) => {
return (
Date: Thu, 27 Jan 2022 19:32:39 +0500
Subject: [PATCH 18/23] refined user bubbble
---
src/components/markdownEditor/view/markdownEditorStyles.js | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/components/markdownEditor/view/markdownEditorStyles.js b/src/components/markdownEditor/view/markdownEditorStyles.js
index ee0ddd5d5..4adfa8c25 100644
--- a/src/components/markdownEditor/view/markdownEditorStyles.js
+++ b/src/components/markdownEditor/view/markdownEditorStyles.js
@@ -126,14 +126,15 @@ export default EStyleSheet.create({
flexDirection: 'row',
alignItems: 'center',
marginHorizontal: 4,
- paddingHorizontal: 8,
- paddingVertical: 8,
+ paddingHorizontal: 4,
+ paddingVertical: 4,
backgroundColor: '$primaryBlue',
borderRadius: 24,
},
userBubbleText: {
fontSize: 16,
color: '$white',
- marginHorizontal: 6,
+ marginLeft: 6,
+ marginRight: 8,
},
});
From 5cb037bc28efbffc091605213b7d53f8d167ec44 Mon Sep 17 00:00:00 2001
From: noumantahir
Date: Thu, 27 Jan 2022 19:42:52 +0500
Subject: [PATCH 19/23] cleaned markdownEditor by moving username search to
separate component completely
---
.../markdownEditor/view/markdownEditorView.js | 32 +-------
.../view/usernameAutofillBar.tsx | 78 +++++++++++++++++++
.../markdownEditor/view/usersBar.tsx | 41 ----------
3 files changed, 81 insertions(+), 70 deletions(-)
create mode 100644 src/components/markdownEditor/view/usernameAutofillBar.tsx
delete mode 100644 src/components/markdownEditor/view/usersBar.tsx
diff --git a/src/components/markdownEditor/view/markdownEditorView.js b/src/components/markdownEditor/view/markdownEditorView.js
index 642e37f8f..78fa5e16c 100644
--- a/src/components/markdownEditor/view/markdownEditorView.js
+++ b/src/components/markdownEditor/view/markdownEditorView.js
@@ -46,9 +46,7 @@ import styles from './markdownEditorStyles';
import applySnippet from './formats/applySnippet';
import { MainButton } from '../../mainButton';
import isAndroidOreo from '../../../utils/isAndroidOreo';
-import { extractWordAtIndex } from '../../../utils/editor';
-import { searchAccount } from '../../../providers/ecency/ecency';
-import { UsersBar } from './usersBar';
+import { UsernameAutofillBar } from './usernameAutofillBar';
import applyUsername from './formats/applyUsername';
const MIN_BODY_INPUT_HEIGHT = 300;
@@ -85,7 +83,6 @@ const MarkdownEditorView = ({
const [bodyInputHeight, setBodyInputHeight] = useState(MIN_BODY_INPUT_HEIGHT);
const [isSnippetsOpen, setIsSnippetsOpen] = useState(false);
const [showDraftLoadButton, setShowDraftLoadButton] = useState(false);
- const [searchedUsers, setSearchedUsers] = useState([]);
const inputRef = useRef(null);
const galleryRef = useRef(null);
@@ -109,18 +106,6 @@ const MarkdownEditorView = ({
}
}, [onLoadDraftPress]);
- useEffect(() => {
- if (selection.start === selection.end && text) {
- const word = extractWordAtIndex(text, selection.start);
- console.log('selection word is: ', word);
- if (word.startsWith('@') && word.length > 3) {
- _handleUserSearch(word.substring(1));
- } else {
- setSearchedUsers([]);
- }
- }
- }, [text, selection]);
-
useEffect(() => {
if (text === '' && draftBody !== '') {
_setTextAndSelection({ selection: { start: 0, end: 0 }, text: draftBody });
@@ -201,24 +186,13 @@ const MarkdownEditorView = ({
dispatch(toggleAccountsBottomSheet(!isVisibleAccountsBottomSheet));
};
- const _handleUserSearch = async (username) => {
- let users = [];
- if (username) {
- users = await searchAccount(username, 5);
- console.log('result users', users);
- }
-
- setSearchedUsers(users);
- };
-
- const _onUserSelect = (username) => {
+ const _onApplyUsername = (username) => {
applyUsername({
text,
selection,
setTextAndSelection: _setTextAndSelection,
username,
});
- setSearchedUsers([]);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
@@ -486,7 +460,7 @@ const MarkdownEditorView = ({
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
>
{isAndroidOreo() ? _renderEditorWithoutScroll() : _renderEditorWithScroll()}
- user.name)} onUserSelect={_onUserSelect} />
+
{_renderFloatingDraftButton()}
{!isPreviewActive && _renderEditorButtons()}
diff --git a/src/components/markdownEditor/view/usernameAutofillBar.tsx b/src/components/markdownEditor/view/usernameAutofillBar.tsx
new file mode 100644
index 000000000..1c5f4bf28
--- /dev/null
+++ b/src/components/markdownEditor/view/usernameAutofillBar.tsx
@@ -0,0 +1,78 @@
+import React, {useState, useEffect} from 'react';
+import { View, FlatList, Text, TouchableOpacity } from "react-native"
+import { UserAvatar } from '../..';
+import { searchAccount } from '../../../providers/ecency/ecency';
+import { extractWordAtIndex } from '../../../utils/editor';
+import styles from './markdownEditorStyles';
+
+interface Props {
+ text:string,
+ selection:{
+ start:number,
+ end:number
+ }
+ onApplyUsername:(username:string)=>void;
+}
+
+export const UsernameAutofillBar = ({text, selection, onApplyUsername}:Props) => {
+
+ const [searchedUsers, setSearchedUsers] = useState([])
+
+ useEffect(() => {
+ if (selection.start === selection.end && text) {
+ const word = extractWordAtIndex(text, selection.start);
+ console.log('selection word is: ', word);
+ if (word.startsWith('@') && word.length > 3) {
+ _handleUserSearch(word.substring(1));
+ } else {
+ setSearchedUsers([]);
+ }
+ }
+ }, [text, selection])
+
+
+ const _handleUserSearch = async (username) => {
+ let users = [];
+ if (username) {
+ users = await searchAccount(username, 5);
+ console.log('result users', users);
+ }
+ setSearchedUsers(users);
+ };
+
+ const _onUserSelect = (username) => {
+ onApplyUsername(username)
+ setSearchedUsers([]);
+ };
+
+ if(!searchedUsers || searchedUsers.length === 0){
+ return null;
+ }
+
+ const _renderItem = ({item}:{item:string}) => {
+
+ const username = item;
+ return (
+ {_onUserSelect(username)}}>
+
+
+ {username}
+
+
+ )
+ }
+
+ const usernames = searchedUsers.map(user=>user.name)
+
+ return (
+
+
+
+ )
+ }
diff --git a/src/components/markdownEditor/view/usersBar.tsx b/src/components/markdownEditor/view/usersBar.tsx
deleted file mode 100644
index 65a6363e0..000000000
--- a/src/components/markdownEditor/view/usersBar.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import React from 'react';
-import { View, FlatList, Text, TouchableOpacity } from "react-native"
-import { UserAvatar } from '../..';
-import styles from './markdownEditorStyles';
-
-interface Props {
- usernames:Array;
- onUserSelect:(username:string)=>void;
-}
-
-export const UsersBar = ({usernames, onUserSelect}:Props) => {
-
- if(!usernames || usernames.length === 0){
- return null;
- }
-
- const _renderItem = ({item}:{item:string}) => {
-
- const username = item;
- return (
- {onUserSelect(username)}}>
-
-
- {username}
-
-
- )
- }
-
- return (
-
-
-
- )
- }
From ac462d619d8b0f6e6f8c1ef53c3797a84ac74aa0 Mon Sep 17 00:00:00 2001
From: noumantahir
Date: Thu, 27 Jan 2022 19:55:31 +0500
Subject: [PATCH 20/23] swapped search method with dhive lookupAccounts method
---
.../markdownEditor/view/usernameAutofillBar.tsx | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/src/components/markdownEditor/view/usernameAutofillBar.tsx b/src/components/markdownEditor/view/usernameAutofillBar.tsx
index 1c5f4bf28..30c1660b7 100644
--- a/src/components/markdownEditor/view/usernameAutofillBar.tsx
+++ b/src/components/markdownEditor/view/usernameAutofillBar.tsx
@@ -1,9 +1,10 @@
import React, {useState, useEffect} from 'react';
import { View, FlatList, Text, TouchableOpacity } from "react-native"
import { UserAvatar } from '../..';
-import { searchAccount } from '../../../providers/ecency/ecency';
+import { lookupAccounts } from '../../../providers/hive/dhive';
import { extractWordAtIndex } from '../../../utils/editor';
import styles from './markdownEditorStyles';
+import {debounce} from 'lodash';
interface Props {
text:string,
@@ -31,14 +32,17 @@ export const UsernameAutofillBar = ({text, selection, onApplyUsername}:Props) =>
}, [text, selection])
- const _handleUserSearch = async (username) => {
+
+ const _handleUserSearch = debounce(async (username) => {
let users = [];
if (username) {
- users = await searchAccount(username, 5);
+ users = await lookupAccounts(username);
console.log('result users', users);
}
setSearchedUsers(users);
- };
+ }, 500);
+
+
const _onUserSelect = (username) => {
onApplyUsername(username)
@@ -62,16 +66,15 @@ export const UsernameAutofillBar = ({text, selection, onApplyUsername}:Props) =>
)
}
- const usernames = searchedUsers.map(user=>user.name)
-
return (
`searched-user-${item}`}
/>
)
From 65b6634f74625e2e963aba38881cfcddb16ed9b9 Mon Sep 17 00:00:00 2001
From: noumantahir
Date: Thu, 27 Jan 2022 20:27:37 +0500
Subject: [PATCH 21/23] improved show hide behaviour
---
.../markdownEditor/view/usernameAutofillBar.tsx | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/src/components/markdownEditor/view/usernameAutofillBar.tsx b/src/components/markdownEditor/view/usernameAutofillBar.tsx
index 30c1660b7..cf2c1f4dd 100644
--- a/src/components/markdownEditor/view/usernameAutofillBar.tsx
+++ b/src/components/markdownEditor/view/usernameAutofillBar.tsx
@@ -18,6 +18,7 @@ interface Props {
export const UsernameAutofillBar = ({text, selection, onApplyUsername}:Props) => {
const [searchedUsers, setSearchedUsers] = useState([])
+ const [query, setQuery] = useState('');
useEffect(() => {
if (selection.start === selection.end && text) {
@@ -27,6 +28,7 @@ export const UsernameAutofillBar = ({text, selection, onApplyUsername}:Props) =>
_handleUserSearch(word.substring(1));
} else {
setSearchedUsers([]);
+ setQuery('')
}
}
}, [text, selection])
@@ -34,22 +36,27 @@ export const UsernameAutofillBar = ({text, selection, onApplyUsername}:Props) =>
const _handleUserSearch = debounce(async (username) => {
+ if(query !== username){
let users = [];
if (username) {
+ setQuery(username)
users = await lookupAccounts(username);
- console.log('result users', users);
+ console.log('result users for', username, users);
}
setSearchedUsers(users);
+ }
+
}, 500);
-
+
const _onUserSelect = (username) => {
onApplyUsername(username)
setSearchedUsers([]);
+ setQuery('')
};
- if(!searchedUsers || searchedUsers.length === 0){
+ if(!searchedUsers || searchedUsers.length === 0 || query === ''){
return null;
}
From 14b56ac576303ce6b6ee0559aa4b3d3a250da4d4 Mon Sep 17 00:00:00 2001
From: feruz
Date: Thu, 27 Jan 2022 21:16:06 +0200
Subject: [PATCH 22/23] bump version
---
android/app/build.gradle | 2 +-
ios/Ecency-tvOS/Info.plist | 4 ++--
ios/Ecency-tvOSTests/Info.plist | 4 ++--
ios/Ecency.xcodeproj/project.pbxproj | 4 ++--
ios/Ecency/Info.plist | 2 +-
ios/EcencyTests/Info.plist | 4 ++--
ios/eshare/Info.plist | 4 ++--
package.json | 4 ++--
8 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/android/app/build.gradle b/android/app/build.gradle
index af230d579..501cbad02 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -144,7 +144,7 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode versionMajor * 10000 + versionMinor * 100 + versionPatch
- versionName "3.0.25"
+ versionName "3.0.26"
resValue "string", "build_config_package", "app.esteem.mobile.android"
multiDexEnabled true
// react-native-image-crop-picker
diff --git a/ios/Ecency-tvOS/Info.plist b/ios/Ecency-tvOS/Info.plist
index 657cc0ea6..06f4cd14d 100644
--- a/ios/Ecency-tvOS/Info.plist
+++ b/ios/Ecency-tvOS/Info.plist
@@ -15,11 +15,11 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 3.0.25
+ 3.0.26
CFBundleSignature
????
CFBundleVersion
- 2804
+ 2805
LSRequiresIPhoneOS
NSAppTransportSecurity
diff --git a/ios/Ecency-tvOSTests/Info.plist b/ios/Ecency-tvOSTests/Info.plist
index 7eff350a0..ae8a18efd 100644
--- a/ios/Ecency-tvOSTests/Info.plist
+++ b/ios/Ecency-tvOSTests/Info.plist
@@ -15,10 +15,10 @@
CFBundlePackageType
BNDL
CFBundleShortVersionString
- 3.0.25
+ 3.0.26
CFBundleSignature
????
CFBundleVersion
- 2804
+ 2805
diff --git a/ios/Ecency.xcodeproj/project.pbxproj b/ios/Ecency.xcodeproj/project.pbxproj
index 06168e721..c5d32ac9b 100644
--- a/ios/Ecency.xcodeproj/project.pbxproj
+++ b/ios/Ecency.xcodeproj/project.pbxproj
@@ -1129,7 +1129,7 @@
CODE_SIGN_IDENTITY = "iPhone Distribution";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
- CURRENT_PROJECT_VERSION = 2804;
+ CURRENT_PROJECT_VERSION = 2805;
DEAD_CODE_STRIPPING = NO;
DEVELOPMENT_TEAM = 75B6RXTKGT;
EXCLUDED_ARCHS = "";
@@ -1208,7 +1208,7 @@
CODE_SIGN_ENTITLEMENTS = Ecency/Ecency.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
- CURRENT_PROJECT_VERSION = 2804;
+ CURRENT_PROJECT_VERSION = 2805;
DEAD_CODE_STRIPPING = NO;
DEVELOPMENT_TEAM = 75B6RXTKGT;
EXCLUDED_ARCHS = "";
diff --git a/ios/Ecency/Info.plist b/ios/Ecency/Info.plist
index 24165baf0..6296cf446 100644
--- a/ios/Ecency/Info.plist
+++ b/ios/Ecency/Info.plist
@@ -17,7 +17,7 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 3.0.25
+ 3.0.26
CFBundleSignature
????
CFBundleURLTypes
diff --git a/ios/EcencyTests/Info.plist b/ios/EcencyTests/Info.plist
index f275b8316..6c797b853 100644
--- a/ios/EcencyTests/Info.plist
+++ b/ios/EcencyTests/Info.plist
@@ -15,10 +15,10 @@
CFBundlePackageType
BNDL
CFBundleShortVersionString
- 3.0.25
+ 3.0.26
CFBundleSignature
????
CFBundleVersion
- 2804
+ 2805
diff --git a/ios/eshare/Info.plist b/ios/eshare/Info.plist
index 026af48ff..499823f0f 100644
--- a/ios/eshare/Info.plist
+++ b/ios/eshare/Info.plist
@@ -17,9 +17,9 @@
CFBundlePackageType
$(PRODUCT_BUNDLE_PACKAGE_TYPE)
CFBundleShortVersionString
- 3.0.25
+ 3.0.26
CFBundleVersion
- 2804
+ 2805
NSExtension
NSExtensionAttributes
diff --git a/package.json b/package.json
index 8ebc9f0ed..0233d7dd4 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "ecency",
- "version": "3.0.25",
+ "version": "3.0.26",
"displayName": "Ecency",
"private": true,
"rnpm": {
@@ -18,7 +18,7 @@
"test": "node node_modules/jest/bin/jest.js --watch",
"lint": "eslint src/",
"lint:fix": "eslint src/ --fix",
- "format": "prettier --write 'src/**/*.{js,jsx}' && yarn lint:fix --fix",
+ "format": "prettier --write 'src/**/*.{js,jsx,ts,tsx}' && yarn lint:fix --fix",
"lint-staged": "lint-staged",
"clear": "watchman watch-del-all && rm -rf $TMPDIR/react-native-packager-cache-* && rm -rf $TMPDIR/metro-bundler-cache-* && rm -rf node_modules/ && yarn && yarn start -- --reset-cache",
"bump-patch": "npm version patch --no-git-tag-version",
From ef521f5210b3d48cc71a66012c8dd715b83b3d98 Mon Sep 17 00:00:00 2001
From: noumantahir
Date: Fri, 28 Jan 2022 20:11:48 +0500
Subject: [PATCH 23/23] reduced debounce interval to 200 ms
---
src/components/markdownEditor/view/usernameAutofillBar.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/markdownEditor/view/usernameAutofillBar.tsx b/src/components/markdownEditor/view/usernameAutofillBar.tsx
index cf2c1f4dd..b2e83227b 100644
--- a/src/components/markdownEditor/view/usernameAutofillBar.tsx
+++ b/src/components/markdownEditor/view/usernameAutofillBar.tsx
@@ -46,7 +46,7 @@ export const UsernameAutofillBar = ({text, selection, onApplyUsername}:Props) =>
setSearchedUsers(users);
}
- }, 500);
+ }, 200);