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-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-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-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> <button type="button">Resolve</button>
<span>Get details of media (aka, "claim" metadata)</span> <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-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-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-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> <button type="button">Publish</button>
<span>Create a meme and upload it to the LBRY blockchain</span> <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-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-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-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> <button type="button">Support</button>
<span>Support creators on LBRY with a tip, on us!</span> <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.querySelector(data.selector).innerHTML = data.html;
document.getElementById("emailAddress").value = ""; document.getElementById("emailAddress").value = "";
document.getElementById("emailMessage").innerHTML = ""; 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"); document.querySelector(".tour").classList.remove("waiting");
break; break;

View file

@ -92,7 +92,7 @@ module.exports = exports = (data, socket) => {
body.file_path = uploadResponse.filename; body.file_path = uploadResponse.filename;
return publishMeme(body).then(publishResponse => { return publishMeme(body).then(publishResponse => {
let explorerNotice = ""; // let explorerNotice = "";
if (publishResponse.error) { if (publishResponse.error) {
socket.send(JSON.stringify({ socket.send(JSON.stringify({
@ -112,19 +112,22 @@ module.exports = exports = (data, socket) => {
return; return;
} }
/*
if ( if (
publishResponse.result && publishResponse.result &&
publishResponse.result.txid publishResponse.result.txid
) explorerNotice = ` ) 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> <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"); const renderedCode = prism.highlight(stringifyObject(publishResponse, { indent: " ", singleQuotes: false }), prism.languages.json, "json");
return socket.send(JSON.stringify({ return socket.send(JSON.stringify({
"example": data.example,
"html": raw(` "html": raw(`
<h3>Response</h3> <h3>Response</h3>
${explorerNotice} <!--/ explorerNotice /-->
<pre><code class="language-json">${renderedCode}</code></pre> <pre><code class="language-json">${renderedCode}</code></pre>
`), `),
"message": "updated html", "message": "updated html",
@ -147,7 +150,7 @@ module.exports = exports = (data, socket) => {
} }
return new Promise((resolve, reject) => { // eslint-disable-line return new Promise((resolve, reject) => { // eslint-disable-line
let explorerNotice = ""; // let explorerNotice = "";
request({ request({
body: body, body: body,
@ -179,20 +182,23 @@ module.exports = exports = (data, socket) => {
return resolve(body.error); return resolve(body.error);
} }
/*
if ( if (
body.result && body.result &&
body.result.txid body.result.txid
) explorerNotice = ` ) 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> <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) { if (socket) {
const renderedCode = prism.highlight(stringifyObject(body, { indent: " ", singleQuotes: false }), prism.languages.json, "json"); const renderedCode = prism.highlight(stringifyObject(body, { indent: " ", singleQuotes: false }), prism.languages.json, "json");
return socket.send(JSON.stringify({ return socket.send(JSON.stringify({
"example": data.example,
"html": raw(` "html": raw(`
<h3>Response</h3> <h3>Response</h3>
${explorerNotice} <!--/ explorerNotice /-->
<pre><code class="language-json">${renderedCode}</code></pre> <pre><code class="language-json">${renderedCode}</code></pre>
`), `),
"message": "updated html", "message": "updated html",

View file

@ -456,10 +456,22 @@
*/ */
.tour__description { .tour__description {
background-color: rgba($black, 0.05);
cursor: default; cursor: default;
font-size: 1rem; font-size: 1rem;
line-height: 1.33; line-height: 1.33;
padding: 1rem; padding: 1rem;
&:not(.success) {
background-color: rgba($black, 0.05);
text-align: center; 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"): case (action.message === "landed on tour"):
generateContent(1, result => { generateContent(1, result => {
socket.send(JSON.stringify({ socket.send(JSON.stringify({
// "example": 1,
"html": result, "html": result,
"message": "updated html", "message": "updated html",
"selector": "#tour-loader" "selector": "#tour-loader"
@ -49,6 +50,7 @@ module.exports = exports = (socket, action) => {
case (action.message === "request for tour, example 1"): case (action.message === "request for tour, example 1"):
generateContent(1, result => { generateContent(1, result => {
socket.send(JSON.stringify({ socket.send(JSON.stringify({
// "example": 1,
"html": result, "html": result,
"message": "updated html", "message": "updated html",
"selector": "#tour-loader" "selector": "#tour-loader"
@ -63,6 +65,7 @@ module.exports = exports = (socket, action) => {
case (action.message === "request for tour, example 3"): case (action.message === "request for tour, example 3"):
generateContent(3, result => { generateContent(3, result => {
socket.send(JSON.stringify({ socket.send(JSON.stringify({
// "example": 3,
"html": result, "html": result,
"message": "updated html", "message": "updated html",
"selector": "#tour-loader" "selector": "#tour-loader"
@ -75,7 +78,7 @@ module.exports = exports = (socket, action) => {
break; break;
default: default:
process.stdout.write(action); console.log(action); // eslint-disable-line
break; break;
} }
}; };
@ -84,6 +87,98 @@ module.exports = exports = (socket, action) => {
// H E L P E R S // 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) { function generateMemeCreator(socket) {
const images = [ const images = [
{ {
@ -210,104 +305,13 @@ function generateMemeCreator(socket) {
`; `;
return socket.send(JSON.stringify({ return socket.send(JSON.stringify({
// "example": 2,
"html": memeCreator, "html": memeCreator,
"message": "updated html", "message": "updated html",
"selector": "#tour-loader" "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() { function getTrendingContent() {
return new Promise((resolve, reject) => { // eslint-disable-line return new Promise((resolve, reject) => { // eslint-disable-line
request({ request({