diff --git a/.gitignore b/.gitignore
index 4d29575..8a68fa5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,10 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*
+/.idea/.gitignore
+/.idea/d.buzz-blog.iml
+/.idea/inspectionProfiles/Project_Default.xml
+/.idea/modules.xml
+/.idea/vcs.xml
+/.idea/codeStyles/codeStyleConfig.xml
+/.idea/codeStyles/Project.xml
diff --git a/package.json b/package.json
index ff489ec..c9d9fac 100644
--- a/package.json
+++ b/package.json
@@ -20,7 +20,6 @@
"crypto-js": "^4.0.0",
"diff-match-patch": "^1.0.5",
"emoji-mart": "^3.0.1",
- "react-giphy-searchbox": "^1.5.4",
"heic2any": "^0.0.4",
"immutable": "^4.0.0-rc.12",
"lottie-react": "^2.1.0",
@@ -36,6 +35,7 @@
"react-dnd-html5-backend": "^3.0.2",
"react-dom": "^16.13.1",
"react-fastclick": "^3.0.2",
+ "react-giphy-searchbox": "^1.5.4",
"react-helmet": "^6.1.0",
"react-icons": "^4.2.0",
"react-infinite-scroll-component": "^6.0.0",
@@ -50,6 +50,7 @@
"react-router-dom": "^5.2.0",
"react-router-last-location": "^2.0.1",
"react-scripts": "^3.4.3",
+ "react-social-media-embed": "^2.5.9",
"react-sticky": "^6.0.3",
"react-tag-input": "^6.2.1",
"react-textarea-autosize": "^8.3.0",
diff --git a/src/components/common/MarkdownViewer/index.js b/src/components/common/MarkdownViewer/index.js
index 05fe980..26fcb81 100644
--- a/src/components/common/MarkdownViewer/index.js
+++ b/src/components/common/MarkdownViewer/index.js
@@ -3,9 +3,14 @@ import { DefaultRenderer } from 'steem-content-renderer'
import markdownLinkExtractor from 'markdown-link-extractor'
import textParser from 'npm-text-parser'
import classNames from 'classnames'
-import { UrlVideoEmbed, TweetSkeleton } from 'components'
+import {
+ UrlWithImageAndVideoEmbed,
+ TweetSkeleton,
+} from 'components'
import { createUseStyles } from 'react-jss'
import { TwitterTweetEmbed } from 'react-twitter-embed'
+import { parseUrls, generateUniqueId } from 'services/helper'
+import { FacebookEmbed, TikTokEmbed } from "react-social-media-embed"
const renderer = new DefaultRenderer({
baseUrl: "https://blog.d.buzz/",
@@ -121,51 +126,27 @@ const useStyles = createUseStyles(theme => ({
const prepareTwitterEmbeds = (content) => {
let body = content
- const mainTwitterRegex = /(?:https?:\/\/(?:(?:twitter\.com\/(.*?)\/status\/(.*))))/i
- const htmlReplacement = /
]*?>]*?>(.*?)<\/p>.*?mdash; (.*)(.*?)<\/a><\/blockquote>/i
-
const links = textParser.getUrls(content)
- const matchData = content.match(htmlReplacement)
- if (matchData) {
- const id = matchData[5]
- let title = body
- title = title.replace(htmlReplacement, '')
- body = body.replace(body, `~~~~~~.^.~~~:twitter:${id}:~~~~~~.^.~~~`)
- body = `${title} ${body}`
- } else {
- links.forEach((link) => {
- try {
- link = link.replace(/&/g, '&')
- let match = ''
- let id = ''
-
- if (link.match(mainTwitterRegex)) {
- match = link.match(mainTwitterRegex)
- id = match[2]
- if (link.match(/(?:https?:\/\/(?:(?:twitter\.com\/(.*?)\/status\/(.*)?=(.*))))/i)) {
- match = link.match(/(?:https?:\/\/(?:(?:twitter\.com\/(.*?)\/status\/(.*)?=(.*))))/i)
- id = match[2]
- id = id.slice(0, -2)
- }
- body = body.replace(link, `~~~~~~.^.~~~:twitter:${id}:~~~~~~.^.~~~`)
- }
-
- if (match) {
- const id = match[2]
- body = body.replace(link, `~~~~~~.^.~~~:twitter:${id}:~~~~~~.^.~~~`)
- }
- } catch (e) { }
- })
- }
+ links.forEach((link) => {
+ try {
+ // Use a regular expression to extract the numeric identifier
+ const match = link.match(/\/status\/(\d+)/)
+ console.log('prepareTwitterEmbeds', match)
+ if (match) {
+ const id = match[1]
+ body = body.replace(link, `~~~~~~.^.~~~:twitter:${id}:~~~~~~.^.~~~`)
+ }
+ } catch (e) { }
+ })
return body
}
const prepareVimmEmbeds = (content) => {
- const vimmRegex = /(?:https?:\/\/(?:(?:www\.vimm\.tv\/(.*?))))/i
- const vimmRegexEmbed = /(?:https?:\/\/(?:(?:www\.vimm\.tv\/(.*?)\/embed)))/i
+ const vimmRegex = /https?:\/\/www\.vimm\.tv\/(.*?)/i
+ const vimmRegexEmbed = /https?:\/\/www\.vimm\.tv\/(.*?)\/embed/i
let body = content
const links = textParser.getUrls(content)
@@ -195,32 +176,42 @@ const prepareVimmEmbeds = (content) => {
}
const prepareThreeSpeakEmbeds = (content) => {
- let body = content
+ try {
+ const link = (/\[!\[.*]\(.*\)]\(.*\)/).exec(content)
+
+ // check if there is hyperlink with embedded image
+ if (link) {
+ const linkRegex = /\[!\[(.*?)]\((.*?)\)]\((.*?)\)/
+ const bodyMatch = content.match(linkRegex)
+ const [wholeLink, , , videoLink] = bodyMatch
+ const platformMatch = videoLink.match(/(?:https?:\/\/(?:3speak\.online|3speak\.co|3speak\.tv)\/watch\?v=(.*))?/i)
+
+ if (platformMatch) {
+ console.log('platformMatch', platformMatch)
+ const id = platformMatch[1]
+ return content.replace(wholeLink, `~~~~~~.^.~~~:threespeak:${id}:~~~~~~.^.~~~`)
+ }
+ } else { // this should filter all the hyperlink and normal link
+ const plainTextRegex = /https?:\/\/(?:3speak\.online|3speak\.co|3speak\.tv)\/watch\?v=([^\s()]+)/i
+ const plainTextMatch = content.match(plainTextRegex)
- const links = markdownLinkExtractor(content)
+ if (plainTextMatch[0] === plainTextMatch.input) {
+ console.log('plainTextMatches', plainTextMatch)
- links.forEach((link) => {
- try {
- link = link.replace(/&/g, '&')
- let match = ''
- if (link.includes('3speak.online/watch?v')) {
- match = link.match(/(?:https?:\/\/(?:(?:3speak\.online\/watch\?v=(.*))))?/i)
- } else if (link.includes('3speak.co/watch?v')) {
- match = link.match(/(?:https?:\/\/(?:(?:3speak\.co\/watch\?v=(.*))))?/i)
+ if (plainTextMatch) {
+ const id = plainTextMatch[1]
+ return content.replace(plainTextRegex, `~~~~~~.^.~~~:threespeak:${id}:~~~~~~.^.~~~`)
+ }
}
+ }
+ } catch (error) {}
- if (match) {
- const id = match[1]
- body = body.replace(link, `~~~~~~.^.~~~:threespeak:${id}:~~~~~~.^.~~~`)
- }
- } catch (error) { }
- })
- return body
+ return content
}
const prepareRumbleEmbed = (content) => {
- const rumbleRegex = /(?:https?:\/\/(?:(?:rumble\.com\/(.*?))))/i
- const rumbleRegexEmbed = /(?:https?:\/\/(?:(?:rumble\.com\/embed\/(.*?))))/i
+ const rumbleRegex = /https?:\/\/rumble\.com\/(.*?)/i
+ const rumbleRegexEmbed = /https?:\/\/rumble\.com\/embed\/(.*?)/i
let body = content
const links = textParser.getUrls(content)
@@ -251,6 +242,7 @@ const prepareRumbleEmbed = (content) => {
}
} catch (error) { }
})
+
return body
}
@@ -328,50 +320,281 @@ const prepareBitchuteEmbeds = (content) => {
return body
}
+const prepareBannedEmbeds = (content) => {
+ const bannedRegex = /https?:\/\/banned\.video\/watch\?id=(.*)/i
+
+ let body = content
+
+ const links = parseUrls(content)
+
+ links.forEach((link) => {
+ try {
+ link = link.replace(/&/g, '&')
+ let match = ''
+ let id = ''
+
+ if (link.match(bannedRegex)) {
+ const data = link.split('?id=')
+ match = link.match(bannedRegex)
+ if (data[1]) {
+ id = data[1]
+ }
+ }
+
+ if (match) {
+ body = body.replace(link, `~~~~~~.^.~~~:banned:${id}:~~~~~~.^.~~~`)
+ }
+ } catch (error) { }
+ })
+
+ return body
+}
+
+const prepareDollarVigilanteEmbeds = (content) => {
+ const dollarVigilanteRegex = /https?:\/\/(www\.)?vigilante\.tv\/w\/(.*)/i
+
+ let body = content
+
+ const links = parseUrls(content)
+ links.forEach((link) => {
+ try {
+ link = link.replace(/&/g, '&')
+ let match = ''
+ let id = ''
+
+ if (link.match(dollarVigilanteRegex)) {
+ const data = link.split('/')
+ match = link.match(dollarVigilanteRegex)
+ if (data[4]) {
+ id = data[4]
+ }
+ }
+
+ if (match) {
+ body = body.replace(link, `~~~~~~.^.~~~:dollarvigilante:${id}:~~~~~~.^.~~~`)
+ }
+ } catch (error) { }
+ })
+
+ return body
+}
+
+const prepareSoundCloudEmbeds = (content) => {
+ const soundcloudRegex = /^https?:\/\/(soundcloud\.com|snd\.sc)\/(.*)$/
+ let body = content
+
+ const links = parseUrls(content)
+
+ links.forEach((link) => {
+ link = link.replace(/&/g, '&')
+ let match = ''
+ let id = ''
+
+ try {
+ if (link.match(soundcloudRegex)) {
+ const data = link.split('/')
+ match = link.match(soundcloudRegex)
+ id = `${data[3]}/${data[4]}`
+ }
+
+ if (!id) {
+ id = ''
+ }
+
+ if (match) {
+ body = body.replace(link, `~~~~~~.^.~~~:soundcloud:${id}:~~~~~~.^.~~~`)
+ }
+ } catch (error) { }
+ })
+
+ return body
+}
+
+const prepareFacebookEmbeds = (content) => {
+ let body = content
+
+ const links = parseUrls(content)
+
+ links.forEach((link) => {
+ try {
+ body = body.replace(link, `~~~~~~.^.~~~:facebook:${link}:~~~~~~.^.~~~`)
+ } catch (error) { }
+ })
+
+ return body
+}
+
+const prepareTiktokEmbeds = (content) => {
+ let body = content
+ const links = parseUrls(content)
+
+ links.forEach((link) => {
+ body = body.replace(link, `~~~~~~.^.~~~:tiktok:${link}:~~~~~~.^.~~~`)
+ })
+
+ return body
+}
+
+const prepareOdyseeEmbeds = (content) => {
+ const odyseeRegex = /^https:\/\/odysee\.com\/@([^/]+)\/([^:]+:\w+)/
+ let body = content
+
+ const links = parseUrls(content)
+
+ links.forEach((link) => {
+ try {
+ const match = link.match(odyseeRegex)
+
+ if (match) {
+ const id = `@${match[1]}/${match[2]}`
+ const modifiedString = id.replace(/:/g, "=====")
+ body = body.replace(link, `~~~~~~.^.~~~:odysee:${modifiedString}~~~~~~.^.~~~`)
+ }
+ } catch (error) { }
+ })
+
+ return body
+}
+
+const prepareDTubeEmbeds = (content) => {
+ const dtubeEmbedRegex = /^(https?:\/\/)?(?:www\.)?(emb\.)?d\.tube\/v\/.*\/[a-zA-Z0-9-]+/gi
+ const dtubeVideoRegex = /^(https?:\/\/)?(?:www\.)?(d\.tube)\/#!\/v\/.*\/[a-zA-Z0-9-]+/gi
+ let body = content
+
+ const links = parseUrls(content)
+
+ links.forEach((link) => {
+ link = link.replace(/&/g, '&')
+ const matchEmbed = link.match(dtubeEmbedRegex)
+ const matchVideo = link.match(dtubeVideoRegex)
+
+ if (matchEmbed) {
+ const data = link.split('/')
+ const id = link.includes('http') ? `${data[4]}/${data[5]}` : `${data[2]}/${data[3]}`
+ body = body.replace(link, `~~~~~~.^.~~~:dtube:${id}:~~~~~~.^.~~~`)
+
+ } else if (matchVideo) {
+ const data = link.split('/')
+ const id = link.includes('http') ? `${data[5]}/${data[6]}` : `${data[3]}/${data[4]}`
+ body = body.replace(link, `~~~~~~.^.~~~:dtube:${id}:~~~~~~.^.~~~`)
+ }
+ })
+
+ return body
+}
+
+const prepareAppleEmbeds = (content) => {
+ const appleRegex = /https?:\/\/music\.apple\.com\/(.*?)/i
+ const appleRegexEmbed = /https?:\/\/embed\.music\.apple\.com\/(.*?)/i
+ let body = content
+
+ const links = parseUrls(content)
+
+ links.forEach((link) => {
+ link = link.replace(/&/g, '&')
+
+ const match = link.match(appleRegex) || link.match(appleRegexEmbed)
+
+ if (match) {
+ const data = link.split('/')
+ const id = `${data[4]}/${data[5]}/${data[6]}`
+ body = body.replace(link, `~~~~~~.^.~~~:apple:${id}:~~~~~~.^.~~~`)
+ }
+ })
+
+ return body
+}
+
+const prepareDBuzzVideos = (content) => {
+ const oldDbuzzVideos = /https:\/\/ipfs\.io\/ipfs\/(.*\?dbuzz_video)/i
+ const dbuzzVideos = /https:\/\/ipfs\.io\/ipfs\/.*\?dbuzz_video=https:\/\/ipfs\.io\/ipfs\/([a-zA-Z0-9]+)/i
+ let body = content
+
+ const links = parseUrls(content)
+
+ links.forEach((link) => {
+ link = link.replace(/&/g, '&')
+
+ let match
+
+ if (link.match(oldDbuzzVideos) && link.match(dbuzzVideos)) {
+ match = link.match(dbuzzVideos)[1]
+ } else if (link.match(oldDbuzzVideos) && !link.match(dbuzzVideos)) {
+ match = link.match(oldDbuzzVideos)[1].replace('?dbuzz_video', '')
+ }
+
+ if (match) {
+ const id = match
+ body = body.replace(link, `~~~~~~.^.~~~:dbuzz-video:${id}:~~~~~~.^.~~~`)
+ }
+ })
+
+ return body
+}
+
const render = (content, markdownClass, assetClass, scrollIndex, recomputeRowIndex) => {
+ const splitContent = content.split(':')
+ const embedTypes = [
+ ':threespeak:',
+ ':vimm:',
+ ':rumble:',
+ ':lbry:',
+ ':bitchute:',
+ ':banned:',
+ ':dollarvigilante:',
+ ':soundcloud:',
+ // ':facebook:',
+ // ':tiktok:',
+ // :twitter:,
+ ':odysee:',
+ ':dtube:',
+ ':apple:',
+ ':dbuzz-video:',
+ ]
if (content.includes(':twitter:')) {
- const splitTwitter = content.split(':')
try {
- return recomputeRowIndex(scrollIndex)} placeholder={} />
- } catch (e) { console.log(e) }
- } else if (content.includes(':threespeak:')) {
- const splitThreeSpeak = content.split(':')
- const url = `https://3speak.co/embed?v=${splitThreeSpeak[2]}`
- return
- } else if (content.includes(':vimm:')) {
- const splitVimm = content.split(':')
- const url = `https://www.vimm.tv/${splitVimm[2]}/embed?autoplay=0`
- return
- } else if (content.includes(':rumble:')) {
- const splitRumble = content.split(':')
- if (splitRumble[2]) {
- const url = `https://rumble.com/embed/${splitRumble[2]}`
- return
+ return (
+ recomputeRowIndex(scrollIndex)}
+ placeholder={}
+ />
+ )
+ } catch (e) {
+ console.log(e)
}
- } else if (content.includes(':lbry:')) {
- const splitLbry = content.split(':')
- const url = `https://lbry.tv/$/embed/${splitLbry[2]}`
- return
- } else if (content.includes(':bitchute:')) {
- const splitBitchute = content.split(':')
- const url = `https://www.bitchute.com/embed/${splitBitchute[2]}`
- return
} else if (content.includes(':facebook:')) {
- const splitFacebook = content.split(':')
- const url = splitFacebook[4] ? `https:${splitFacebook[3]}` : `https://www.facebook.com/plugins/video.php?href=https%3A%2F%2Fwww.facebook.com%2F${splitFacebook[2]}%2Fvideos%2F${splitFacebook[3]}&width=500&show_text=false&height=300`
- return
+ return
+ } else if (content.includes(':tiktok:')) {
+ return
+ } else if (embedTypes.some(type => content.includes(type))) {
+ const embed = {
+ app: splitContent[1],
+ id: splitContent[2],
+ domain: '',
+ }
+ return
} else {
// render normally
- return
+ return (
+
+ )
}
-
}
+
const MarkdownViewer = React.memo((props) => {
const classes = useStyles()
const {
@@ -379,28 +602,7 @@ const MarkdownViewer = React.memo((props) => {
scrollIndex = -1,
recomputeRowIndex = () => { },
} = props
- let { content = '' } = props
- const links = textParser.getUrls(content)
-
- links.forEach((link) => {
- try {
- link = link.replace(/&/g, '&')
-
- if (link.includes('twitter.com')) {
- content = prepareTwitterEmbeds(content)
- } else if (link.includes('3speak.co') || link.includes('3speak.online')) {
- content = prepareThreeSpeakEmbeds(content)
- } else if (link.includes('www.vimm.tv')) {
- content = prepareVimmEmbeds(content)
- } else if (link.includes('rumble.com')) {
- content = prepareRumbleEmbed(content)
- } else if (link.includes('lbry.tv') || link.includes('open.lbry.com')) {
- content = prepareLbryEmbeds(content)
- } else if (link.includes('www.bitchute.com')) {
- content = prepareBitchuteEmbeds(content)
- }
- } catch (error) { }
- })
+ const { content = '' } = props
let assetClass = classes.minified
@@ -408,9 +610,54 @@ const MarkdownViewer = React.memo((props) => {
assetClass = classes.full
}
+ let splitContent = content.split(`\n`)
+
+ splitContent = splitContent.map((item, index) => {
+ if (item.includes('twitter.com') || item.includes('x.com')) {
+ item = prepareTwitterEmbeds(item)
+ } else if (item.includes('3speak.co') || item.includes('3speak.online') || item.includes('3speak.tv')) {
+ item = prepareThreeSpeakEmbeds(item)
+ // } else if (item.includes('vimm.tv') || item.includes('Vimm.tv')) {
+ // item = prepareVimmEmbeds(item)
+ } else if (item.includes('rumble.com')) {
+ item = prepareRumbleEmbed(item)
+ // } else if (item.includes('lbry.tv') || item.includes('open.lbry.com')) {
+ // item = prepareLbryEmbeds(item)
+ } else if (item.includes('bitchute.com')) {
+ item = prepareBitchuteEmbeds(item)
+ } else if (item.includes('banned.video')) {
+ item = prepareBannedEmbeds(item)
+ } else if (item.includes('vigilante.tv')) {
+ item = prepareDollarVigilanteEmbeds(item)
+ } else if (item.includes('soundcloud.com')) {
+ item = prepareSoundCloudEmbeds(item)
+ } else if (item.includes('facebook.com') || item.includes('fb.watch')) {
+ item = prepareFacebookEmbeds(item)
+ } else if (item.includes('tiktok.com')) {
+ item = prepareTiktokEmbeds(item)
+ } else if (item.includes('odysee.com') || item.includes('lbry.tv') || item.includes('open.lbry.com')) {
+ item = prepareOdyseeEmbeds(item)
+ } else if (item.includes('music.apple.com')) {
+ item = prepareAppleEmbeds(item)
+ } else if (item.includes('d.tube')) {
+ item = prepareDTubeEmbeds(item)
+ } else if (item.includes('dbuzz_video')) {
+ item = prepareDBuzzVideos(item)
+ // } else if (hiveTubePattern.test(link)) {
+ // item = prepareHiveTubeVideoEmbeds(item)
+ // } else if (buzzImagesPattern.test(link)) {
+ // item = prepareBuzzImages(item)
+ }
+
+ return item
+ })
+
+ const combinedString = splitContent.join('\n')
- let splitContent = content.split(`~~~~~~.^.~~~`)
+ console.log('splitContent', splitContent)
+ console.log('combinedString', combinedString)
+ splitContent = combinedString.split(`~~~~~~.^.~~~`)
splitContent = splitContent.filter((item) => item !== '')
return (
diff --git a/src/components/common/UrlWithImageAndVideoEmbed/index.js b/src/components/common/UrlWithImageAndVideoEmbed/index.js
new file mode 100644
index 0000000..c89bb1b
--- /dev/null
+++ b/src/components/common/UrlWithImageAndVideoEmbed/index.js
@@ -0,0 +1,94 @@
+import React from 'react'
+import { createUseStyles } from 'react-jss'
+
+const useStyles = createUseStyles({
+ videoWrapper: {
+ marginTop: 26,
+ position: 'relative',
+ paddingBottom: '56.25%',
+ height: 0,
+ '& iframe': {
+ animation: 'skeleton-loading 1s linear infinite alternate',
+ position: 'absolute',
+ top: 0,
+ left: 0,
+ width: '100%',
+ height: '100%',
+ },
+ },
+})
+
+const FACEBOOK_APP_ID = 236880454857514
+
+const UrlWithImageAndVideoEmbed = (props) => {
+ const classes = useStyles()
+ const { embed } = props
+ const { app, id, domain } = embed || { app: '', id: '', domain: '' }
+
+ console.log('UrlWithImageAndVideoEmbed', props)
+
+ const getEmbedUrl = () => {
+ if(embed) {
+ switch (app) {
+ case 'youtube':
+ return `https://www.youtube.com/embed/${id}`
+ case 'vimm':
+ return `https://www.vimm.tv/${id}/embed?autoplay=0`
+ case 'threespeak':
+ return `//3speak.tv/embed?v=${id}`
+ case 'rumble':
+ return `https://rumble.com/embed/${id}`
+ case 'lbry':
+ return `https://lbry.tv/$/embed/${id}`
+ case 'bitchute':
+ return `https://www.bitchute.com/embed/${id}`
+ case 'banned':
+ return `https://api.banned.video/embed/${id}`
+ case 'dollarvigilante':
+ return `https://vigilante.tv/videos/embed/${id}`
+ case 'dapplr':
+ return `https://cdn.dapplr.in/file/dapplr-videos/${id}`
+ case 'freeworldnews':
+ return `https://api.banned.video/embed/${id}`
+ case 'dbuzz-video':
+ return `https://ipfs.io/ipfs/${id}`
+ case 'hive-tube-embed':
+ return `https://${domain}/videos/embed/${id}`
+ case 'facebook':
+ return `https://www.facebook.com/plugins/video.php?href=https%3A%2F%2Fwww.facebook.com%2Ffacebook%2Fvideos%2F${id}%2F&width=500&show_text=false&appId=${FACEBOOK_APP_ID}&height=360`
+ case 'tiktok':
+ return `https://www.tiktok.com/embed/v2/${id}?lang=en-US`
+ case 'odysee':
+ return `https://odysee.com/$/embed/${id.replace(/=====/g, ":")}`
+ case 'apple':
+ return `https://embed.music.apple.com/gb/${id}`
+ case 'dtube':
+ return `https://emb.d.tube/#!/${id}`
+ default:
+ return null
+ }
+ }
+ }
+
+ return (
+
+
+
+
+
+
+
+ )
+}
+
+export default UrlWithImageAndVideoEmbed
diff --git a/src/services/helper.js b/src/services/helper.js
index f936205..268ee2a 100644
--- a/src/services/helper.js
+++ b/src/services/helper.js
@@ -1,10 +1,10 @@
-import { useState, useEffect } from 'react'
+import {useEffect, useState} from 'react'
import uuid from 'uuid-random'
-import { encrypt, decrypt } from 'caesar-shift'
-import CryptoJS from 'crypto-js'
+import {decrypt, encrypt} from 'caesar-shift'
+import CryptoJS from 'crypto-js'
import sha256 from 'crypto-js/sha256'
-import { Remarkable } from 'remarkable'
-import { DefaultRenderer } from 'steem-content-renderer'
+import {Remarkable} from 'remarkable'
+import {DefaultRenderer} from 'steem-content-renderer'
import markdownLinkExtractor from 'markdown-link-extractor'
import diff_match_patch from 'diff-match-patch'
import sanitize from 'sanitize-html'
@@ -17,7 +17,7 @@ export const getUrls = (text) => {
}
export const calculateOverhead = (content) => {
let urls = getUrls(content) || []
-
+
const markdown = content?.match(/#+\s|[*]|\s+ +\s|\s+$/gm) || []
let overhead = 0
@@ -30,11 +30,11 @@ export const calculateOverhead = (content) => {
overhead += item.length
})
}
-
+
if((urls.length) > 3) {
urls = urls.slice(0, 2)
}
-
+
if(urls && urls.length <= 3){
urls.forEach((item) => {
// overheadItems.push(item)
@@ -176,7 +176,7 @@ export const extractVideoLinks = (links) => {
if (tempLink.includes('&')) {
splitLink[1] = (tempLink.split('&'))[0]
}
-
+
videoLinks.push({ link, type: 'youtube', id: splitLink[1] })
}
} else if (link.includes('3speak.online')) {
@@ -193,18 +193,18 @@ export const extractImageLinks = (links) => {
const imageLinks = []
links.forEach((link) => {
- if ((link.includes('.jpg')
+ if ((link.includes('.jpg')
|| link.includes('.png')
|| link.includes('.JPEG')
- || link.includes('youtu.be')
- || link.includes('youtube'))
+ || link.includes('youtu.be')
+ || link.includes('youtube'))
&& !link.includes('img.3speakcontent.online')) {
if (link.includes('youtube')) {
const splitLink = link.includes('youtu.be') ? link.split('be/') : link.split('v=')
link = `https://img.youtube.com/vi/${splitLink[1]}/hqdefault.jpg`
- }
-
+ }
+
imageLinks.push(link)
}
})
@@ -219,7 +219,7 @@ const prepareImages = (content) => {
// remove 3speak thumbnails
if((item.includes('.png') && item.includes('img.3speakcontent.online')) && !item.includes('https://images.hive.blog')) {
splitContent[index] = ''
- }
+ }
})
return splitContent.join(' ')
}
@@ -244,7 +244,7 @@ const prepareEmbeds = (content) => {
idToFormat = idToFormat.replace(/\)/g, '')
idToFormat = idToFormat.replace('[Watch on', '')
idToFormat = idToFormat.trim('')
-
+
const videoLink = `https://3speak.online/embed?v=${idToFormat}`
if(!visited.includes(videoLink)) {
@@ -287,7 +287,7 @@ const render = (content) => {
height='400'
width='100%'
loading='lazy'
- >`
+ >`
} else {
contentBody = renderer.render(item)
}
@@ -581,6 +581,12 @@ export const truncateString = (str, num) => {
}
}
+export const generateUniqueId = () => {
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
+ const r = (Math.random() * 16) | 0
+ return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16)
+ })
+}
export const proxyImage = (url) => {
// const enabled = true
@@ -622,4 +628,4 @@ export const getTheme =() => {
}
return mode
-}
\ No newline at end of file
+}
diff --git a/yarn.lock b/yarn.lock
index a63ac1b..c2233a3 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2691,6 +2691,11 @@
dependencies:
"@types/yargs-parser" "*"
+"@types/youtube-player@^5.5.5":
+ version "5.5.11"
+ resolved "https://registry.yarnpkg.com/@types/youtube-player/-/youtube-player-5.5.11.tgz#cc297e27151db946596d92fb7cfb837627e83be0"
+ integrity sha512-pM41CDBqJqBmTeJWnF7NOGz82IQoYOhqzMYXv5vKCXBqGiYSLldxMtpCk6KAEtADTy49S45AriYaCaZyeUX38Q==
+
"@typescript-eslint/eslint-plugin@^2.10.0":
version "2.34.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz#6f8ce8a46c7dea4a6f1d171d2bb8fbae6dac2be9"
@@ -3862,6 +3867,13 @@ braces@~3.0.2:
dependencies:
fill-range "^7.0.1"
+bricks.js@^1.8.0:
+ version "1.8.0"
+ resolved "https://registry.yarnpkg.com/bricks.js/-/bricks.js-1.8.0.tgz#8fdeb3c0226af251f4d5727a7df7f9ac0092b4b2"
+ integrity sha512-XJsIGxoixpMDo/KoLXR+uQizFVGWNAQy1lLoIwXKxm6/Zpd9QQLSUd0otybbK7wjqX23ZvCXFxnIw+uCXJHo0A==
+ dependencies:
+ knot.js "^1.1.5"
+
brorand@^1.0.1, brorand@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
@@ -4393,6 +4405,11 @@ classnames@^2.2.1, classnames@^2.2.6, classnames@^2.3.1, classnames@~2.3.1:
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924"
integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==
+classnames@^2.5.1:
+ version "2.5.1"
+ resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b"
+ integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==
+
clean-css@^4.2.3:
version "4.2.4"
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.4.tgz#733bf46eba4e607c6891ea57c24a989356831178"
@@ -5234,7 +5251,7 @@ data-urls@^1.0.0, data-urls@^1.1.0:
whatwg-mimetype "^2.2.0"
whatwg-url "^7.0.0"
-debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6.9:
+debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.6, debug@^2.6.8, debug@^2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
@@ -5745,6 +5762,14 @@ elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.3, elliptic@^6.5.4:
minimalistic-assert "^1.0.1"
minimalistic-crypto-utils "^1.0.1"
+emoji-mart@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/emoji-mart/-/emoji-mart-3.0.1.tgz#9ce86706e02aea0506345f98464814a662ca54c6"
+ integrity sha512-sxpmMKxqLvcscu6mFn9ITHeZNkGzIvD0BSNFE/LJESPbCA8s1jM6bCDPjWbV31xHq7JXaxgpHxLB54RCbBZSlg==
+ dependencies:
+ "@babel/runtime" "^7.0.0"
+ prop-types "^15.6.0"
+
emoji-regex@^7.0.1, emoji-regex@^7.0.2:
version "7.0.3"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
@@ -6517,7 +6542,7 @@ fancy-log@^1.3.2:
parse-node-version "^1.0.0"
time-stamp "^1.0.0"
-fast-deep-equal@^3.1.1:
+fast-deep-equal@3.1.3, fast-deep-equal@^3.1.1:
version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
@@ -9293,6 +9318,11 @@ kleur@^3.0.3:
resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==
+knot.js@^1.1.5:
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/knot.js/-/knot.js-1.1.5.tgz#28e72522f703f50fe98812fde224dd72728fef5d"
+ integrity sha512-ptGtvTrgLNtQj9ilUR+tSyHWTCPp2xu/EHkeo3OvpczzNqBSwjQKz8G7vUhzlRbasXVULBWSejsj6QRQb1pakw==
+
last-call-webpack-plugin@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz#9742df0e10e3cf46e5c0381c2de90d3a7a2d7555"
@@ -9415,6 +9445,11 @@ load-json-file@^4.0.0:
pify "^3.0.0"
strip-bom "^3.0.0"
+load-script@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/load-script/-/load-script-1.0.0.tgz#0491939e0bee5643ee494a7e3da3d2bac70c6ca4"
+ integrity sha512-kPEjMFtZvwL9TaZo0uZ2ml+Ye9HUMmPwbYRJ324qF9tqMejwykJ5ggTyvzmrbBeapCAbk98BSbTeovHEEP1uCA==
+
loader-fs-cache@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz#f08657646d607078be2f0a032f8bd69dd6f277d9"
@@ -11759,7 +11794,7 @@ prop-types-extra@^1.1.0:
react-is "^16.3.2"
warning "^4.0.0"
-prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
+prop-types@15.8.1, prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@@ -12097,6 +12132,14 @@ react-fastclick@^3.0.2:
resolved "https://registry.yarnpkg.com/react-fastclick/-/react-fastclick-3.0.2.tgz#2994c60088cda90b0b2cbfac4b6e7c6bc73d6a3a"
integrity sha512-ia0v5WamwSHmGsWaeKVvR79ubjpa5gIxm+ZFqzSbKrZrUfF4t3PF1+cvQzfbSe51muO7VwUHLBW4uu+oGIwEow==
+react-giphy-searchbox@^1.5.4:
+ version "1.5.4"
+ resolved "https://registry.yarnpkg.com/react-giphy-searchbox/-/react-giphy-searchbox-1.5.4.tgz#49c6f98bf1afefbbd3a9ab3c5f79709cb32f399b"
+ integrity sha512-5SCiT3Y/0aeJcFfd3yXwJ1LShmDTTSL/aKJUXu9t0eBvwUU5DSev/JvMx3ijedsWpHuMtkwHLy5jV3pBDdzPQw==
+ dependencies:
+ bricks.js "^1.8.0"
+ react-infinite-scroller "^1.2.4"
+
react-helmet@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/react-helmet/-/react-helmet-6.1.0.tgz#a750d5165cb13cf213e44747502652e794468726"
@@ -12107,6 +12150,11 @@ react-helmet@^6.1.0:
react-fast-compare "^3.1.1"
react-side-effect "^2.1.0"
+react-html-props@^2.0.3:
+ version "2.0.9"
+ resolved "https://registry.yarnpkg.com/react-html-props/-/react-html-props-2.0.9.tgz#0070476137ea0d6141e094b0d32521c173ed2c47"
+ integrity sha512-Q9wIP8hs4HFUb3CDh5tF1nKgZ4S9odU07tR/lZ+/9ePv+psxRy+mUn7ujjrCGwtrLA52AI41fXWr425yK1iyTA==
+
react-icons@^4.2.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.6.0.tgz#f83eda179af5d02c047449a20b702c858653d397"
@@ -12119,6 +12167,13 @@ react-infinite-scroll-component@^6.0.0:
dependencies:
throttle-debounce "^2.1.0"
+react-infinite-scroller@^1.2.4:
+ version "1.2.6"
+ resolved "https://registry.yarnpkg.com/react-infinite-scroller/-/react-infinite-scroller-1.2.6.tgz#8b80233226dc753a597a0eb52621247f49b15f18"
+ integrity sha512-mGdMyOD00YArJ1S1F3TVU9y4fGSfVVl6p5gh/Vt4u99CJOptfVu/q5V/Wlle72TMgYlBwIhbxK5wF0C/R33PXQ==
+ dependencies:
+ prop-types "^15.5.8"
+
react-is@^16.12.0, react-is@^16.13.1, react-is@^16.3.2, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.4, react-is@^16.8.6:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
@@ -12318,6 +12373,18 @@ react-side-effect@^2.1.0:
resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-2.1.2.tgz#dc6345b9e8f9906dc2eeb68700b615e0b4fe752a"
integrity sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw==
+react-social-media-embed@^2.5.9:
+ version "2.5.9"
+ resolved "https://registry.yarnpkg.com/react-social-media-embed/-/react-social-media-embed-2.5.9.tgz#f56ecb6bc27db68430f4ab8ace8426a6317c8f0f"
+ integrity sha512-fbUeEqlTqst0z7DUDvZ5CkQTQ6jXsoP6w144Qh559OryL/DlusXNtIPU3iQPmS37zHthv/RVo1YKp/dislNklw==
+ dependencies:
+ "@types/youtube-player" "^5.5.5"
+ classnames "^2.5.1"
+ react-html-props "^2.0.3"
+ react-sub-unsub "^2.2.1"
+ react-twitter-embed "^4.0.4"
+ react-youtube "^10.1.0"
+
react-sticky@^6.0.3:
version "6.0.3"
resolved "https://registry.yarnpkg.com/react-sticky/-/react-sticky-6.0.3.tgz#7a18b643e1863da113d7f7036118d2a75d9ecde4"
@@ -12326,6 +12393,11 @@ react-sticky@^6.0.3:
prop-types "^15.5.8"
raf "^3.3.0"
+react-sub-unsub@^2.2.1:
+ version "2.2.7"
+ resolved "https://registry.yarnpkg.com/react-sub-unsub/-/react-sub-unsub-2.2.7.tgz#d755ea40ab61ff64bc8c73a9013efa910472629d"
+ integrity sha512-b2o0mIW8G4Yb3aaKxFB9iiCCHxCDGmogy+493oQpEJHjBy/hl6uf+6RhAinqKWRwi1fvO6mGIMVGsf2XYLL38g==
+
react-tag-input@^6.2.1:
version "6.8.1"
resolved "https://registry.yarnpkg.com/react-tag-input/-/react-tag-input-6.8.1.tgz#bbf6e4e0765c0565470cc48a44dc4757c75784b9"
@@ -12374,6 +12446,13 @@ react-twitter-embed@^3.0.3:
react-proptype-conditional-require "^1.0.4"
scriptjs "^2.5.9"
+react-twitter-embed@^4.0.4:
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/react-twitter-embed/-/react-twitter-embed-4.0.4.tgz#4a6b8354acc266876ff1110b9f648518ea20db6d"
+ integrity sha512-2JIL7qF+U62zRzpsh6SZDXNI3hRNVYf5vOZ1WRcMvwKouw+xC00PuFaD0aEp2wlyGaZ+f4x2VvX+uDadFQ3HVA==
+ dependencies:
+ scriptjs "^2.5.9"
+
react-virtualized@^9.18.5:
version "9.22.3"
resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.22.3.tgz#f430f16beb0a42db420dbd4d340403c0de334421"
@@ -12386,6 +12465,15 @@ react-virtualized@^9.18.5:
prop-types "^15.7.2"
react-lifecycles-compat "^3.0.4"
+react-youtube@^10.1.0:
+ version "10.1.0"
+ resolved "https://registry.yarnpkg.com/react-youtube/-/react-youtube-10.1.0.tgz#7e5670c764f12eb408166e8eb438d788dc64e8b5"
+ integrity sha512-ZfGtcVpk0SSZtWCSTYOQKhfx5/1cfyEW1JN/mugGNfAxT3rmVJeMbGpA9+e78yG21ls5nc/5uZJETE3cm3knBg==
+ dependencies:
+ fast-deep-equal "3.1.3"
+ prop-types "15.8.1"
+ youtube-player "5.5.2"
+
react@^16.13.1, react@^16.8.6:
version "16.14.0"
resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d"
@@ -13362,6 +13450,11 @@ simple-swizzle@^0.2.2:
dependencies:
is-arrayish "^0.3.1"
+sister@^3.0.0:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/sister/-/sister-3.0.2.tgz#bb3e39f07b1f75bbe1945f29a27ff1e5a2f26be4"
+ integrity sha512-p19rtTs+NksBRKW9qn0UhZ8/TUI9BPw9lmtHny+Y3TinWlOa9jWh9xB0AtPSdmOy49NJJJSSe0Ey4C7h0TrcYA==
+
sisteransi@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed"
@@ -15763,3 +15856,12 @@ yargs@^7.1.0:
which-module "^1.0.0"
y18n "^3.2.1"
yargs-parser "^5.0.1"
+
+youtube-player@5.5.2:
+ version "5.5.2"
+ resolved "https://registry.yarnpkg.com/youtube-player/-/youtube-player-5.5.2.tgz#052b86b1eabe21ff331095ffffeae285fa7f7cb5"
+ integrity sha512-ZGtsemSpXnDky2AUYWgxjaopgB+shFHgXVpiJFeNB5nWEugpW1KWYDaHKuLqh2b67r24GtP6HoSW5swvf0fFIQ==
+ dependencies:
+ debug "^2.6.6"
+ load-script "^1.0.0"
+ sister "^3.0.0"