From 88209d88236c3d865a9f5174a0dced31920859bf Mon Sep 17 00:00:00 2001 From: Tyler Murphy Date: Thu, 26 Jan 2023 17:29:16 -0500 Subject: i did things --- public/js/api.js | 63 ++++++++++++++ public/js/header.js | 25 ++++++ public/js/home.js | 233 +++++++++++++++++++++++++++++++++++++++++++++++++++ public/js/login.js | 29 +++++++ public/js/main.js | 22 +++++ public/js/people.js | 65 ++++++++++++++ public/js/profile.js | 88 +++++++++++++++++++ 7 files changed, 525 insertions(+) create mode 100644 public/js/api.js create mode 100644 public/js/header.js create mode 100644 public/js/home.js create mode 100644 public/js/login.js create mode 100644 public/js/main.js create mode 100644 public/js/people.js create mode 100644 public/js/profile.js (limited to 'public/js') diff --git a/public/js/api.js b/public/js/api.js new file mode 100644 index 0000000..07769f6 --- /dev/null +++ b/public/js/api.js @@ -0,0 +1,63 @@ +const endpoint = '/api' + +const request = async (url, body, method) => { + if (method === undefined) method = 'POST' + const response = await fetch(endpoint + url, { + method, + body: JSON.stringify(body), + headers: { + 'Content-Type': 'application/json' + } + }); + if (response.status == 401) { + location.href = 'login' + } + const contentType = response.headers.get("content-type"); + if (contentType && contentType.indexOf("application/json") !== -1) { + const json = await response.json() + return { status: response.status, msg: json.msg, json } + } else { + const msg = await response.text(); + return { status: response.status, msg } + } +} + +const login = async (email, password) => { + return await request('/auth/login', {email, password}) +} + +const register = async (firstname, lastname, email, password, gender, day, month, year) => { + return await request('/auth/register', {firstname, lastname, email, password, gender, day, month, year}) +} + +const loadpostspage = async (page) => { + return await request('/posts/page', {page}) +} + +const loadusersposts = async (user_id) => { + return await request('/posts/user', {user_id}) +} + +const loadusers = async (ids) => { + return await request('/users/load', {ids}) +} + +const loaduserspage = async (page) => { + return await request('/users/page', {page}) +} + +const loadself = async () => { + return await request("/users/self", {}) +} + +const postcomment = async (post_id, content) => { + return await request('/posts/comment', {post_id, content}, 'PATCH') +} + +const postlike = async (post_id, state) => { + return await request('/posts/like', {post_id, state}, 'PATCH') +} + +const createpost = async (content) => { + return await request('/posts/create', {content}) +} \ No newline at end of file diff --git a/public/js/header.js b/public/js/header.js new file mode 100644 index 0000000..8fe03e5 --- /dev/null +++ b/public/js/header.js @@ -0,0 +1,25 @@ +function header(home, people) { + const html = ` + +
+ ` + + add(html, 'header') +} \ No newline at end of file diff --git a/public/js/home.js b/public/js/home.js new file mode 100644 index 0000000..fd40ebf --- /dev/null +++ b/public/js/home.js @@ -0,0 +1,233 @@ +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 = ` +
+ + + + + ${author.firstname + ' ' + author.lastname} +

${comment[1]}

+
+
+ ` + return html +} + +function parsePost(post) { + console.log(post.likes) + const author = data.users[post.user_id] + if (author === undefined) { + author = {} + } + const html = ` +
+
+ + + +
+ ${author.firstname + ' ' + author.lastname} + ${parseDate(new Date(post.date))} +
+
+

+ ${post.content.replace(/\n/g,'
')} +

+ + ${Object.keys(post.likes).map(k => post.likes[k]).filter(v => v !== false).length} Likes + +
+
+ + + Like + + + + Comment + +
+
+
+ ${post.comments.map(parseComment).join('')} +
+ + + +
+ +
+
+
+
+ ` + + 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.msg, + user_id: data.user.user_id, + date: Date.now(), + content: text, + likes: [], + comments: [] + }) + render() +} + +function render() { + const html = ` +
+
+ + + + +
+ ${data.posts.map(p => parsePost(p)).join('')} +
+ ` + + add(html, 'posts') + + const popup = ` + + ` + + add(popup, 'popup') + + const load = ` +
+ Load more posts +
+ ` + + 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() +} \ No newline at end of file diff --git a/public/js/login.js b/public/js/login.js new file mode 100644 index 0000000..f65808b --- /dev/null +++ b/public/js/login.js @@ -0,0 +1,29 @@ +async function onlogin() { + const email = document.getElementById('email').value + const password = document.getElementById('pass').value + const response = await login(email, password) + if (response.status !== 200) { + const error = document.getElementsByClassName('error')[0] + error.innerHTML = response.msg + } else { + location.href = '/home' + } +} + +async function onregister() { + const first = document.getElementById('firstname').value + const last = document.getElementById('lastname').value + const email = document.getElementById('newemail').value + const pass = document.getElementById('newpass').value + const month = document.getElementById('month').value + const day = document.getElementById('day').value + const year = document.getElementById('year').value + const gender = document.querySelector('input[name="gender"]:checked').value + const response = await register(first, last, email, pass, gender, parseInt(day), parseInt(month), parseInt(year)) + if (response.status !== 200) { + const error = document.getElementsByClassName('error')[1] + error.innerHTML = response.msg + } else { + location.href = '/home' + } +} \ No newline at end of file diff --git a/public/js/main.js b/public/js/main.js new file mode 100644 index 0000000..0003c0d --- /dev/null +++ b/public/js/main.js @@ -0,0 +1,22 @@ +var range; + +function add(html, id) { + const old = document.getElementById(id) + if (old !== null) { + old.remove() + } + if (range === undefined) { + var range = document.createRange() + range.setStart(document.body, 0) + } + document.body.appendChild( + range.createContextualFragment(html) + ) +} + +function remove(id) { + const old = document.getElementById(id) + if (old !== null) { + old.remove() + } +} \ No newline at end of file diff --git a/public/js/people.js b/public/js/people.js new file mode 100644 index 0000000..ddd1875 --- /dev/null +++ b/public/js/people.js @@ -0,0 +1,65 @@ +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 parseUser(user) { + const html = ` + +
+ +
+
+ ${user.firstname + ' ' + user.lastname} + Joined ${parseDate(new Date(user.date))} + Gender: ${user.gender} + Birthday: ${months[user.month] + ' ' + user.day + ', ' + user.year} + User ID: ${user.user_id} +
+
+ ` + return html +} + +function render() { + const html = ` +
+ ${data.users.map(u => parseUser(u)).join('')} +
+ ` + + add(html, 'users') + + const load = ` +
+ Load more users +
+ ` + + if (page !== -1) { + add(load, 'load') + } else { + remove('load') + } +} + +var page = 0 +var data = { + users: [] +} + +async function load() { + const users = (await loaduserspage(page)).json + if (users.length === 0) { + page = -1 + } else { + page++ + } + data.users.push(... users) + render() +} + +header(false, true) +load() \ No newline at end of file diff --git a/public/js/profile.js b/public/js/profile.js new file mode 100644 index 0000000..79dbe2f --- /dev/null +++ b/public/js/profile.js @@ -0,0 +1,88 @@ +function render() { + const html = ` +
+ +
+
+ +
+
+ ${data.user.firstname + ' ' + data.user.lastname} + Joined ${parseDate(new Date(data.user.date))} +
+
+
+
+ + +
+
+ ` + + add(html, 'top') + + const postsh = ` +
+ ${data.posts.map(p => parsePost(p)).join('')} +
+ ` + + add(postsh, 'posts') + + const about = ` +
+ About +
+ Name: ${data.user.firstname + ' ' + data.user.lastname} + Email: ${data.user.email} + Gender: ${data.user.gender} + Birthday: ${months[data.user.month] + ' ' + data.user.day + ', ' + data.user.year} + User ID: ${data.user.user_id} +
+
+ ` + + add(about, 'about') +} + +var posts = true + +async function load() { + header(false, false) + + var params = {}; + for (const [key, value] of new URLSearchParams(location.search)) { + params[key] = value + } + + const id = params.id !== undefined && !isNaN(params.id) ? parseInt(params.id) : (await loadself()).json.user_id + const posts = (await loadusersposts(id)).json + data.posts.push(... posts) + const batch = [id] + 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 user of users) { + data.users[user.user_id] = user + } + data.user = data.users[id] + render() +} + +load() \ No newline at end of file -- cgit v1.2.3-freya