Work on meme example, will replace with spee.ch

This commit is contained in:
ポール ウェッブ 2018-08-10 17:29:06 -05:00
parent 1768a7ca52
commit a42a2a2826
9 changed files with 371 additions and 55 deletions

View file

@ -12,6 +12,7 @@ const stringifyObject = require("stringify-object");
// V A R I A B L E S
const randomString = local("/helpers/random-string");
const loadLanguages = require("prismjs/components/");
const logSlackError = local("/helpers/slack");
const uploadImage = local("/helpers/upload-image");
@ -52,36 +53,26 @@ module.exports = exports = (data, socket) => {
body.method = resolveMethod;
if (resolveMethod === "publish") {
// body.bid = 0.001; // Hardcoded publish amount
body.bid = 0.001; // Hardcoded publish amount
body.description = dataDetails.description;
body.file_path = process.env.LBRY_DAEMON_IMAGES_PATH + dataDetails.file_path; // TODO: Fix the internal image path in daemon (original comment, check to see if still true)
body.language = dataDetails.language;
body.license = dataDetails.license;
body.name = dataDetails.name;
body.name = dataDetails.name.replace(/\s/g, "") + randomString(10);
body.nsfw = dataDetails.nsfw;
body.title = dataDetails.title;
// TODO: Forget all this and upload to spee.ch
return uploadImage(body.file_path).then(uploadResponse => {
if (uploadResponse.status !== "ok") return;
body.file_path = uploadResponse.filename;
body.method = resolveMethod;
body.filename = uploadResponse.filename;
// Reference:
// https://github.com/lbryio/lbry.tech/blob/legacy/content/.vuepress/components/Tour/Step2.vue
// https://github.com/lbryio/lbry.tech/blob/legacy/server.js
return new Promise((resolve, reject) => {
request({
qs: body,
url: "http://daemon.lbry.tech/images.php"
}, (error, response, body) => {
if (error) reject(error);
body = JSON.parse(body);
// console.log(body);
resolve(body);
});
});
}).catch(uploadError => {
// component.isLoading = false;
// component.jsonData = JSON.stringify(uploadError, null, " ");
@ -102,9 +93,7 @@ module.exports = exports = (data, socket) => {
});
}
if (resolveMethod === "resolve") {
body.uri = claimAddress;
}
if (resolveMethod === "resolve") body.uri = claimAddress;
if (resolveMethod === "wallet_send") {
body.amount = "0.001"; // Hardcoded tip amount

10
helpers/random-string.js Normal file
View file

@ -0,0 +1,10 @@
"use strict";
const crypto = require("crypto");
module.exports = exports = len => {
if (!Number.isFinite(len)) throw new TypeError("Expected a finite number");
return crypto.randomBytes(Math.ceil(len / 2)).toString("hex").slice(0, len);
};

View file

@ -51,13 +51,13 @@
"choo-devtools": "^2.5.1",
"nodemon": "^1.18.3",
"npm-run-all": "^4.1.3",
"sass": "^1.10.3",
"sass": "^1.10.4",
"snazzy": "^7.1.1",
"standardx": "^2.1.0",
"updates": "^4.1.2"
},
"peerDependencies": {
"request": "^2.87.0"
"request": "^2.88.0"
},
"babel": {
"presets": [

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -69,7 +69,7 @@
border-left: 1px solid rgba($black, 0.05);
float: right;
padding: 1rem;
padding: 1rem 0 1rem 1rem;
vertical-align: top;
}
@ -146,12 +146,177 @@
}
}
.tour__content__meme,
.tour__content__trends {
overflow-y: auto;
position: relative;
}
.tour__content__meme {
&::after {
@include clearfix;
}
}
.tour__content__meme__canvas {
float: left;
margin-right: 2%;
width: 48%;
canvas {
width: 100%; height: 100%;
background-color: rgba($teal, 0.3);
margin-bottom: 1rem;
}
}
.tour__content__meme__canvas__thumbnail {
width: 5rem; height: 5rem;
border-style: solid;
border-width: 2px;
margin-bottom: 1rem;
object-fit: contain;
object-position: center;
&:not(:last-of-type) {
margin-right: 1rem;
}
&:not(.selected) {
border-color: transparent;
}
&.selected {
border-color: $black;
}
}
.tour__content__meme__editor {
float: right;
width: 48%;
h2.__metadata {
margin-top: 3rem;
}
fieldset {
border: none;
&:not(:last-of-type) {
margin-bottom: 1rem;
}
}
label {
color: rgba($black, 0.3);
display: block;
font-size: 0.8rem;
font-weight: 600;
letter-spacing: 0.05rem;
margin-bottom: 0.025rem;
text-transform: uppercase;
width: 100%;
}
input:not([type="checkbox"]):not([type="submit"]),
select,
textarea {
@media (min-width: 901px) {
font-size: 1.25rem;
}
@media (max-width: 900px) {
font-size: 1.05rem;
}
}
input {
&:not([type="checkbox"]):not([type="file"]):not([type="submit"]) {
border-bottom: 2px solid;
padding-bottom: 0.15rem;
transition: all 0.2s;
width: 100%;
}
&:not([type="file"]):not([type="submit"]) {
&:not(:hover):not(:active) {
border-color: $black;
}
&:hover,
&:active {
border-color: $teal;
}
}
&[type="checkbox"] {
width: 1.25rem; height: 1.25rem;
border: 2px solid;
margin-right: 0.5rem;
position: relative;
top: 0.35rem;
&::after {
width: 100%; height: 100%;
content: "";
font-size: 1.5rem;
line-height: 1rem;
position: absolute;
}
&:not(:checked)::after {
color: transparent;
}
&:checked::after {
color: $teal;
}
}
}
select,
textarea {
border-bottom: 2px solid;
width: 100%;
&:not(:hover):not(:active) {
border-color: $black;
}
&:hover,
&:active {
border-color: $teal;
}
}
select {
background-image: url("/assets/media/svg/down.svg");
background-position: 99% center;
background-repeat: no-repeat;
background-size: 1rem;
padding-right: 2rem;
}
textarea {
min-height: 100px;
resize: vertical;
}
}
.tour__content__trends {
display: grid;
grid-gap: 2%;
grid-template-columns: 32% 32% 32%;
overflow-y: auto;
position: relative;
&:empty {
width: 100%; height: 10rem;;

162
server.js
View file

@ -16,6 +16,7 @@ const fastify = require("fastify")({
}
});
const html = require("choo-async/html");
const local = require("app-root-path").require;
const octokit = require("@octokit/rest")();
const redis = require("redis");
@ -100,7 +101,7 @@ fastify.ready(err => {
break;
case "landed on tour" || "request for tour, example 1":
case "landed on tour":
generateTrendingContent(1, result => {
socket.send(JSON.stringify({
"html": result,
@ -111,6 +112,21 @@ fastify.ready(err => {
break;
case "request for tour, example 1":
generateTrendingContent(1, result => {
socket.send(JSON.stringify({
"html": result,
"message": "updated html",
"selector": "#tour-loader"
}));
});
break;
case "request for tour, example 2":
generateMemeCreator(socket);
break;
/*
case "request for tour, example 3":
generateTrendingContent(3, result => {
@ -203,6 +219,136 @@ function generateGitHubFeed(displayGitHubFeed) {
}
}
function generateMemeCreator(socket) {
const images = [
{
alt: "Carl Sagan",
src: "/assets/media/images/carlsagan2.jpg"
},
{
alt: "Doge",
src: "/assets/media/images/doge-meme.jpg"
},
{
alt: "LBRY Logo With Green Background",
src: "/assets/media/images/lbry-green.png"
}
];
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 = [];
for (const image of images) {
renderedImages.push(`<img alt="${image.alt}" class="tour__content__meme__canvas__thumbnail" src="${image.src}"/>`);
}
const memeCreator = html`
<div class="tour__content__meme__canvas">
<img alt="Base image for LBRY meme creator" id="base-image" style="height: 0; visibility: hidden;"/>
<canvas id="meme-canvas" height="300" width="400">Unfortunately, it looks like canvas is <strong>not supported</strong> in your browser</canvas>
${renderedImages}
</div>
<form class="tour__content__meme__editor">
<h2>Image Text</h2>
<fieldset>
<label for="meme-top-line">Top line</label>
<input id="meme-top-line" name="meme-top-line" placeholder="${memePlaceholderData.topLine.placeholder}" spellcheck="false" type="text" value="${memePlaceholderData.topLine.value}" required/>
</fieldset>
<fieldset>
<label for="meme-bottom-line">Bottom line</label>
<input id="meme-bottom-line" name="meme-bottom-line" placeholder="${memePlaceholderData.bottomLine.placeholder}" spellcheck="false" type="text" value="${memePlaceholderData.bottomLine.value}" required/>
</fieldset>
<h2 class="__metadata">Metadata</h2>
<fieldset>
<label for="meme-title">Title</label>
<input id="meme-title" name="meme-title" placeholder="${memePlaceholderData.title.placeholder}" spellcheck="false" type="text" value="${memePlaceholderData.title.value}" required/>
</fieldset>
<fieldset>
<label for="meme-description">Description</label>
<textarea id="meme-description" name="meme-description" placeholder="${memePlaceholderData.description.placeholder}" spellcheck="false" type="text" required>${memePlaceholderData.description.value}</textarea>
</fieldset>
<fieldset>
<label for="meme-language">Language</label>
<select id="meme-language" name="meme-language">
<option value="ar">Arabic</option>
<option value="zh">Chinese (Mandarin)</option>
<option value="en">English</option>
<option value="fr">French</option>
<option value="de">German</option>
<option value="it">Italian</option>
<option value="jp">Japanese</option>
<option value="ru">Russian</option>
<option value="es">Spanish</option>
<option value="">Not specified</option>
</select>
</fieldset>
<fieldset>
<label for="meme-license">License</label>
<select id="meme-license" name="meme-license" required>
<option value="Public Domain">Public Domain</option>
<option value="Creative Commons Attribution 4.0 International">Creative Commons Attribution 4.0 International</option>
<option value="Creative Commons Attribution-ShareAlike 4.0 International">Creative Commons Attribution-ShareAlike 4.0 International</option>
<option value="Creative Commons Attribution-NoDerivatives 4.0 International">Creative Commons Attribution-NoDerivatives 4.0 International</option>
<option value="Creative Commons Attribution-NonCommercial 4.0 International">Creative Commons Attribution-NonCommercial 4.0 International</option>
<option value="Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International</option>
<option value="Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International">Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International</option>
<option value="None">None</option>
</select>
</fieldset>
<fieldset>
<label><input id="meme-nsfw-flag" name="nsfw" type="checkbox"/>NSFW</label>
</fieldset>
<fieldset>
<button data-action="upload image" class="__button-black" type="button">Submit</button>
</fieldset>
</form>
<script>
detectLanguageAndUpdate();
initCanvas();
setTimeout(() => {
$(".tour__content__meme__canvas__thumbnail").click();
}, 100);
</script>
`;
return socket.send(JSON.stringify({
"html": memeCreator,
"message": "updated html",
"selector": "#tour-loader"
}));
}
function generateTrendingContent(exampleNumber, displayTrendingContent) {
return getTrendingContent().then(response => {
if (!response || !response.success || response.success !== true || !response.data) return "";
@ -213,16 +359,6 @@ function generateTrendingContent(exampleNumber, displayTrendingContent) {
for (const data of trendingContentData) {
rawContentCollection.push(fetchMetadata({ claim: data.url, method: "resolve", example: exampleNumber }));
/*
if (exampleNumber === 1) {
rawContentCollection.push(fetchMetadata({ claim: data.url, method: "resolve", example: exampleNumber }));
}
if (exampleNumber === 3) {
rawContentCollection.push(fetchMetadata({ claim: data.url, method: "wallet_send", example: exampleNumber }));
}
*/
}
Promise.all(rawContentCollection).then(collection => {
@ -247,12 +383,12 @@ function generateTrendingContent(exampleNumber, displayTrendingContent) {
}
function getTrendingContent() {
return new Promise((resolve, reject) => {
return new Promise((resolve, reject) => { // eslint-disable-line
request({
method: "GET",
url: "https://api.lbry.io/file/list_trending"
}, (error, response, body) => {
if (error) reject(error);
if (error || !JSON.parse(body)) resolve("Issue fetching content"); // error
body = JSON.parse(body);
resolve(body);
});

View file

@ -6,7 +6,7 @@ initializeTour();
if (window.location.href.search && window.location.href.split("?url=")[1]) { // pre-fill Tour if search parameter exists
if (window.location.href.search && window.location.href.split("?url=")[1]) { // pre-fill example one if search parameter exists
const searchParameter = window.location.href.split("?url=")[1];
fetchMetadata(1, searchParameter);
}
@ -33,6 +33,12 @@ $("body").on("click", "[data-action]", event => {
break;
case "tour, example 1":
if ($("#tour-loader").hasClass("tour__content__meme")) {
$("#tour-loader").removeClass("tour__content__meme").addClass("tour__content__trends");
}
if ($("#tour-url")[0].style.display === "none") $("#tour-url").show();
$(".tour__sidebar__example").removeClass("active");
$(".tour__sidebar__example:nth-child(1)").addClass("active");
@ -46,18 +52,31 @@ $("body").on("click", "[data-action]", event => {
break;
case "tour, example 2":
if ($("#tour-loader").hasClass("tour__content__trends")) {
$("#tour-loader").removeClass("tour__content__trends").addClass("tour__content__meme");
}
$("#tour-url").hide();
$(".tour__sidebar__example").removeClass("active");
$(".tour__sidebar__example:nth-child(2)").addClass("active");
/*
$("#example1-page").hide();
$("#example2-page").show();
$(".hook__page__content__meme__thumbnail").click(); // preload canvas
$("#example3-page").hide();
*/
$("#tour-loader").html("");
$("#tour-results").html("");
send(JSON.stringify({
"message": `request for ${data.action}`
}));
break;
case "tour, example 3":
if ($("#tour-loader").hasClass("tour__content__meme")) {
$("#tour-loader").removeClass("tour__content__meme").addClass("tour__content__trends");
}
if ($("#tour-url")[0].style.display === "none") $("#tour-url").show();
$(".tour__sidebar__example").removeClass("active");
$(".tour__sidebar__example:nth-child(3)").addClass("active");
@ -79,8 +98,8 @@ $("body").on("click", "[data-action]", event => {
}
});
$("body").on("click", ".hook__page__content__meme__thumbnail", event => {
$(".hook__page__content__meme__thumbnail").removeClass("selected");
$("body").on("click", ".tour__content__meme__canvas__thumbnail", event => {
$(".tour__content__meme__canvas__thumbnail").removeClass("selected");
event.currentTarget.className += " selected";
updateCanvas(event.currentTarget);
@ -91,13 +110,13 @@ $("#fetch-claim-uri").on("keyup", function (e) {
if (key === 13 && $("#fetch-claim-uri").val()) fetchMetadata(1, $("#fetch-claim-uri").val());
});
$("#meme-top-line, #meme-bottom-line").on("keyup", () => updateCanvas());
$("body").on("keyup", "#meme-top-line, #meme-bottom-line", () => updateCanvas());
// H E L P E R S
function detectLanguageAndUpdate() {
function detectLanguageAndUpdate() { // eslint-disable-line
const compare = (array1, array2) => array2.filter(value => array2.indexOf(value)); // compare two arrays and get match(es)
const memeLocaleObject = $("#meme-language").children();
const memeLocales = [];
@ -128,9 +147,6 @@ function initializeTour() {
TODO:
- Account for someone wanting to make multiple resolves
*/
// detectLanguageAndUpdate();
// initCanvas();
}
@ -147,7 +163,7 @@ function fetchMetadata(exampleNumber, data) {
"example": exampleNumber
}));
$("#fetch-claim-uri").val(data); // if (!$("#fetch-claim-uri").val()) $("#fetch-claim-uri").val(data);
$("#fetch-claim-uri").val(data);
$("#tour-results").html(`
<pre><code class="language-bash">
@ -238,7 +254,7 @@ function clearCanvas(canvas) {
ctx.restore();
}
function initCanvas() {
function initCanvas() { // eslint-disable-line
const canvas = document.getElementById("meme-canvas");
const canvasWidth = 400;
const canvasHeight = 300;

View file

@ -46,7 +46,7 @@ function sidebar() { // TODO: Save tutorial position to localStorage
function example1() {
return html`
<div class="tour__content__urlbar">
<div class="tour__content__urlbar" id="tour-url">
<span>lbry://</span><input id="fetch-claim-uri" placeholder="&thinsp;Enter a LBRY address or select an example below" type="text"/>
<button class="button" data-action="execute claim" type="button">Resolve</button>
</div>