feat: startup splash for user configuration
This commit is contained in:
parent
4dd15d52bb
commit
56c315c301
|
@ -10,6 +10,13 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
<div id="start-splash">
|
||||||
|
<img class="center" src="oct.jpg"></img>
|
||||||
|
<input class="center" type="text" id="username" placeholder="Choose a username!" onkeyup="usernameInputUpdated(event)"></input>
|
||||||
|
<!--<ul class="center" id="interest-selection"></ul>-->
|
||||||
|
<a id="advance-button" class="center" href="#" onclick="advanceSplash()">Choose some interests!</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- blocks are added by JavaScript so container starts empty -->
|
<!-- blocks are added by JavaScript so container starts empty -->
|
||||||
<div id="block-container"></div>
|
<div id="block-container"></div>
|
||||||
|
|
||||||
|
|
207
main.js
207
main.js
|
@ -8,7 +8,34 @@ const adjectives = [
|
||||||
"analytical", "motivated", "solution-focused", "committed", "agile"
|
"analytical", "motivated", "solution-focused", "committed", "agile"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const interests = [
|
||||||
|
"music", "comedy", "travel", "technology", "hiking", "nature", "food", "movies",
|
||||||
|
"culture", "art", "activism", "community", "books", "baking", "creativity", "fitness",
|
||||||
|
"fashion", "wellness", "history", "adventure", "gaming", "gardening", "sustainability",
|
||||||
|
"coding", "coffee", "DIY", "crafts", "pets", "animals", "humor", "languages", "sports",
|
||||||
|
"competition", "meditation", "mindfulness", "design", "concerts", "innovation", "museums",
|
||||||
|
"future", "writing", "relaxation", "photography", "compassion", "nutrition", "style",
|
||||||
|
"restaurants", "gadgets", "inspiration", "literature", "outdoors", "wildlife", "conservation",
|
||||||
|
"motivation", "beauty", "culinary arts", "festivals", "exploration", "knowledge", "camping",
|
||||||
|
"archeology", "triathlon", "endurance", "luxury", "wine", "fine dining", "audio equipment",
|
||||||
|
"sound quality", "startups", "entrepreneurship", "extreme sports", "philosophy", "survival",
|
||||||
|
"environment", "politics", "running", "gastronomy", "genres", "software", "current events",
|
||||||
|
"recipes", "listening", "discovery", "expression", "reading", "recommendations", "news",
|
||||||
|
"analysis", "trends", "dining", "reviews", "rescue", "welfare", "health", "artists", "cooking"
|
||||||
|
];
|
||||||
|
|
||||||
|
var localUser = {
|
||||||
|
user: null,
|
||||||
|
interests: [],
|
||||||
|
postingStyle: null
|
||||||
|
};
|
||||||
|
var splashStep = 0;
|
||||||
|
const maxInterests = 3;
|
||||||
|
|
||||||
|
// configuration
|
||||||
const localMode = false;
|
const localMode = false;
|
||||||
|
const showSplash = false;
|
||||||
|
|
||||||
const blockContainer = document.getElementById("block-container");
|
const blockContainer = document.getElementById("block-container");
|
||||||
const postCountElem = document.getElementById("post-count");
|
const postCountElem = document.getElementById("post-count");
|
||||||
const postTotalElem = document.getElementById("post-total");
|
const postTotalElem = document.getElementById("post-total");
|
||||||
|
@ -215,13 +242,18 @@ function makePostFromJson(json) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCurrentUser() {
|
function getCurrentUser() {
|
||||||
|
// return some default values if we didn't do the initial configuration
|
||||||
|
if (!showSplash) {
|
||||||
|
return {
|
||||||
|
"user": "ktyl",
|
||||||
|
"interests": ["trains", "trains", "trains"],
|
||||||
|
"posting_style": "borderline maniacal train content"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"user": "theChief",
|
"user": localUser.user,
|
||||||
"interests": [
|
"interests": localUser.interests,
|
||||||
"gen-ai",
|
|
||||||
"blockchain",
|
|
||||||
"nfts"
|
|
||||||
],
|
|
||||||
"posting_style": "just the most truly inane takes"
|
"posting_style": "just the most truly inane takes"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -243,12 +275,10 @@ function writePost(postCallback) {
|
||||||
body: "local mode post (local mode post)"
|
body: "local mode post (local mode post)"
|
||||||
});
|
});
|
||||||
postCallback(post);
|
postCallback(post);
|
||||||
//blockContainer.insertBefore(post.getElement(), getTopPost());
|
|
||||||
} else {
|
} else {
|
||||||
fetch("https://api.wayfarer.games/singularity/generate-posts.php", request)
|
fetch("https://api.wayfarer.games/singularity/generate-posts.php", request)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(makePostFromJson)
|
.then(makePostFromJson)
|
||||||
//.then(post => blockContainer.insertBefore(post.getElement(), getTopPost()));
|
|
||||||
.then(postCallback);
|
.then(postCallback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -302,6 +332,162 @@ function init() {
|
||||||
window.addEventListener("scroll", handleInfiniteScroll);
|
window.addEventListener("scroll", handleInfiniteScroll);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function chooseInterest(interest) {
|
||||||
|
if (localUser.interests.length == maxInterests) {
|
||||||
|
console.error(`can't choose more than ${maxInterests} interests`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
localUser.interests.push(interest);
|
||||||
|
|
||||||
|
const interestsTextElem = document.getElementById("interests-text");
|
||||||
|
|
||||||
|
if (localUser.interests.length != maxInterests) {
|
||||||
|
interestsTextElem.innerHTML = getInterestsTextValue(localUser.interests.length);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const advanceButtonElem = document.getElementById("advance-button");
|
||||||
|
advanceButtonElem.innerHTML = "Begin!";
|
||||||
|
advanceButtonElem.style.visibility = "visible";
|
||||||
|
|
||||||
|
interestsTextElem.remove();
|
||||||
|
const interestsListElem = document.getElementById("interest-selection");
|
||||||
|
interestsListElem.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getInterestsSubset() {
|
||||||
|
const count = 20;
|
||||||
|
let subset = [];
|
||||||
|
|
||||||
|
while (subset.length < count) {
|
||||||
|
const interest = interests[Math.floor(Math.random() * interests.length)];
|
||||||
|
|
||||||
|
// skip if it's already included
|
||||||
|
if (subset.includes(interest))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// skip if the user has already chosen it
|
||||||
|
if (localUser.interests.includes(interest))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
subset.push(interest);
|
||||||
|
}
|
||||||
|
|
||||||
|
return subset;
|
||||||
|
}
|
||||||
|
|
||||||
|
function populateSplashInterests() {
|
||||||
|
|
||||||
|
const rootElem = document.getElementById("interest-selection");
|
||||||
|
if (rootElem == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// clear existing interests
|
||||||
|
rootElem.innerHTML = "";
|
||||||
|
|
||||||
|
const interestsSubset = getInterestsSubset();
|
||||||
|
|
||||||
|
for (let i = 0; i < interestsSubset.length; i++) {
|
||||||
|
const interest = interestsSubset[i];
|
||||||
|
const listItemElem = document.createElement("li");
|
||||||
|
rootElem.appendChild(listItemElem);
|
||||||
|
|
||||||
|
const buttonElem = document.createElement("a");
|
||||||
|
buttonElem.innerHTML = `#${interest}`;
|
||||||
|
buttonElem.addEventListener("click", () => {
|
||||||
|
chooseInterest(interest);
|
||||||
|
populateSplashInterests();
|
||||||
|
});
|
||||||
|
listItemElem.appendChild(buttonElem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getInterestsTextValue(numChosenInterests) {
|
||||||
|
return `Choose some interests! (${numChosenInterests}/${maxInterests})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function usernameInputUpdated(event) {
|
||||||
|
const inputElem = document.getElementById("username");
|
||||||
|
const buttonElem = document.getElementById("advance-button");
|
||||||
|
const isNameEmpty = inputElem.value.length == "";
|
||||||
|
buttonElem.style.visibility = isNameEmpty ? "hidden" : "visible";
|
||||||
|
|
||||||
|
if (isNameEmpty)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (event.key == "Enter") {
|
||||||
|
advanceSplash();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function chooseName() {
|
||||||
|
// check that a name has been chosen
|
||||||
|
const inputElem = document.getElementById("username");
|
||||||
|
if (!inputElem.value) {
|
||||||
|
console.error("a name needs to be entered!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
splashStep = 1;
|
||||||
|
localUser.user = inputElem.value;
|
||||||
|
|
||||||
|
// TODO: disable button until name has been chosen
|
||||||
|
|
||||||
|
// TODO: insert interest selection elements before name input
|
||||||
|
//writePost(post => blockContainer.insertBefore(post.getElement(), getTopPost()));
|
||||||
|
const splashElem = document.getElementById("start-splash");
|
||||||
|
|
||||||
|
const interestsTextElem = document.createElement("p");
|
||||||
|
interestsTextElem.innerHTML = getInterestsTextValue(0);
|
||||||
|
interestsTextElem.id = "interests-text";
|
||||||
|
interestsTextElem.className = "center";
|
||||||
|
splashElem.insertBefore(interestsTextElem, inputElem);
|
||||||
|
|
||||||
|
const interestsListElem = document.createElement("ul");
|
||||||
|
interestsListElem.className = "center";
|
||||||
|
interestsListElem.id = "interest-selection";
|
||||||
|
splashElem.insertBefore(interestsListElem, inputElem);
|
||||||
|
|
||||||
|
populateSplashInterests();
|
||||||
|
|
||||||
|
// remove name input
|
||||||
|
inputElem.remove();
|
||||||
|
|
||||||
|
const advanceButtonElem = document.getElementById("advance-button");
|
||||||
|
advanceButtonElem.style.visibility = "hidden";
|
||||||
|
|
||||||
|
splashStep = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function chooseInterests() {
|
||||||
|
if (localUser.interests.length < maxInterests) {
|
||||||
|
console.error(`need to choose ${maxInterests} interests`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("TODO: generate user posting style");
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeSplash() {
|
||||||
|
document.getElementById("start-splash").remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
function advanceSplash() {
|
||||||
|
switch(splashStep) {
|
||||||
|
case 0:
|
||||||
|
chooseName();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
chooseInterests();
|
||||||
|
removeSplash();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.error(`nothing defined for splash step ${splashStep}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function loadDataFromEndpoint(endpoint, callback) {
|
function loadDataFromEndpoint(endpoint, callback) {
|
||||||
fetch(endpoint)
|
fetch(endpoint)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
|
@ -311,6 +497,7 @@ function loadDataFromEndpoint(endpoint, callback) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const usersUrl = localMode ? "users.json" : "https://api.wayfarer.games/singularity/users.json";
|
const usersUrl = localMode ? "users.json" : "https://api.wayfarer.games/singularity/users.json";
|
||||||
const postsUrl = localMode ? "posts.json" : "https://api.wayfarer.games/singularity/posts.json";
|
const postsUrl = localMode ? "posts.json" : "https://api.wayfarer.games/singularity/posts.json";
|
||||||
loadDataFromEndpoint(usersUrl, json => { users = json.users; });
|
loadDataFromEndpoint(usersUrl, json => { users = json.users; });
|
||||||
|
@ -333,3 +520,7 @@ loadDataFromEndpoint(postsUrl, json => {
|
||||||
|
|
||||||
postTotalElem.innerHTML = Object.keys(posts).length;
|
postTotalElem.innerHTML = Object.keys(posts).length;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!showSplash) {
|
||||||
|
removeSplash();
|
||||||
|
}
|
||||||
|
|
96
styles.css
96
styles.css
|
@ -1,15 +1,17 @@
|
||||||
:root {
|
:root {
|
||||||
--header-height: 64px;
|
--header-height: 64px;
|
||||||
--background-color: #374955;
|
--blue-gray: #374955;
|
||||||
--accent-color: #86b1cc;
|
--sky-blue: #86b1cc;
|
||||||
--comment-column-width: 3px;
|
--comment-column-width: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
font-family: "Poppins", sans-serif;
|
font-family: "Poppins", sans-serif;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
background-color: var(--background-color);
|
background-color: var(--sky-blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (min-width: 800px) {
|
@media only screen and (min-width: 800px) {
|
||||||
|
@ -23,6 +25,77 @@ body {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#start-splash {
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
background-color: white;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
display: block;
|
||||||
|
margin: auto;
|
||||||
|
padding: auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#start-splash img {
|
||||||
|
max-width: 40vw;
|
||||||
|
margin-top: 10vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
#start-splash input {
|
||||||
|
margin: 2em auto;
|
||||||
|
border: none;
|
||||||
|
background-color: var(--sky-blue);
|
||||||
|
color: white;
|
||||||
|
border-radius: 16px;
|
||||||
|
font-size: 1.5em;
|
||||||
|
padding: 4px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#advance-button {
|
||||||
|
width: 20%;
|
||||||
|
margin: 2em auto;
|
||||||
|
color: white;
|
||||||
|
background-color: var(--sky-blue);
|
||||||
|
text-align: center;
|
||||||
|
visibility: hidden;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#interests-text {
|
||||||
|
color: var(--blue-gray);
|
||||||
|
}
|
||||||
|
|
||||||
|
#interest-selection {
|
||||||
|
width: 80%;
|
||||||
|
padding: 8px;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#interest-selection li {
|
||||||
|
display: inline;
|
||||||
|
margin: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#interest-selection li a {
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 16px;
|
||||||
|
color: white;
|
||||||
|
background-color: var(--sky-blue);
|
||||||
|
transition: all 200ms ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#interest-selection li a:hover {
|
||||||
|
background-color: var(--blue-gray);
|
||||||
|
}
|
||||||
|
|
||||||
#block-container {
|
#block-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -51,19 +124,20 @@ body {
|
||||||
border-radius: calc(var(--header-height) / 2);
|
border-radius: calc(var(--header-height) / 2);
|
||||||
margin-top: calc(var(--header-height) / 8);
|
margin-top: calc(var(--header-height) / 8);
|
||||||
padding: calc(var(--header-height) / 8) calc(var(--header-height) / 4);
|
padding: calc(var(--header-height) / 8) calc(var(--header-height) / 4);
|
||||||
background-color: var(--accent-color);
|
background-color: var(--sky-blue);
|
||||||
color: var(--backround-color);
|
color: white;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 200ms ease-in-out;
|
transition: all 200ms ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reply-button:hover {
|
.reply-button:hover {
|
||||||
background-color: var(--background-color);
|
background-color: var(--blue-gray);
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reply-button:active {
|
.reply-button:active {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
color: var(--blue-gray);
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-header {
|
.post-header {
|
||||||
|
@ -82,16 +156,16 @@ body {
|
||||||
|
|
||||||
.write-post {
|
.write-post {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: var(--background-color);
|
color: var(--blue-gray);
|
||||||
}
|
}
|
||||||
|
|
||||||
.write-post:hover {
|
.write-post:hover {
|
||||||
background-color: var(--accent-color);
|
background-color: var(--sky-blue);
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.write-post:active {
|
.write-post:active {
|
||||||
background-color: var(---background-color);
|
background-color: var(---blue-gray);
|
||||||
}
|
}
|
||||||
|
|
||||||
.write-post h2 {
|
.write-post h2 {
|
||||||
|
@ -102,7 +176,7 @@ body {
|
||||||
|
|
||||||
a {
|
a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: var(--background-color);
|
color: var(--blue-gray);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pfp {
|
.pfp {
|
||||||
|
@ -118,7 +192,7 @@ a {
|
||||||
|
|
||||||
.post:not(.block) {
|
.post:not(.block) {
|
||||||
margin-top: calc(var(--header-height) / 4);
|
margin-top: calc(var(--header-height) / 4);
|
||||||
border-left: var(--comment-column-width) solid var(--accent-color);
|
border-left: var(--comment-column-width) solid var(--sky-blue);
|
||||||
padding-left: calc(var(--header-height) / 2 - var(--comment-column-width));
|
padding-left: calc(var(--header-height) / 2 - var(--comment-column-width));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue