2018-09-27 18:11:26 +02:00
"use strict" ;
// P A C K A G E S
const html = require ( "choo/html" ) ;
const local = require ( "app-root-path" ) . require ;
const request = require ( "request-promise-native" ) ;
2018-10-10 19:56:35 +02:00
// U T I L S
2018-09-27 18:11:26 +02:00
2018-10-10 23:15:43 +02:00
const fetchMetadata = local ( "/app/helpers/fetch-metadata" ) ;
const { generateGitHubFeed } = local ( "/app/helpers/github" ) ;
const logSlackError = local ( "/app/helpers/slack" ) ;
2018-09-27 18:11:26 +02:00
// P R O G R A M
module . exports = exports = ( socket , action ) => {
if ( typeof socket !== "object" && typeof action !== "object" ) return ;
switch ( true ) {
case ( action . message === "fetch metadata" ) :
fetchMetadata ( action , socket ) ;
break ;
case ( action . message === "landed on homepage" ) :
generateGitHubFeed ( result => {
socket . send ( JSON . stringify ( {
2018-10-06 22:53:01 +02:00
html : result ,
message : "updated html" ,
selector : "#github-feed"
2018-09-27 18:11:26 +02:00
} ) ) ;
} ) ;
break ;
2018-10-03 22:27:13 +02:00
case ( action . message === "landed on playground" ) :
2018-09-27 18:11:26 +02:00
generateContent ( 1 , result => {
socket . send ( JSON . stringify ( {
2018-10-06 22:53:01 +02:00
html : result ,
message : "updated html" ,
selector : "#playground-loader"
2018-09-27 18:11:26 +02:00
} ) ) ;
} ) ;
break ;
2018-10-03 22:27:13 +02:00
case ( action . message === "request for playground, example 1" ) :
2018-09-27 18:11:26 +02:00
generateContent ( 1 , result => {
socket . send ( JSON . stringify ( {
2018-10-06 22:53:01 +02:00
html : result ,
message : "updated html" ,
selector : "#playground-loader"
2018-09-27 18:11:26 +02:00
} ) ) ;
} ) ;
break ;
2018-10-03 22:27:13 +02:00
case ( action . message === "request for playground, example 2" ) :
2018-09-27 18:11:26 +02:00
generateMemeCreator ( socket ) ;
break ;
2018-10-03 22:27:13 +02:00
case ( action . message === "request for playground, example 3" ) :
2018-09-27 18:11:26 +02:00
generateContent ( 3 , result => {
socket . send ( JSON . stringify ( {
2018-10-06 22:53:01 +02:00
html : result ,
message : "updated html" ,
selector : "#playground-loader"
2018-09-27 18:11:26 +02:00
} ) ) ;
} ) ;
break ;
case ( action . message === "subscribe" ) :
newsletterSubscribe ( action , socket ) ;
break ;
default :
2018-09-27 20:00:34 +02:00
console . log ( action ) ; // eslint-disable-line
2018-09-27 18:11:26 +02:00
break ;
}
} ;
// H E L P E R S
2018-09-27 20:00:34 +02:00
function generateContent ( exampleNumber , displayTrendingContent ) {
if ( exampleNumber === 1 ) {
return getTrendingContent ( ) . then ( response => {
if ( ! response || ! response . success || response . success !== true || ! response . data ) return "" ;
const rawContentCollection = [ ] ;
const renderedContentCollection = [ ] ;
const trendingContentData = response . data ;
for ( const data of trendingContentData ) {
rawContentCollection . push ( fetchMetadata ( { claim : data . url , method : "resolve" , example : exampleNumber } ) ) ;
}
Promise . all ( rawContentCollection ) . then ( collection => {
for ( const part of collection ) {
try {
renderedContentCollection . push ( `
2018-10-03 22:27:13 +02:00
< figure class = "playground__content__trend" >
2018-10-10 00:11:22 +02:00
< img alt = "${part.name}" data - action = "choose claim" data - claim - id = "${part.name}" src = "${makeImageSourceSecure(part.value.stream.metadata.thumbnail)}" / >
2018-09-27 20:00:34 +02:00
2018-09-27 22:46:59 +02:00
< figcaption data - action = "choose claim" data - claim - id = "${part.name}" >
2018-09-27 20:00:34 +02:00
$ { part . value . stream . metadata . title }
< span > $ { part . channel _name } < / s p a n >
< / f i g c a p t i o n >
< / f i g u r e >
` );
} catch ( err ) {
return ; // TODO: Return nice error message
}
}
renderedContentCollection . push ( `
< script >
2018-10-03 22:27:13 +02:00
document . getElementById ( "playground-example-description" ) . innerHTML = document . querySelector ( "[data-action='playground, example 1']" ) . dataset . description
2018-09-27 20:00:34 +02:00
< / s c r i p t >
` );
displayTrendingContent ( renderedContentCollection . join ( "" ) ) ;
} ) ;
} ) ;
}
if ( exampleNumber === 3 ) {
const approvedUrls = [
"LBRY#3db81c073f82fd1bb670c65f526faea3b8546720" ,
"correlation-can-imply-causation#173412f5b1b7aa63a752e8832406aafd9f1ecb4e" ,
2018-09-27 22:46:59 +02:00
"thanos-is-the-protagonist-how-infinity#2a7f5db2678177435b1dee6c9e38e035ead450b6" ,
2018-09-27 20:00:34 +02:00
"epic-arcade-mode-duos-nickatnyte-molt#d81bac6d49b1f92e58c37a5f633a27a45b43405e" ,
"political-correctness-a-force-for-good-a#b4668c0bd096317b44c40738c099b6618095e75f" ,
"10-secrets-hidden-inside-famous-logos#007789cc45cbb4255cf02ba77cbf84ca8e3d7561" ,
"ever-wonder-how-bitcoin-and-other#1ac47b8b3def40a25850dc726a09ce23d09e7009" ,
"bankrupt-pan-am#784b3c215a6f06b663fc1aa292bcb19f29c489bb" ,
"minecraft-in-real-life-iron-man#758dd6497cdfc401ae1f25984738d024d47b50af" ,
"ethan-shows-kyle-warframe-skyvault#8a7401b88d5ed0376d98f16808194d4dcb05b284"
] ;
const rawContentCollection = [ ] ;
const renderedContentCollection = [ ] ;
2018-09-28 21:09:45 +02:00
for ( const url of approvedUrls )
2018-09-27 20:00:34 +02:00
rawContentCollection . push ( fetchMetadata ( { claim : url , method : "resolve" , example : exampleNumber } ) ) ;
2018-09-27 22:46:59 +02:00
return Promise . all ( rawContentCollection ) . then ( collection => {
2018-09-27 20:00:34 +02:00
for ( const part of collection ) {
2018-09-27 22:46:59 +02:00
if (
part &&
part . value &&
part . value . stream . metadata . thumbnail &&
part . channel _name
) {
2018-09-27 20:00:34 +02:00
renderedContentCollection . push ( `
2018-10-03 22:27:13 +02:00
< figure class = "playground__content__trend" >
2018-10-10 00:11:22 +02:00
< img alt = "${part.name}" data - action = "choose claim" data - claim - id = "${part.claim_id}" src = "${makeImageSourceSecure(part.value.stream.metadata.thumbnail)}" / >
2018-09-27 22:46:59 +02:00
< figcaption data - action = "choose claim" data - claim - id = "${part.claim_id}" >
2018-09-27 20:00:34 +02:00
$ { part . value . stream . metadata . title }
< span > $ { part . channel _name } < / s p a n >
< / f i g c a p t i o n >
< / f i g u r e >
` );
}
}
renderedContentCollection . push ( `
< script >
2018-10-03 22:27:13 +02:00
document . getElementById ( "playground-example-description" ) . innerHTML = document . querySelector ( "[data-action='playground, example 3']" ) . dataset . description
2018-09-27 20:00:34 +02:00
< / s c r i p t >
` );
displayTrendingContent ( renderedContentCollection . join ( "" ) ) ;
} ) ;
}
}
2018-09-27 18:11:26 +02:00
function generateMemeCreator ( socket ) {
const images = [
{
alt : "Carl Sagan" ,
2018-10-10 00:24:35 +02:00
// src: "https://spee.ch/4f6b953e605a602434246743fd246d3e1fd4f5fd/carlsagan2.jpg"
src : "/assets/media/images/carlsagan2.jpg"
2018-09-27 18:11:26 +02:00
} ,
{
alt : "Doge" ,
2018-10-10 00:24:35 +02:00
// src: "https://spee.ch/2f90f2d91441a4d33d3d4eb82bdfc4c56ec742c7/doge-meme.jpg"
src : "/assets/media/images/doge-meme.jpg"
2018-09-27 18:11:26 +02:00
} ,
{
alt : "LBRY Logo With Green Background" ,
2018-10-10 00:24:35 +02:00
// src: "https://spee.ch/40ac6818bbac87a208722bf4467653341d460908/lbry-green.png"
src : "/assets/media/images/lbry-green.png"
2018-09-27 18:11:26 +02:00
}
] ;
const memePlaceholderData = {
bottomLine : {
placeholder : "Top line" ,
value : "that I made"
} ,
description : {
placeholder : "Description" ,
value : "Check out this image I published to LBRY via lbry.tech"
} ,
topLine : {
placeholder : "Top line" ,
value : "This is an example meme"
} ,
title : {
placeholder : "Title" ,
value : "Dank Meme Supreme da Cheese"
}
} ;
const renderedImages = [ ] ;
2018-09-28 21:09:45 +02:00
for ( const image of images )
2018-10-03 22:27:13 +02:00
renderedImages . push ( ` <img alt=" ${ image . alt } " class="playground__content__meme__canvas__thumbnail" src=" ${ image . src } "/> ` ) ;
2018-09-27 18:11:26 +02:00
const memeCreator = html `
2018-10-03 22:27:13 +02:00
< div class = "playground__content__meme__canvas" >
2018-09-27 18:11:26 +02:00
< img alt = "Base image for LBRY meme creator" id = "base-image" style = "height: 0; position: absolute; visibility: hidden;" / >
2018-09-28 23:59:38 +02:00
< canvas id = "meme-canvas" height = "600" width = "800" > Unfortunately , it looks like canvas is < strong > not supported < / s t r o n g > i n y o u r b r o w s e r < / c a n v a s >
2018-09-27 18:11:26 +02:00
$ { renderedImages }
< / d i v >
2018-10-03 22:27:13 +02:00
< form class = "playground__content__meme__editor" >
2018-09-27 18:11:26 +02:00
< h2 > Image Text < / h 2 >
< fieldset >
< label for = "meme-top-line" > Top line < / l a b e l >
< input id = "meme-top-line" name = "meme-top-line" placeholder = "${memePlaceholderData.topLine.placeholder}" spellcheck = "false" type = "text" value = "${memePlaceholderData.topLine.value}" required / >
< / f i e l d s e t >
< fieldset >
< label for = "meme-bottom-line" > Bottom line < / l a b e l >
< input id = "meme-bottom-line" name = "meme-bottom-line" placeholder = "${memePlaceholderData.bottomLine.placeholder}" spellcheck = "false" type = "text" value = "${memePlaceholderData.bottomLine.value}" required / >
< / f i e l d s e t >
< h2 class = "__metadata" > Metadata < / h 2 >
< fieldset >
< label for = "meme-title" > Title < / l a b e l >
< input id = "meme-title" name = "meme-title" placeholder = "${memePlaceholderData.title.placeholder}" spellcheck = "false" type = "text" value = "${memePlaceholderData.title.value}" required / >
< / f i e l d s e t >
< fieldset >
< label for = "meme-description" > Description < / l a b e l >
< textarea id = "meme-description" name = "meme-description" placeholder = "${memePlaceholderData.description.placeholder}" spellcheck = "false" type = "text" required > $ { memePlaceholderData . description . value } < / t e x t a r e a >
< / f i e l d s e t >
< fieldset >
< label for = "meme-language" > Language < / l a b e l >
< select id = "meme-language" name = "meme-language" >
< option value = "ar" > Arabic < / o p t i o n >
< option value = "zh" > Chinese ( Mandarin ) < / o p t i o n >
< option value = "en" > English < / o p t i o n >
< option value = "fr" > French < / o p t i o n >
< option value = "de" > German < / o p t i o n >
< option value = "it" > Italian < / o p t i o n >
< option value = "jp" > Japanese < / o p t i o n >
< option value = "ru" > Russian < / o p t i o n >
< option value = "es" > Spanish < / o p t i o n >
< option value = "" > Not specified < / o p t i o n >
< / s e l e c t >
< / f i e l d s e t >
< fieldset >
< label for = "meme-license" > License < / l a b e l >
< select id = "meme-license" name = "meme-license" required >
< option value = "Public Domain" > Public Domain < / o p t i o n >
< option value = "Creative Commons Attribution 4.0 International" > Creative Commons Attribution 4.0 International < / o p t i o n >
< option value = "Creative Commons Attribution-ShareAlike 4.0 International" > Creative Commons Attribution - ShareAlike 4.0 International < / o p t i o n >
< option value = "Creative Commons Attribution-NoDerivatives 4.0 International" > Creative Commons Attribution - NoDerivatives 4.0 International < / o p t i o n >
< option value = "Creative Commons Attribution-NonCommercial 4.0 International" > Creative Commons Attribution - NonCommercial 4.0 International < / o p t i o n >
< option value = "Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International" > Creative Commons Attribution - NonCommercial - ShareAlike 4.0 International < / o p t i o n >
< option value = "Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International" > Creative Commons Attribution - NonCommercial - NoDerivatives 4.0 International < / o p t i o n >
< option value = "None" > None < / o p t i o n >
< / s e l e c t >
< / f i e l d s e t >
< fieldset >
< label > < input id = "meme-nsfw-flag" name = "nsfw" type = "checkbox" / > NSFW < / l a b e l >
< / f i e l d s e t >
< fieldset >
2018-10-09 20:28:58 +02:00
< button data - action = "upload image" class = "button" type = "button" > Submit < / b u t t o n >
2018-09-27 18:11:26 +02:00
< / f i e l d s e t >
< / f o r m >
` ;
return socket . send ( JSON . stringify ( {
2018-10-06 22:53:01 +02:00
example : 2 ,
html : memeCreator ,
message : "updated html" ,
selector : "#playground-loader"
2018-09-27 18:11:26 +02:00
} ) ) ;
}
function getTrendingContent ( ) {
return new Promise ( ( resolve , reject ) => { // eslint-disable-line
request ( {
method : "GET" ,
url : "https://api.lbry.io/file/list_trending"
} , ( error , response , body ) => {
if ( error || ! JSON . parse ( body ) ) resolve ( "Issue fetching content" ) ; // error
body = JSON . parse ( body ) ;
resolve ( body ) ;
} ) ;
} ) ;
}
2018-10-10 00:11:22 +02:00
function makeImageSourceSecure ( url ) {
const originalUrl = new URL ( url ) ;
if ( originalUrl . protocol !== "https" )
return ` https:// ${ originalUrl . host } ${ originalUrl . pathname } ` ;
return originalUrl . href ;
}
2018-09-27 18:11:26 +02:00
function newsletterSubscribe ( data , socket ) {
const email = data . email ;
if ( ! validateEmail ( email ) ) return socket . send ( JSON . stringify ( {
2018-10-10 21:04:16 +02:00
class : "error" ,
html : "Your email address is invalid" ,
2018-10-06 22:53:01 +02:00
message : "updated html" ,
selector : "#emailMessage"
2018-09-27 18:11:26 +02:00
} ) ) ;
2018-10-10 21:04:16 +02:00
return new Promise ( ( resolve , reject ) => request ( {
method : "POST" ,
url : ` https://api.lbry.io/list/subscribe?email= ${ encodeURIComponent ( email ) } &tag=developer `
} ) . then ( body => {
if ( ! body || ! JSON . parse ( body ) ) {
logSlackError (
"\n" +
"> *NEWSLETTER ERROR:* ```¯\\_(ツ)_/¯ This should be an unreachable error```" + "\n" +
` > _Cause: ${ email } interacted with the form_ \n `
) ;
2018-09-27 18:11:26 +02:00
2018-10-10 21:04:16 +02:00
return resolve ( socket . send ( JSON . stringify ( {
class : "error" ,
html : "Something is terribly wrong" ,
message : "updated html" ,
selector : "#emailMessage"
} ) ) ) ;
}
2018-09-27 18:11:26 +02:00
2018-10-10 21:04:16 +02:00
body = JSON . parse ( body ) ;
2018-09-27 18:11:26 +02:00
2018-10-10 21:04:16 +02:00
if ( ! body . success ) {
logSlackError (
"\n" +
"> *NEWSLETTER ERROR:* ```" + JSON . parse ( JSON . stringify ( body . error ) ) + "```" + "\n" +
` > _Cause: ${ email } interacted with the form_ \n `
) ;
return reject ( socket . send ( JSON . stringify ( {
class : "error" ,
html : body . error ,
message : "updated html" ,
selector : "#emailMessage"
} ) ) ) ;
}
return resolve ( socket . send ( JSON . stringify ( {
html : "Thank you! Please confirm subscription in your inbox." ,
message : "updated html" ,
selector : "#emailMessage"
} ) ) ) ;
} )
. catch ( welp => {
if ( welp . statusCode === 409 ) {
2018-09-27 18:11:26 +02:00
logSlackError (
"\n" +
2018-10-10 21:04:16 +02:00
"> *NEWSLETTER ERROR:* ```" + JSON . parse ( JSON . stringify ( welp . error ) ) + "```" + "\n" +
` > _Cause: ${ email } interacted with the form_ \n `
2018-09-27 18:11:26 +02:00
) ;
2018-10-10 21:04:16 +02:00
return resolve ( socket . send ( JSON . stringify ( {
class : "error" ,
html : "You have already subscribed!" ,
2018-10-06 22:53:01 +02:00
message : "updated html" ,
selector : "#emailMessage"
2018-09-27 18:11:26 +02:00
} ) ) ) ;
}
2018-10-10 21:04:16 +02:00
} ) ) ;
2018-09-27 18:11:26 +02:00
}
function validateEmail ( email ) {
const emailRegex = /^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\\.,;:\s@"]{2,})$/i ;
2018-10-06 22:53:01 +02:00
2018-09-27 18:11:26 +02:00
return emailRegex . test ( String ( email ) ) ;
}