xssbook/public/js/home.js
2023-01-27 16:04:04 -05:00

232 lines
No EOL
6.9 KiB
JavaScript

const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
function parseDate(date) {
return months[date.getUTCMonth()] + ' ' + date.getUTCDate() + ', ' + date.getUTCFullYear() + ' ' + date.toLocaleTimeString();
}
function parseComment(comment) {
const author = data.users[comment[0]]
if (author === undefined) {
author = {}
}
const html = `
<div class="comment">
<a class="pfp">
</a>
<span>
<span class="bold mtext">${author.firstname + ' ' + author.lastname}</span>
<p class="mtext">${comment[1]}</p>
</span>
</div>
`
return html
}
function parsePost(post) {
const author = data.users[post.user_id]
if (author === undefined) {
author = {}
}
const html = `
<div class="post" postid=${post.post_id}>
<div class="postheader">
<a class="pfp">
</a>
<div class="postname">
<span class="bold">${author.firstname + ' ' + author.lastname}</span>
<span class="gtext mtext">${parseDate(new Date(post.date))}</span>
</div>
</div>
<p class="mtext">
${post.content.replace(/\n/g,'<br>')}
</p>
<span class="gtext mtext">
${Object.keys(post.likes).map(k => post.likes[k]).filter(v => v !== false).length} Likes
</span>
<div class="fullline nb"></div>
<div class="postbuttons">
<span onclick="like(this)">
<i class="icons like ${post.likes.includes(data.user.user_id) ? 'blue' : ''}"></i>
<span class="bold ${post.likes.includes(data.user.user_id) ? 'blue' : ''}">Like</span>
</span>
<span onclick="this.parentElement.parentElement.getElementsByClassName('newcomment')[0].focus()">
<i class="icons comm"></i>
<span class="bold">Comment</span>
</span>
</div>
<div id="comments">
<div class="fullline" style="margin-top: 0"></div>
${post.comments.map(parseComment).join('')}
<div class="comment">
<a class="pfp" href="profile">
</a>
<form onsubmit="comment(event)">
<input type="text" name="text" placeholder="Write a comment..." id="newcomment" class="newcomment">
</form>
</div>
</div>
</div>
`
return html
}
function getPost(post_id) {
for (let i = 0; i < data.posts.length; i++) {
if (data.posts[i].post_id === post_id) {
return i
}
}
return -1
}
async function like(span) {
const id = parseInt(span.parentElement.parentElement.getAttribute('postid'))
const post = data.posts[getPost(id)]
const index = post.likes.indexOf(data.user.user_id)
const current = index !== -1
const response = await postlike(id, !current)
if (response.status != 200) return;
if (current) {
post.likes.splice(index, 1)
} else {
post.likes.push(data.user.user_id)
}
render()
}
async function comment(event) {
event.preventDefault();
const text = event.target.elements.text.value.trim();
if (text.length < 1) return;
const id = parseInt(event.target.parentElement.parentElement.parentElement.getAttribute('postid'))
var index = getPost(id);
if (index === -1) return;
const response = await postcomment(id, text)
if (response.status != 200) return;
event.target.elements.text.value = '';
data.posts[index].comments.push([data.user.user_id, text])
render()
}
async function post() {
const text = document.getElementById("text").value.trim()
const error = document.getElementsByClassName('error')[0]
if (text.length < 1) return;
const response = await createpost(text);
if (response.status != 201) {
error.innerHTML = response.msg
return;
}
error.innerHTML = '';
data.posts.unshift({
post_id: response.json.post_id,
user_id: data.user.user_id,
date: Date.now(),
content: text,
likes: [],
comments: []
})
render()
}
function render() {
const html = `
<div id="posts">
<div class="create">
<a class="pfp" href="profile">
</a>
<button class="pfp">
<p class="gtext" onclick="document.getElementById('popup').classList.remove('hidden')">
What's on your mind, ${data.user.firstname}?
</p>
</button>
</div>
${data.posts.map(p => parsePost(p)).join('')}
</div>
`
add(html, 'posts')
const popup = `
<div id="popup" class="hidden">
<div class="createpost">
<div class="close" onclick="document.getElementById('popup').classList.add('hidden')"></div>
<span class="ltext ctext bold">Create post</span>
<div class="fullline"></div>
<div class="postheader">
<a class="pfp" style="cursor: auto">
</a>
<div class="postname">
<span class="bold">${data.user.firstname + ' ' + data.user.lastname}</span>
<span class="gtext mtext">Now</span>
</div>
</div>
<textarea type="text" name="text" id="text" placeholder="What's on your mind, ${data.user.firstname}?"></textarea>
<span class="error ctext" style="padding-bottom: 15px; margin-top: -30px;"></span>
<button class="primary" onclick="post(this)">Post</button>
</div>
</div>
`
add(popup, 'popup')
const load = `
<div id="load">
<a class="bold gtext" onclick="load()">Load more posts</a>
</div>
`
if (page !== -1) {
add(load, 'load')
} else {
remove('load')
}
}
var page = 0
const data = {
user: {},
users: {},
posts: []
}
async function load() {
const posts = (await loadpostspage(page)).json
if (posts.length === 0) {
page = -1
} else {
page++
}
data.posts.push(... posts)
const batch = []
for (const post of posts) {
for(const comment of post.comments) {
if (data.users[comment[0]] !== undefined) continue
if (batch.includes(comment[0])) continue
batch.push(comment[0])
}
if (data.users[post.user_id] !== undefined) continue
if (batch.includes(post.user_id)) continue
batch.push(post.user_id)
}
const users = (await loadusers(batch)).json
for (const id in users) {
data.users[id] = users[id]
}
render()
}
async function init() {
header(true, false)
data.user = (await loadself()).json
data.users[data.user.user_id] = data.user
load()
}