Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed odysee embeds bug #730 #773

Merged
merged 13 commits into from
Jun 7, 2021
9 changes: 8 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React from 'react'
import React, { useEffect } from 'react'
import routes from './routes'
import { withRouter } from 'react-router'
import { Init, AuthGuard, ThemeLoader } from 'components'
import { renderRoutes } from 'react-router-config'
import { LastLocationProvider } from 'react-router-last-location'
import { createUseStyles } from 'react-jss'
import { Helmet } from 'react-helmet'
import { redirectToUserProfile } from 'services/helper'

const useStyles = createUseStyles(theme => ({
wrapper: {
Expand All @@ -24,6 +25,12 @@ const AppWrapper = ({ children }) => {
}

const App = () => {

useEffect(() => {
// redirect to user profile if link only contains @username
redirectToUserProfile()
}, [])

return (
<React.Fragment>
<Helmet>
Expand Down
114 changes: 95 additions & 19 deletions src/components/common/MarkdownViewer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ const useStyles = createUseStyles(theme => ({
const prepareTwitterEmbeds = (content) => {
let body = content
const mainTwitterRegex = /(?:https?:\/\/(?:(?:twitter\.com\/(.*?)\/status\/(.*))))/i
const mobileTwitterRegex = /(?:https?:\/\/(?:(?:mobile\.twitter\.com\/(.*?)\/status\/(.*))))/i
const htmlReplacement = /<blockquote[^>]*?><p[^>]*?>(.*?)<\/p>.*?mdash; (.*)<a href="(https:\/\/twitter\.com\/.*?(.*?\/status\/(.*?))\?.*?)">(.*?)<\/a><\/blockquote>/i

const links = textParser.getUrls(content)
Expand Down Expand Up @@ -173,6 +174,16 @@ const prepareTwitterEmbeds = (content) => {
}
body = body.replace(link, `~~~~~~.^.~~~:twitter:${id}:~~~~~~.^.~~~`)
}
else if(link.match(mobileTwitterRegex)) {
match = link.match(mobileTwitterRegex)
id = match[2]
if(link.match(/(?:https?:\/\/(?:(?:mobile\.twitter\.com\/(.*?)\/status\/(.*)?=(.*))))/i)) {
match = link.match(/(?:https?:\/\/(?:(?:mobile\.twitter\.com\/(.*?)\/status\/(.*)?=(.*))))/i)
id = match[2]
id = id.slice(0, -2)
}
body = body.replace(link, `~~~~~~.^.~~~:twitter:${id}:~~~~~~.^.~~~`)
}

if(match) {
const id = match[2]
Expand Down Expand Up @@ -317,7 +328,7 @@ const prepareLbryEmbeds = (content) => {
}

const prepareOdyseeEmbeds = (content) => {
const odyseeRegex = /(?:https?:\/\/(?:(?:odysee\.com)))/i
const odyseeRegex = /(?:https?:\/\/(?:(?:odysee\.com\/@(.*?))))/i
let body = content

const links = markdownLinkExtractor(content)
Expand Down Expand Up @@ -382,6 +393,35 @@ const prepareBitchuteEmbeds = (content) => {
return body
}

const prepareBannedEmbeds = (content) => {
const bannedRegex = /(?:https?:\/\/(?:(?:banned\.video\/watch\?id=(.*))))/i

let body = content

const links = textParser.getUrls(content)

links.forEach((link) => {
try {
link = link.replace(/&amp;/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 prepareSoundCloudEmbeds = (content) => {
const soundcloudRegex = /^https?:\/\/(soundcloud\.com|snd\.sc)\/(.*)$/
let body = content
Expand Down Expand Up @@ -447,6 +487,7 @@ const prepareFacebookEmbeds = (content) => {

const prepareTiktokEmbeds = (content) => {
const tiktokRegex = /((http:\/\/(.*\.tiktok\.com\/.*|tiktok\.com\/.*))|(https:\/\/(.*\.tiktok\.com\/.*|tiktok\.com\/.*)))/g
const tiktokIdRegex = /[0-9]+/

let body = content
const links = textParser.getUrls(content)
Expand All @@ -458,10 +499,11 @@ const prepareTiktokEmbeds = (content) => {

try {
if(link.match(tiktokRegex)){
const data = link.split('/')
const url = new URL(link)
const data = url.pathname.split('/')
match = link.match(tiktokRegex)

id = data[5]
id = data.reduce((a, v) => v.match(tiktokIdRegex) ? v : a)
}

if (!id) {
Expand Down Expand Up @@ -497,6 +539,26 @@ const prepareAppleEmbeds = (content) => {
return body
}

const prepareDTubeEmbeds = (content) => {
const dtubeRegex = /^https:\/\/(emb\.)?d\.tube\/(.*)/
let body = content

const links = textParser.getUrls(content)

links.forEach((link) => {
link = link.replace(/&amp;/g, '&')

const match = link.match(dtubeRegex)

if (match) {
const data = link.split('/')
const id = `${data[4]}/${data[5]}`
body = body.replace(link, `~~~~~~.^.~~~:dtube:${id}:~~~~~~.^.~~~`)
}
})
return body
}

const getCoinTicker = (coin) => {
const data = require('../../../files/coinGeckoData.json')

Expand Down Expand Up @@ -533,6 +595,10 @@ const render = (content, markdownClass, assetClass, scrollIndex, recomputeRowInd
const splitBitchute = content.split(':')
const url = `https://www.bitchute.com/embed/${splitBitchute[2]}`
return <UrlVideoEmbed key={`${url}${scrollIndex}bitchute`} url={url} />
} else if(content.includes(':banned:')) {
const splitBanned = content.split(':')
const url = `https://api.banned.video/embed/${splitBanned[2]}`
return <UrlVideoEmbed key={`${url}${scrollIndex}banned`} url={url} />
} else if(content.includes(':soundcloud:')) {
const splitSoundcloud = content.split(':')
const url = `https://soundcloud.com/${splitSoundcloud[2]}`
Expand Down Expand Up @@ -563,22 +629,24 @@ const render = (content, markdownClass, assetClass, scrollIndex, recomputeRowInd
}
} else if (content.includes(':tiktok:')) {
const splitTiktok = content.split(':')
const url = `https://www.tiktok.com/embed/v2/${splitTiktok[2]}?lang=en-US`

return (
<React.Fragment>
<div className={classes.tiktokWrapper}>
<iframe
title='Embedded Video'
src={url}
allowFullScreen={true}
frameBorder='0'
height='250'
width='100%'
></iframe>
</div>
</React.Fragment>
)
if (splitTiktok[2]) {
const url = `https://www.tiktok.com/embed/v2/${splitTiktok[2]}?lang=en-US`

return (
<React.Fragment>
<div className={classes.tiktokWrapper}>
<iframe
title='Embedded Video'
src={url}
allowFullScreen={true}
frameBorder='0'
height='250'
width='100%'
></iframe>
</div>
</React.Fragment>
)
}
} else if (content.includes(':odysy:')) {
const splitOdysy = content.split(':')
const url = `https://odysee.com/$/embed/${splitOdysy[2]}`
Expand All @@ -601,6 +669,10 @@ const render = (content, markdownClass, assetClass, scrollIndex, recomputeRowInd
</div>
</React.Fragment>
)
} else if (content.includes(':dtube:')) {
const splitDTube = content.split(':')
const url = `https://emb.d.tube/#!/${splitDTube[2]}`
return <UrlVideoEmbed key={`${url}${scrollIndex}dtube`} url={url} />
} else {
// render normally
return <div
Expand Down Expand Up @@ -649,6 +721,8 @@ const MarkdownViewer = React.memo((props) => {
content = prepareLbryEmbeds(content)
} else if(link.includes('www.bitchute.com')) {
content = prepareBitchuteEmbeds(content)
} else if(link.includes('banned.video')) {
content = prepareBannedEmbeds(content)
} else if(link.includes('soundcloud.com')) {
content = prepareSoundCloudEmbeds(content)
} else if(link.includes('facebook.com')) {
Expand All @@ -659,6 +733,8 @@ const MarkdownViewer = React.memo((props) => {
content = prepareOdyseeEmbeds(content)
} else if(link.includes('music.apple.com')) {
content = prepareAppleEmbeds(content)
} else if (link.includes('d.tube')) {
content = prepareDTubeEmbeds(content)
}
} catch(error) { }
})
Expand Down
14 changes: 7 additions & 7 deletions src/components/layout/MobileAppFrame/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -304,20 +304,20 @@ const MobileAppFrame = (props) => {
icon: <Badge badgeContent={count.unread || 0} color="secondary"><NotificationsIcon /></Badge>,
},
{
name: 'Wallet',
icon: <WalletIcon />,
path: `/@${username}/wallet`,
name: 'Display',
icon: <SunMoonIcon />,
onClick: showThemeModal,
type: 'action',
},
{
name: 'Profile',
path: `/@${username}/t/buzz?ref=nav`,
icon: <ProfileIcon />,
},
{
name: 'Display',
icon: <SunMoonIcon />,
onClick: showThemeModal,
type: 'action',
name: 'Wallet',
icon: <WalletIcon />,
path: `/@${username}/wallet`,
},
]
const isActivePath = (path, current) => {
Expand Down
16 changes: 8 additions & 8 deletions src/components/layout/SideBarLeft/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -364,21 +364,21 @@ const SideBarLeft = (props) => {
icon: <Badge badgeContent={count.unread || 0} color="secondary"><NotificationsIcon /></Badge>,
},
{
name: 'Wallet',
icon: <WalletIcon />,
path: `/@${username}/wallet`,
name: 'Theme',
icon: <SunMoonIcon />,
path: '#',
preventDefault: true,
onClick: showThemeModal,
},
{
name: 'Profile',
path: `/@${username}/t/buzz?ref=nav`,
icon: <ProfileIcon />,
},
{
name: 'Theme',
icon: <SunMoonIcon />,
path: '#',
preventDefault: true,
onClick: showThemeModal,
name: 'Wallet',
icon: <WalletIcon />,
path: `/@${username}/wallet`,
},
{
name: 'Switch Account',
Expand Down
2 changes: 1 addition & 1 deletion src/components/modals/LoginModal/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ const LoginModal = (props) => {
const { name, value } = target

if (name === 'username') {
setUsername(value)
setUsername(value.replace("@", ""))
} else if (name === 'password') {
setPassword(value)
}
Expand Down
40 changes: 36 additions & 4 deletions src/components/sections/CreateBuzzForm/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import HelpIcon from '@material-ui/icons/Help'
import Tooltip from '@material-ui/core/Tooltip'
import { useLocation } from 'react-router-dom'
import queryString from 'query-string'
import ClearIcon from '@material-ui/icons/Clear'

const useStyles = createUseStyles(theme => ({
container: {
Expand Down Expand Up @@ -118,6 +119,7 @@ const useStyles = createUseStyles(theme => ({
height: 25,
width: 50,
marginLeft: 5,
border: '1px solid lightgray',
borderRadius: 5,
},
payoutLabel: {
Expand All @@ -144,21 +146,42 @@ const useStyles = createUseStyles(theme => ({
...theme.font,
cursor: 'pointer',
marginLeft: 2,
marginBottom: 5,
},
draftPostContainer: {
display: 'flex',
alignItems: 'center',
height: 'fit-content',
float: 'right',
opacity: 0.5,
animation: 'savedAsDraftAnimation 350ms',
},
draftPostLabel: {
...theme.font,
margin: 0,
marginRight: 5,
lineHeight: 1.5,
fontSize: '1.2em',
color: '#e61c34',
float: 'right',
padding: '2px 10px',
width: 'fit-content',
border: '1px solid #e61c34',
borderRadius: '5px',
opacity: 0.5,
animation: 'savedAsDraftAnimation 350ms',
userSelect: 'none',
},
clearDraftIcon: {
color: '#e61c34',
borderRadius: '50%',
cursor: 'pointer',

'&:hover':{
transition: 'all 350ms',
padding: 5,
transform: 'scale(1.1)',
background: '#e61c34',
color: 'white',
},
},
counter: {
position: 'absolute',
fontWeight: 'bold',
Expand Down Expand Up @@ -261,6 +284,12 @@ const CreateBuzzForm = (props) => {
localStorage.setItem('draft_post', content)
}

const clearDraft = () => {
setContent('')
savePostAsDraft('')
savePostAsDraftToStorage('')
}

const onChange = (e, draft) => {
const { target } = e
const { name } = target
Expand Down Expand Up @@ -510,7 +539,10 @@ const CreateBuzzForm = (props) => {
/>
)}
{draftPost && (
<p className={classes.draftPostLabel}>draft</p>
<span className={classes.draftPostContainer}>
<p className={classes.draftPostLabel}>draft</p>
<ClearIcon size={20} className={classes.clearDraftIcon} onClick={clearDraft}/>
</span>
)}
<br />
<br />
Expand Down
2 changes: 1 addition & 1 deletion src/components/sections/ReplyList/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ const ReplyList = (props) => {
<div className={classes.context}>
<div className={classes.contextWrapper}>
<h6 style={{ paddingTop: 5 }}>Reply is truncated because it is over 280 characters</h6>
<a target="_blank" without="true" rel="noopener noreferrer" href={`https://hive.blog/@${author}/${permlink}`}>View the full reply</a>
<a target="_blank" without="true" rel="noopener noreferrer" href={`https://blog.d.buzz/#/@${author}/c/${permlink}`}>View the full reply</a>
</div>
</div>
)}
Expand Down
2 changes: 1 addition & 1 deletion src/components/sections/SearchPeople/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ const SearchPeople = (props) => {
return (
<React.Fragment>
{(items.people || []).map((item) => (
<div className={classes.wrapper}>
<div className={classes.wrapper} key={item.account}>
<div className={classes.row}>
<Link to={`/@${item.account}`}>
<Row>
Expand Down
Loading