Skip to content

Commit

Permalink
Add support for embedded dtube videos
Browse files Browse the repository at this point in the history
  • Loading branch information
smoke-indica committed Aug 6, 2020
1 parent 7f4ab77 commit 96b1b59
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 3 deletions.
4 changes: 2 additions & 2 deletions config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@
"google_analytics_id": "UA-106330268-3",
"helmet": {
"directives": {
"childSrc": "'self' player.twitch.tv www.youtube.com staticxx.facebook.com w.soundcloud.com open.spotify.com player.vimeo.com www.theweedtube.com emb.d.tube player.twitch.tv www.twitch.tv gleam.io js.gleam.io",
"childSrc": "'self' emb.d.tube player.twitch.tv www.youtube.com staticxx.facebook.com w.soundcloud.com open.spotify.com player.vimeo.com www.theweedtube.com emb.d.tube player.twitch.tv www.twitch.tv gleam.io js.gleam.io",
"connectSrc": "'self' smoke.io rpc.smoke.io https://rpc.smoke.io wss://rpc.smoke.io pubrpc.smoke.io api.smoke.io",
"defaultSrc": "'self' www.youtube.com staticxx.facebook.com player.vimeo.com open.spotify.com",
"defaultSrc": "'self' emb.d.tube www.youtube.com staticxx.facebook.com player.vimeo.com open.spotify.com",
"fontSrc": "data: fonts.gstatic.com",
"frameAncestors": "'none'",
"imgSrc": "* data:",
Expand Down
16 changes: 15 additions & 1 deletion src/app/components/cards/MarkdownViewer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class MarkdownViewer extends Component {

// HtmlReady inserts ~~~ embed:${id} type ~~~
for (let section of cleanText.split('~~~ embed:')) {
const match = section.match(/^([A-Za-z0-9\?\=\_\-]+) (youtube|vimeo|twitch|spotify|spotifyLarge) ~~~/)
const match = section.match(/^([A-Za-z0-9\?\=\_\-\/]+) (youtube|vimeo|twitch|spotify|spotifyLarge|dtube) ~~~/)
if (match && match.length >= 2) {
const id = match[1]
const type = match[2]
Expand Down Expand Up @@ -180,6 +180,20 @@ class MarkdownViewer extends Component {
/>
</div>
);
} else if (type === 'dtube') {
const url = `https://emb.d.tube/#!/${id}`;
sections.push(
<div className="videoWrapper">
<iframe
key={idx++}
src={url}
width={w}
height={h}
frameBorder="0"
allowFullScreen
/>
</div>
);
} else {
console.error('MarkdownViewer unknown embed type', type);
}
Expand Down
2 changes: 2 additions & 0 deletions src/app/utils/Links.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export default {
// simpleLink: new RegExp(`<a href="(.*)">(.*)<\/a>`, 'ig'),
ipfsPrefix: /(https?:\/\/.*)?\/ipfs/i,
twitch: /https?:\/\/(?:www.)?twitch.tv\/(?:(videos)\/)?([a-zA-Z0-9][\w]{3,24})/i,
dtube: /https:\/\/(?:emb\.)?(?:d.tube\/\#\!\/(?:v\/)?)([a-zA-Z0-9\/]*)/,
dtubeId: /(?:d\.tube\/#!\/(?:v\/)?([a-zA-Z0-9\/]*))+/,
}

// Original regex
Expand Down
7 changes: 7 additions & 0 deletions src/app/utils/SanitizeConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ const iframeWhitelist = [
return src;
},
},
{
re: /^https:\/\/emb.d.tube\/\#\!\/([a-zA-Z0-9\/]+)$/,
fn: src => {
// <iframe width="560" height="315" src="https://emb.d.tube/#!/justineh/u6qoydvy" frameborder="0" allowfullscreen></iframe>
return src;
},
},
];
export const noImageText = '(Image not shown due to low ratings)'
export const allowedTags = `
Expand Down
6 changes: 6 additions & 0 deletions src/app/utils/SlateEditor/Iframe.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ export default class Iframe extends React.Component {
}
}

// Detect dtube
match = url.match(linksRe.dtubeId);
if (match && match.length >= 2) {
return 'https://emb.d.tube/#!/' + match[1];
}

console.log("unable to auto-detect embed url", url)
return null
}
Expand Down
28 changes: 28 additions & 0 deletions src/shared/HtmlReady.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ function linkifyNode(child, state) {
child = embedYouTubeNode(child, state.links, state.images);
child = embedVimeoNode(child, state.links, state.images);
child = embedTwitchNode(child, state.links, state.images);
child = embedDTubeNode(child, state.links, state.images);
if (embedSpotifyNode(child, state.links, state.images)) return
if (embedSpotifyLargeNode(child, state.links, state.images)) return

Expand Down Expand Up @@ -421,6 +422,33 @@ function twitchId(data) {
};
}

function embedDTubeNode(child, links /*images*/) {
try {
const data = child.data;
const dtube = dtubeId(data);
if (!dtube) return child;

child.data = data.replace(dtube.url, `~~~ embed:${dtube.id} dtube ~~~`);

if (links) links.add(dtube.canonical);
} catch (error) {
console.log(error);
}
return child;
}

function dtubeId(data) {
if (!data) return null;
const m = data.match(linksRe.dtube);
if (!m || m.length < 2) return null;

return {
id: m[1],
url: m[0],
canonical: `https://emb.d.tube/#!/${m[1]}`,
};
}

function ipfsPrefix(url) {
if ($STM_Config.ipfs_prefix) {
// Convert //ipfs/xxx or /ipfs/xxx into https://smoke.io/ipfs/xxxxx
Expand Down
18 changes: 18 additions & 0 deletions src/shared/HtmlReady.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,24 @@ describe('htmlready', () => {
expect(res).toEqual(htmlified);
});

it('should not omit text on same line as dtube link', () => {
const testString =
'<html><p>before text https://d.tube/#!/v/tibfox/mvh7g26e after text</p></html>';
const htmlified =
'<html xmlns="http://www.w3.org/1999/xhtml"><p>before text ~~~ embed:tibfox/mvh7g26e dtube ~~~ after text</p></html>';
const res = HtmlReady(testString).html;
expect(res).toEqual(htmlified);
});

it('should handle dtube embed', () => {
const testString =
'<html><iframe width="560" height="315" src="https://emb.d.tube/#!/dbroze/8lsh5nf7" frameborder="0" allowfullscreen></iframe></html>';
const htmlified =
'<html xmlns="http://www.w3.org/1999/xhtml"><div class="videoWrapper"><iframe width="560" height="315" src="https://emb.d.tube/#!/dbroze/8lsh5nf7" frameborder="0" allowfullscreen="allowfullscreen" xmlns="http://www.w3.org/1999/xhtml"></iframe></div></html>';
const res = HtmlReady(testString).html;
expect(res).toEqual(htmlified);
});

it('should not allow links where the text portion contains smoke.io but the link does not', () => {
// There isn't an easy way to mock counterpart, even with proxyquire, so we just test for the missing translation message -- ugly but ok

Expand Down

0 comments on commit 96b1b59

Please sign in to comment.