Feedback for completing examples

This commit is contained in:
ポール ウェッブ 2018-09-27 13:00:34 -05:00
parent c0b0d66467
commit f72053b29d
6 changed files with 150 additions and 162 deletions

View file

@ -51,6 +51,7 @@ function navigation() { // TODO: Save tutorial position to localStorage
data-action="tour, example 1"
data-description="In this example, you can see what runs under the hood when selecting content to view in the LBRY app."
data-example="1"
data-success="<strong>Success</strong> You resolved a claim, which is a <em>fancy</em> way of saying you searched for a piece of content and got back all the metadata associated with it (if it exists)."
>
<button type="button">Resolve</button>
<span>Get details of media (aka, "claim" metadata)</span>
@ -61,6 +62,7 @@ function navigation() { // TODO: Save tutorial position to localStorage
data-action="tour, example 2"
data-description="Sometimes you want to create content, not just consume it. In this example, you can create a meme and upload it to LBRY!"
data-example="2"
data-success="<strong>Meme-a-riffic</strong> You've just contributed to the growing expanse that is the meme industry. Where will your meme go next? YOU DECIDE!"
>
<button type="button">Publish</button>
<span>Create a meme and upload it to the LBRY blockchain</span>
@ -71,6 +73,7 @@ function navigation() { // TODO: Save tutorial position to localStorage
data-action="tour, example 3"
data-description="In the LBRY app, you can financially support your favorite creators by donating LBRY Coin (LBC). In this example, we are donating LBC in your stead."
data-example="3"
data-success="<strong>Kudos</strong> You've just supported a creator with LBC (or, LBRY credits) with our own stash of LBC (you'd use your own IRL). You're basically saying, \"thanks for this great content, please continue!\" and that's awesome. You're awesome."
>
<button type="button">Support</button>
<span>Support creators on LBRY with a tip, on us!</span>

View file

@ -1,62 +0,0 @@
"use strict";
// P A C K A G E S
import dedent from "dedent";
import html from "choo/html";
import raw from "choo/html/raw";
// E X P O R T
export default function () {
return dedent`
<section class="tour">
<ul class="tour__sidebar">
${raw(sidebar())}
</ul>
<section class="tour__content">${raw(example1())}</section>
</section>
`;
}
// H E L P E R S
function example1() {
return html`
<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>
<div class="tour__content__trends" id="tour-loader"></div>
<div id="tour-results"></div>
`;
}
function sidebar() { // TODO: Save tutorial position to localStorage
return dedent`
<li class="tour__sidebar__example" data-action="tour, example 1" data-example="1">
<button type="button">Resolve a claim</button>
<span>Get details of media (aka, "claim" metadata)</span><br/>
<span>In this example, you can see what runs under the hood when selecting content to view in the LBRY app.</span>
</li>
<li class="tour__sidebar__example" data-action="tour, example 2" data-example="2">
<button type="button">Publish content</button>
<span>Create a meme and upload it to the LBRY blockchain</span><br/>
<span>Sometimes you want to create content, not just consume it. In this example, you can create a meme and upload it to LBRY!</span>
</li>
<li class="tour__sidebar__example" data-action="tour, example 3" data-example="3">
<button type="button">Support with LBC</button>
<span>Support creators on LBRY with a tip, on us!</span><br/>
<span>In the LBRY app, you can financially support your favorite creators by donating LBRY Coin (LBC). In this example, we are donating LBC in your stead.</span>
</li>
`;
}

View file

@ -30,7 +30,32 @@ function initializeWebSocketConnection() {
document.querySelector(data.selector).innerHTML = data.html;
document.getElementById("emailAddress").value = "";
document.getElementById("emailMessage").innerHTML = "";
if (document.getElementById("temp-loader")) document.getElementById("temp-loader").style.display = "none";
// `data.example` is added when updating HTML.
// This is when the results of an example are sent to the client.
if (data.example) {
if (!document.querySelector(`[data-example="${data.example}"`).classList.contains("completed")) {
document.getElementById("tour-example-description").classList.remove("success");
}
document.querySelector(`[data-example="${data.example}"`).classList.add("completed");
document.getElementById("tour-example-description").classList.add("success");
document.getElementById("tour-example-description").innerHTML =
document.querySelector(`[data-example="${data.example}"`).dataset.success;
}
// If `data.example` isn't found, reset the description area.
else {
document.getElementById("tour-example-description").classList.remove("success");
document.getElementById("tour-example-description").innerHTML =
document.querySelector(".tour__navigation__example.active").dataset.description;
}
if (document.getElementById("temp-loader"))
document.getElementById("temp-loader").style.display = "none";
document.querySelector(".tour").classList.remove("waiting");
break;

View file

@ -92,7 +92,7 @@ module.exports = exports = (data, socket) => {
body.file_path = uploadResponse.filename;
return publishMeme(body).then(publishResponse => {
let explorerNotice = "";
// let explorerNotice = "";
if (publishResponse.error) {
socket.send(JSON.stringify({
@ -112,19 +112,22 @@ module.exports = exports = (data, socket) => {
return;
}
/*
if (
publishResponse.result &&
publishResponse.result.txid
) explorerNotice = `
<p>If you want proof of the tip you just gave, <a href="https://explorer.lbry.io/tx/${publishResponse.result.txid}" target="_blank" title="Your tip, on our blockchain explorer" rel="noopener noreferrer">check it out</a> on our blockchain explorer!</p>
`;
*/
const renderedCode = prism.highlight(stringifyObject(publishResponse, { indent: " ", singleQuotes: false }), prism.languages.json, "json");
return socket.send(JSON.stringify({
"example": data.example,
"html": raw(`
<h3>Response</h3>
${explorerNotice}
<!--/ explorerNotice /-->
<pre><code class="language-json">${renderedCode}</code></pre>
`),
"message": "updated html",
@ -147,7 +150,7 @@ module.exports = exports = (data, socket) => {
}
return new Promise((resolve, reject) => { // eslint-disable-line
let explorerNotice = "";
// let explorerNotice = "";
request({
body: body,
@ -179,20 +182,23 @@ module.exports = exports = (data, socket) => {
return resolve(body.error);
}
/*
if (
body.result &&
body.result.txid
) explorerNotice = `
<p>If you want proof of the tip you just gave on behalf of LBRY, <a href="https://explorer.lbry.io/tx/${body.result.txid}" target="_blank" title="Your tip, on our blockchain explorer" rel="noopener noreferrer">check it out</a> on our blockchain explorer!</p>
`;
*/
if (socket) {
const renderedCode = prism.highlight(stringifyObject(body, { indent: " ", singleQuotes: false }), prism.languages.json, "json");
return socket.send(JSON.stringify({
"example": data.example,
"html": raw(`
<h3>Response</h3>
${explorerNotice}
<!--/ explorerNotice /-->
<pre><code class="language-json">${renderedCode}</code></pre>
`),
"message": "updated html",

View file

@ -456,10 +456,22 @@
*/
.tour__description {
background-color: rgba($black, 0.05);
cursor: default;
font-size: 1rem;
line-height: 1.33;
padding: 1rem;
&:not(.success) {
background-color: rgba($black, 0.05);
text-align: center;
}
&.success {
background-color: rgba($teal, 0.05);
strong {
display: block;
text-transform: uppercase;
}
}
}

View file

@ -39,6 +39,7 @@ module.exports = exports = (socket, action) => {
case (action.message === "landed on tour"):
generateContent(1, result => {
socket.send(JSON.stringify({
// "example": 1,
"html": result,
"message": "updated html",
"selector": "#tour-loader"
@ -49,6 +50,7 @@ module.exports = exports = (socket, action) => {
case (action.message === "request for tour, example 1"):
generateContent(1, result => {
socket.send(JSON.stringify({
// "example": 1,
"html": result,
"message": "updated html",
"selector": "#tour-loader"
@ -63,6 +65,7 @@ module.exports = exports = (socket, action) => {
case (action.message === "request for tour, example 3"):
generateContent(3, result => {
socket.send(JSON.stringify({
// "example": 3,
"html": result,
"message": "updated html",
"selector": "#tour-loader"
@ -75,7 +78,7 @@ module.exports = exports = (socket, action) => {
break;
default:
process.stdout.write(action);
console.log(action); // eslint-disable-line
break;
}
};
@ -84,6 +87,98 @@ module.exports = exports = (socket, action) => {
// H E L P E R S
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(`
<figure class="tour__content__trend">
<img alt="${part.name}" data-action="choose claim" data-claim-id="${exampleNumber === 1 ? part.name : part.claim_id}" src="${part.value.stream.metadata.thumbnail}"/>
<figcaption data-action="choose claim" data-claim-id="${exampleNumber === 1 ? part.name : part.claim_id}">
${part.value.stream.metadata.title}
<span>${part.channel_name}</span>
</figcaption>
</figure>
`);
} catch (err) {
return; // TODO: Return nice error message
}
}
renderedContentCollection.push(`
<script>
document.getElementById("tour-example-description").textContent = document.querySelector("[data-action='tour, example 1']").dataset.description
</script>
`);
displayTrendingContent(renderedContentCollection.join(""));
});
});
}
if (exampleNumber === 3) {
const approvedUrls = [
"LBRY#3db81c073f82fd1bb670c65f526faea3b8546720",
"correlation-can-imply-causation#173412f5b1b7aa63a752e8832406aafd9f1ecb4e",
"thanos-is-the-protagonist-how-infinity#2a7f5db2678177435b1dee6c9e38e035ead450b6nyte",
"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 = [];
for (const url of approvedUrls) {
rawContentCollection.push(fetchMetadata({ claim: url, method: "resolve", example: exampleNumber }));
}
Promise.all(rawContentCollection).then(collection => {
for (const part of collection) {
try {
renderedContentCollection.push(`
<figure class="tour__content__trend">
<img alt="${part.name}" data-action="choose claim" data-claim-id="${exampleNumber === 1 ? part.name : part.claim_id}" src="${part.value.stream.metadata.thumbnail}"/>
<figcaption data-action="choose claim" data-claim-id="${exampleNumber === 1 ? part.name : part.claim_id}">
${part.value.stream.metadata.title}
<span>${part.channel_name}</span>
</figcaption>
</figure>
`);
} catch (err) {
return; // TODO: Return nice error message
}
}
renderedContentCollection.push(`
<script>
document.getElementById("tour-example-description").textContent = document.querySelector("[data-action='tour, example 3']").dataset.description
</script>
`);
displayTrendingContent(renderedContentCollection.join(""));
});
}
}
function generateMemeCreator(socket) {
const images = [
{
@ -210,104 +305,13 @@ function generateMemeCreator(socket) {
`;
return socket.send(JSON.stringify({
// "example": 2,
"html": memeCreator,
"message": "updated html",
"selector": "#tour-loader"
}));
}
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(`
<figure class="tour__content__trend">
<img alt="${part.name}" data-action="choose claim" data-claim-id="${exampleNumber === 1 ? part.name : part.claim_id}" src="${part.value.stream.metadata.thumbnail}"/>
<figcaption data-action="choose claim" data-claim-id="${exampleNumber === 1 ? part.name : part.claim_id}">
${part.value.stream.metadata.title}
<span>${part.channel_name}</span>
</figcaption>
</figure>
`);
} catch (err) {
return; // TODO: Return nice error message
}
}
renderedContentCollection.push(`
<script>
document.getElementById("tour-example-description").textContent = document.querySelector("[data-action='tour, example 1']").dataset.description
</script>
`);
displayTrendingContent(renderedContentCollection.join(""));
});
});
}
if (exampleNumber === 3) {
const approvedUrls = [
"LBRY#3db81c073f82fd1bb670c65f526faea3b8546720",
"correlation-can-imply-causation#173412f5b1b7aa63a752e8832406aafd9f1ecb4e",
"thanos-is-the-protagonist-how-infinity#2a7f5db2678177435b1dee6c9e38e035ead450b6nyte",
"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 = [];
for (const url of approvedUrls) {
rawContentCollection.push(fetchMetadata({ claim: url, method: "resolve", example: exampleNumber }));
}
Promise.all(rawContentCollection).then(collection => {
for (const part of collection) {
try {
renderedContentCollection.push(`
<figure class="tour__content__trend">
<img alt="${part.name}" data-action="choose claim" data-claim-id="${exampleNumber === 1 ? part.name : part.claim_id}" src="${part.value.stream.metadata.thumbnail}"/>
<figcaption data-action="choose claim" data-claim-id="${exampleNumber === 1 ? part.name : part.claim_id}">
${part.value.stream.metadata.title}
<span>${part.channel_name}</span>
</figcaption>
</figure>
`);
} catch (err) {
return; // TODO: Return nice error message
}
}
renderedContentCollection.push(`
<script>
document.getElementById("tour-example-description").textContent = document.querySelector("[data-action='tour, example 3']").dataset.description
</script>
`);
displayTrendingContent(renderedContentCollection.join(""));
});
}
}
function getTrendingContent() {
return new Promise((resolve, reject) => { // eslint-disable-line
request({