2024-07-14 02:46:48 +02:00
var users = [ ] ;
var posts = { } ;
2024-08-04 16:02:19 +02:00
const adjectives = [
"dynamic" , "strategic" , "innovative" , "passionate" , "results-oriented" ,
"proactive" , "visionary" , "collaborative" , "driven" , "empathetic" ,
"adaptable" , "resilient" , "resourceful" , "detail-oriented" , "inspirational" ,
"analytical" , "motivated" , "solution-focused" , "committed" , "agile"
] ;
2024-08-04 20:15:29 +02:00
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"
] ;
2024-08-08 22:06:46 +02:00
const postingStyles = [
"Sometimes gets over excited and replies in ALL CAPS" ,
"Posts jokes exclusively. Always posts jokes. Replies are usually quite funny and witty. Does not ever ask questions" ,
"Posts exactly what is on their mind at any given time, usually not related to anything. Replies are a little bit more focused, but still not entirely on topic" ,
"Aggressively tries to relate everything to an unrelated hobby" ,
"Types in a rush so ends up making lots of spelling mistakes. At least two spelling mistakes in every reply." ,
"Constantly brings up a major life achievement, every reply mentions this milestone." ,
"Incredibly sarcastic in every single reply. Always sarcastic. Reply must be sarcastic." ,
"Is a little bit horny all the time. Posts are ever so slightly sexually suggestive. Always flirts given the opportunity" ,
"Always PUMPED UP, replies use lots of CAPITAL LETTERS and communicate how excited the user is. Lots of capital letters." ,
"Quick to anger, likes to antagonise. Very negative. Replies from this user do not ever say anything positive. Ever." ,
"Always plays devil's advocate. Replies from this user always go against what the original post said."
] ;
2024-08-04 20:15:29 +02:00
var localUser = {
user : null ,
interests : [ ] ,
postingStyle : null
} ;
var splashStep = 0 ;
const maxInterests = 3 ;
// configuration
2024-08-03 15:16:44 +02:00
const localMode = false ;
2024-08-10 20:32:54 +02:00
const showSplash = false ;
2024-08-04 20:15:29 +02:00
2024-07-17 01:08:03 +02:00
const blockContainer = document . getElementById ( "block-container" ) ;
2024-07-11 21:13:17 +02:00
const loader = document . getElementById ( "loader" ) ;
2024-08-10 15:43:01 +02:00
// some state
var isWritingPost = false ;
var isWritingReply = false ;
2024-07-25 00:35:30 +02:00
// define a variable for how many posts we want to increase the page by
2024-07-11 22:19:51 +02:00
const postIncrease = 9 ;
2024-07-11 21:13:17 +02:00
// and define a value to determine which page we're on
let currentPage = 1 ;
2024-07-20 13:55:10 +02:00
// how many times can we increase the content until we reach the max limit?
function getPageCount ( ) {
return Math . ceil ( Object . keys ( posts ) . length / postIncrease ) ;
}
2024-07-11 21:13:17 +02:00
2024-08-10 20:32:54 +02:00
class Icon {
constructor ( id , imagePath , callback ) {
this . id = id ;
this . imagePath = imagePath ;
this . callback = callback ;
this . isActive = false ;
}
setActive ( newValue ) {
this . isActive = newValue ;
const elem = document . getElementById ( this . id ) ;
if ( this . isActive ) {
elem . className = "icon active" ;
} else {
elem . className = "icon" ;
}
}
setImage ( path ) {
const imgElem = document . getElementById ( this . id )
. getElementsByClassName ( "icon-img" ) [ 0 ] ;
imgElem . setAttribute ( "src" , path ) ;
}
getElement ( ) {
const elem = document . createElement ( "div" ) ;
elem . id = this . id ;
elem . className = "icon" ;
const imgElem = document . createElement ( "img" ) ;
imgElem . className = "icon-img" ;
imgElem . setAttribute ( "src" , this . imagePath ) ;
elem . appendChild ( imgElem ) ;
const countElem = document . createElement ( "span" ) ;
countElem . className = "icon-count" ;
const count = Math . floor ( 1000 + Math . random ( ) * 9000 ) ;
countElem . innerHTML = count ;
elem . appendChild ( countElem ) ;
elem . addEventListener ( "click" , ( ) => {
this . callback ( this ) ;
} ) ;
return elem ;
}
incrementCount ( ) {
this . modifyCount ( 1 ) ;
}
decrementCount ( ) {
this . modifyCount ( - 1 ) ;
}
modifyCount ( amount ) {
// get count element
const countElem = document . getElementById ( this . id )
. getElementsByClassName ( "icon-count" ) [ 0 ] ;
// read the number out of it
let number = parseInt ( countElem . innerHTML ) ;
number += amount ;
// put the number back
countElem . innerHTML = number ;
}
}
2024-07-11 22:19:51 +02:00
class Post {
2024-07-25 00:35:30 +02:00
// JSON post data
2024-07-14 02:46:48 +02:00
constructor ( data ) {
this . id = data . id ;
this . username = data . associatedUser ;
this . content = data . body ;
this . replyTo = data . replyTo ;
2024-07-25 00:35:30 +02:00
this . parentPost = null ;
2024-07-14 02:46:48 +02:00
2024-07-25 00:35:30 +02:00
this . replies = [ ] ;
2024-07-14 02:46:48 +02:00
}
getIsReply ( ) {
return this . replyTo != "" ;
}
addReply ( reply ) {
this . replies . push ( reply ) ;
2024-07-25 00:35:30 +02:00
reply . parentPost = this ;
2024-07-11 22:19:51 +02:00
}
2024-07-25 00:35:30 +02:00
getPostLevel ( ) {
let p = this . parentPost ;
let depth = 0 ;
while ( p != null ) {
p = p . parentPost ;
depth ++ ;
}
return depth ;
}
2024-07-13 02:45:55 +02:00
2024-07-25 00:35:30 +02:00
getHeaderTag ( ) {
2024-08-03 15:16:44 +02:00
return this . getPostLevel ( ) == 0 ? "h1" : "h2" ;
2024-07-25 00:35:30 +02:00
}
2024-07-13 02:45:55 +02:00
2024-07-25 00:35:30 +02:00
getHeaderElement ( ) {
2024-08-04 16:02:19 +02:00
const elem = document . createElement ( "div" ) ;
elem . className = "post-header" ;
2024-08-03 13:54:00 +02:00
// TODO: fetch current user pfp from thispersondoesnotexist and place in local storage
// for now if this person is us, post octopus
const currentUser = getCurrentUser ( ) ;
const isCurrentUser = this . username == currentUser . user ;
2024-08-10 20:32:54 +02:00
const pfpPath = isCurrentUser ? "https://thispersondoesnotexist.com/" : ` user/ ${ this . username } .png ` ;
2024-08-03 13:54:00 +02:00
const pfpElem = document . createElement ( "img" ) ;
pfpElem . setAttribute ( "src" , pfpPath ) ;
pfpElem . setAttribute ( "class" , "pfp" ) ;
elem . appendChild ( pfpElem ) ;
const usernameElem = document . createElement ( this . getHeaderTag ( ) ) ;
2024-08-03 15:16:44 +02:00
usernameElem . setAttribute ( "class" , "username" ) ;
usernameElem . innerHTML = ` <a href="#"> ${ this . username } </a> ` ;
2024-08-03 13:54:00 +02:00
elem . appendChild ( usernameElem ) ;
2024-07-14 02:46:48 +02:00
2024-07-25 00:35:30 +02:00
return elem ;
}
2024-07-14 02:46:48 +02:00
2024-07-25 00:35:30 +02:00
getContentElement ( ) {
const elem = document . createElement ( "p" ) ;
elem . innerHTML = this . content ;
2024-08-04 16:18:12 +02:00
return elem ;
}
getIconElement ( svg , right ) {
const elem = document . createElement ( "div" ) ;
elem . className = "icon" ;
const imgElem = document . createElement ( "img" ) ;
imgElem . className = "icon-img" ;
imgElem . setAttribute ( "src" , svg ) ;
elem . appendChild ( imgElem ) ;
const countElem = document . createElement ( "span" ) ;
countElem . className = "icon-count" ;
2024-08-10 20:32:54 +02:00
countElem . innerHTML = count ;
2024-08-04 16:18:12 +02:00
elem . appendChild ( countElem ) ;
return elem ;
}
getFooterElement ( ) {
const elem = document . createElement ( "div" ) ;
elem . className = "post-footer" ;
2024-08-10 20:32:54 +02:00
const getToggleCallback = ( activeImg , inactiveImg ) => {
const toggle = icon => {
if ( icon . isActive ) {
icon . setActive ( false ) ;
icon . setImage ( inactiveImg ) ;
icon . decrementCount ( ) ;
} else {
icon . setActive ( true ) ;
icon . setImage ( activeImg ) ;
icon . incrementCount ( ) ;
}
} ;
return toggle ;
}
2024-08-04 16:18:12 +02:00
2024-08-10 20:32:54 +02:00
const star = new Icon (
` ${ this . id } -star ` ,
"icon/star-regular.svg" ,
getToggleCallback ( "icon/star-solid.svg" , "icon/star-regular.svg" ) ) ;
const repost = new Icon (
` ${ this . id } -repost ` ,
"icon/retweet-solid.svg" ,
icon => icon . incrementCount ( ) ) ;
const bookmark = new Icon (
` ${ this . id } -bookmark ` ,
"icon/bookmark-regular.svg" ,
getToggleCallback ( "icon/bookmark-solid.svg" , "icon/bookmark-regular.svg" ) ) ;
const comment = new Icon (
` ${ this . id } -comment ` ,
"icon/comment-regular.svg" ,
icon => {
writeReply ( this ) ;
icon . incrementCount ( ) ;
} ) ;
if ( this . username != getCurrentUser ( ) . user ) {
elem . appendChild ( comment . getElement ( ) ) ;
}
elem . appendChild ( star . getElement ( ) ) ;
elem . appendChild ( repost . getElement ( ) ) ;
elem . appendChild ( bookmark . getElement ( ) ) ;
2024-07-14 02:46:48 +02:00
2024-08-04 16:02:19 +02:00
return elem ;
}
2024-07-25 00:35:30 +02:00
getElement ( ) {
const elem = document . createElement ( "div" ) ;
2024-08-04 16:02:19 +02:00
elem . id = this . id ;
2024-07-14 02:46:48 +02:00
2024-07-25 00:35:30 +02:00
// display root posts as blocks, and comments as attached to their posts
2024-08-03 15:16:44 +02:00
let classes = [ "post" ] ;
2024-07-25 00:35:30 +02:00
if ( this . getPostLevel ( ) == 0 ) {
2024-08-03 15:16:44 +02:00
classes . push ( "block" ) ;
2024-07-25 00:35:30 +02:00
}
2024-08-03 15:16:44 +02:00
elem . className = classes . join ( " " ) ;
2024-07-25 00:35:30 +02:00
elem . appendChild ( this . getHeaderElement ( ) ) ;
elem . appendChild ( this . getContentElement ( ) ) ;
2024-08-04 16:18:12 +02:00
elem . appendChild ( this . getFooterElement ( ) ) ;
2024-07-14 02:46:48 +02:00
2024-07-25 00:35:30 +02:00
for ( let i = 0 ; i < this . replies . length ; i ++ ) {
const reply = this . replies [ i ] ;
elem . appendChild ( reply . getElement ( ) ) ;
2024-07-13 02:45:55 +02:00
}
2024-07-25 00:35:30 +02:00
return elem ;
2024-07-11 22:19:51 +02:00
}
}
2024-08-08 21:51:43 +02:00
function getAdjective ( ) {
return adjectives [ Math . floor ( Math . random ( ) * adjectives . length ) ] ;
}
2024-07-14 02:46:48 +02:00
function getRootPosts ( ) {
let result = [ ] ;
for ( var id in posts ) {
const post = posts [ id ] ;
if ( post . getIsReply ( ) )
continue ;
result . push ( post ) ;
}
return result ;
2024-07-11 21:13:17 +02:00
}
2024-07-11 22:19:51 +02:00
function addPosts ( pageIdx ) {
2024-07-11 21:13:17 +02:00
currentPage = pageIdx ;
2024-07-11 22:19:51 +02:00
const startRange = ( pageIdx - 1 ) * postIncrease ;
2024-07-20 13:55:10 +02:00
const endRange = currentPage == getPageCount ( )
? posts . length
2024-07-11 22:19:51 +02:00
: pageIdx * postIncrease ;
2024-07-11 21:13:17 +02:00
2024-07-14 02:46:48 +02:00
const rootPosts = getRootPosts ( ) ;
2024-07-11 21:13:17 +02:00
for ( let i = startRange + 1 ; i <= endRange ; i ++ ) {
2024-07-25 00:35:30 +02:00
const post = rootPosts [ i ] ;
const elem = post . getElement ( ) ;
blockContainer . appendChild ( elem ) ;
2024-07-11 21:13:17 +02:00
}
}
function handleInfiniteScroll ( ) {
throttle ( ( ) => {
const endOfPage = window . innerHeight + window . pageYOffset >= document . body . offsetHeight ;
if ( endOfPage ) {
2024-07-11 22:19:51 +02:00
addPosts ( currentPage + 1 ) ;
2024-07-11 21:13:17 +02:00
}
2024-07-20 13:55:10 +02:00
if ( currentPage === getPageCount ( ) ) {
2024-07-11 21:13:17 +02:00
removeInfiniteScroll ( ) ;
}
} , 1000 ) ;
}
2024-07-11 22:19:51 +02:00
// limit how often we try to load new posts to maintain browser performance
2024-07-11 21:13:17 +02:00
var throttleTimer ;
function throttle ( callback , time ) {
if ( throttleTimer ) return ;
throttleTimer = true ;
setTimeout ( ( ) => {
callback ( ) ;
throttleTimer = false ;
} , time ) ;
}
function removeInfiniteScroll ( ) {
loader . remove ( ) ;
window . removeEventListener ( "scroll" , handleInfiniteScroll ) ;
}
2024-07-20 14:40:54 +02:00
function getTopPost ( ) {
// find the first post
const children = blockContainer . childNodes ;
let firstPost = null ;
for ( let i = 0 ; i < children . length ; i ++ ) {
const child = children [ i ] ;
const classes = child . className . split ( " " ) ;
if ( classes . some ( c => c == "post" ) ) {
firstPost = child ;
break ;
}
}
2024-07-18 02:16:52 +02:00
2024-07-20 14:40:54 +02:00
return firstPost ;
}
function makePostFromJson ( json ) {
return new Post ( {
id : json . id ,
associatedUser : json . associatedUser ,
body : json . body
} ) ;
}
function getCurrentUser ( ) {
2024-08-04 20:15:29 +02:00
// 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"
} ;
}
2024-07-20 14:40:54 +02:00
return {
2024-08-04 20:15:29 +02:00
"user" : localUser . user ,
"interests" : localUser . interests ,
2024-08-10 20:32:54 +02:00
"posting_style" : localUser . postingStyle
2024-07-20 14:40:54 +02:00
} ;
}
2024-07-18 02:16:52 +02:00
2024-08-04 20:33:00 +02:00
function getPostRequest ( body ) {
return {
2024-07-18 02:16:52 +02:00
method : "POST" ,
mode : "cors" ,
2024-08-04 20:33:00 +02:00
body : JSON . stringify ( body ) ,
2024-07-18 02:16:52 +02:00
headers : {
"Content-type" : "application/json; charset=UTF-8"
}
2024-07-20 14:40:54 +02:00
} ;
2024-08-04 20:33:00 +02:00
}
2024-07-18 02:16:52 +02:00
2024-08-08 21:51:43 +02:00
function getLoaderIcon ( ) {
const elem = document . createElement ( "div" ) ;
elem . className = "loader-icon" ;
return elem ;
}
function getWritePostButtonText ( ) {
2024-08-10 20:32:54 +02:00
return ` write something ${ getAdjective ( ) } . ` ;
2024-08-08 21:51:43 +02:00
}
2024-08-04 20:33:00 +02:00
function writePost ( ) {
2024-08-08 21:51:43 +02:00
if ( isWritingPost )
return ;
2024-08-03 13:28:23 +02:00
if ( localMode ) {
const post = new Post ( {
id : "1234" ,
associatedUser : getCurrentUser ( ) . user ,
body : "local mode post (local mode post)"
} ) ;
2024-08-04 20:33:00 +02:00
blockContainer . insertBefore ( post . getElement ( ) , getTopPost ( ) ) ;
return ;
}
2024-08-08 21:51:43 +02:00
// change the content of the write post button to a loading animation
const buttonContent = document . getElementById ( "write-post-button-content" ) ;
buttonContent . innerHTML = "" ;
buttonContent . appendChild ( getLoaderIcon ( ) ) ;
isWritingPost = true ;
2024-08-04 20:33:00 +02:00
fetch ( "https://api.wayfarer.games/singularity/generate-posts.php" , getPostRequest ( getCurrentUser ( ) ) )
. then ( response => response . json ( ) )
. then ( makePostFromJson )
2024-08-08 21:51:43 +02:00
. then ( post => {
isWritingPost = false ;
blockContainer . insertBefore ( post . getElement ( ) , getTopPost ( ) ) ;
buttonContent . innerHTML = getWritePostButtonText ( ) ;
} ) ;
2024-08-04 16:02:19 +02:00
}
function writeReply ( post ) {
2024-08-08 21:51:43 +02:00
if ( isWritingReply )
return ;
2024-08-04 16:02:19 +02:00
// find the correct element
const elem = document . getElementById ( post . id ) ;
2024-08-04 20:33:00 +02:00
const user = getCurrentUser ( ) ;
2024-08-04 16:02:19 +02:00
2024-08-04 20:33:00 +02:00
if ( localMode ) {
console . error ( "TODO: implement local replies" ) ;
return ;
}
const replyBody = {
postId : post . id ,
interests : user . interests ,
user : user . user ,
posting _style : user . posting _style
} ;
2024-08-08 21:51:43 +02:00
isWritingReply = true ;
2024-08-04 20:33:00 +02:00
const request = getPostRequest ( replyBody ) ;
2024-08-08 21:51:43 +02:00
// add a loading icon to the element
const loader = getLoaderIcon ( ) ;
elem . append ( loader ) ;
2024-08-04 20:33:00 +02:00
fetch ( "https://api.wayfarer.games/singularity/generate-reply.php" , getPostRequest ( replyBody ) )
. then ( response => response . json ( ) )
. then ( makePostFromJson )
. then ( reply => {
2024-08-08 21:51:43 +02:00
isWritingReply = false ;
2024-08-04 20:33:00 +02:00
post . addReply ( reply ) ;
elem . append ( reply . getElement ( ) ) ;
2024-08-08 21:51:43 +02:00
loader . remove ( ) ;
2024-08-04 20:33:00 +02:00
} ) ;
2024-08-04 16:02:19 +02:00
}
2024-07-17 01:08:55 +02:00
function addWritePostBlock ( ) {
const blockElem = document . createElement ( "div" ) ;
2024-08-04 20:33:00 +02:00
blockElem . addEventListener ( "click" , writePost ) ;
2024-08-03 15:16:44 +02:00
blockElem . className = "block write-post" ;
2024-07-17 01:08:55 +02:00
2024-08-08 21:51:43 +02:00
const contentElem = document . createElement ( "h1" ) ;
contentElem . className = "" ;
contentElem . id = "write-post-button-content" ;
contentElem . innerHTML = getWritePostButtonText ( ) ;
blockElem . append ( contentElem ) ;
2024-07-17 01:08:55 +02:00
2024-08-03 15:16:44 +02:00
blockContainer . append ( blockElem ) ;
2024-07-17 01:08:55 +02:00
}
2024-07-14 02:46:48 +02:00
function init ( ) {
if ( posts == undefined )
{
console . log ( "resource loading failed" ) ;
return ;
}
// need to load all the resources first
2024-07-17 01:08:55 +02:00
const postCount = Object . keys ( posts ) . length ;
if ( users . length == 0 || postCount == 0 )
2024-07-14 02:46:48 +02:00
return ;
2024-07-17 01:08:55 +02:00
console . log ( ` loaded ${ users . length } users and ${ postCount } posts ` ) ;
addWritePostBlock ( ) ;
2024-07-14 02:46:48 +02:00
addPosts ( currentPage ) ;
window . addEventListener ( "scroll" , handleInfiniteScroll ) ;
}
2024-08-04 20:15:29 +02:00
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" ) ;
2024-08-10 15:43:01 +02:00
advanceButtonElem . innerHTML = "enter." ;
2024-08-04 20:15:29 +02:00
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 ) {
2024-08-10 15:43:01 +02:00
const leftToChoose = maxInterests - numChosenInterests ;
if ( leftToChoose > 1 )
return ` choose ${ leftToChoose } interests. ` ;
return "choose 1 interest." ;
2024-08-04 20:15:29 +02:00
}
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 ;
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 ( ) ;
2024-08-08 22:06:46 +02:00
localUser . postingStyle = postingStyles [ Math . floor ( Math . random ( ) * postingStyles . length ) ] ;
2024-08-04 20:15:29 +02:00
removeSplash ( ) ;
break ;
default :
console . error ( ` nothing defined for splash step ${ splashStep } ` ) ;
}
}
2024-07-14 02:46:48 +02:00
function loadDataFromEndpoint ( endpoint , callback ) {
fetch ( endpoint )
. then ( response => response . json ( ) )
. then ( json => {
callback ( json ) ;
init ( ) ;
} ) ;
}
2024-07-11 21:13:17 +02:00
2024-08-08 21:52:04 +02:00
function shuffle ( array ) {
let idx = array . length ;
while ( idx != 0 ) {
const r = Math . floor ( Math . random ( ) * idx ) ;
idx -- ;
[ array [ idx ] , array [ r ] ] = [ array [ r ] , array [ idx ] ] ;
}
}
2024-08-04 20:15:29 +02:00
2024-08-03 13:28:23 +02:00
const usersUrl = localMode ? "users.json" : "https://api.wayfarer.games/singularity/users.json" ;
const postsUrl = localMode ? "posts.json" : "https://api.wayfarer.games/singularity/posts.json" ;
loadDataFromEndpoint ( usersUrl , json => { users = json . users ; } ) ;
loadDataFromEndpoint ( postsUrl , json => {
2024-08-08 21:52:04 +02:00
let postsData = json . content ;
shuffle ( postsData ) ;
2024-07-14 02:46:48 +02:00
// first pass to instantiate all the posts
2024-08-08 21:52:04 +02:00
for ( let i = 0 ; i < postsData . length ; i ++ ) {
const post = new Post ( postsData [ i ] ) ;
2024-07-14 02:46:48 +02:00
posts [ post . id ] = post ;
}
// second pass to link each reply to the appropriate parent
for ( const id in posts ) {
const post = posts [ id ] ;
if ( ! post . getIsReply ( ) )
continue ;
const parent = posts [ post . replyTo ] ;
parent . addReply ( post ) ;
}
} ) ;
2024-08-04 20:15:29 +02:00
if ( ! showSplash ) {
removeSplash ( ) ;
}