xssbook/public/js/profile.js
2023-02-12 16:44:45 -05:00

273 lines
7.6 KiB
JavaScript

import { div, pfp, banner, parse, button, body, a, span, crawl, parseDate, parseMonth } from './main.js'
import { loadself, loadusers, loadusersposts, updateavatar, updatebanner, logout } from './api.js'
import { parsePost, header } from './components.js'
function swap(value) {
let postsb = document.getElementById("profilepostbutton");
let aboutb = document.getElementById("profileaboutbutton");
let posts = document.getElementById("posts");
let about = document.getElementById("about");
let load = document.getElementsByClassName("loadp")[0];
if (value) {
postsb.classList.add("selected")
aboutb.classList.remove("selected")
about.classList.add("hidden")
posts.classList.remove("hidden")
if (load) {
load.classList.remove("hidden")
}
} else {
postsb.classList.remove("selected")
aboutb.classList.add("selected")
about.classList.remove("hidden")
posts.classList.add("hidden")
if (load) {
load.classList.add("hidden")
}
}
}
function changeimage(fn) {
var input = document.createElement('input')
input.type = 'file'
input.accept= 'image/png'
input.onchange = async (e) => {
var popup = document.getElementById("popup")
var loader = popup.getElementsByClassName("loading")[0]
var message = popup.getElementsByClassName("message")[0]
loader.classList.add("hidden")
message.innerHTML = '';
popup.classList.remove("hidden")
var file = e.target.files[0];
if (file.type !== 'image/png') {
message.innerHTML = 'Image must be a PNG';
return
}
loader.classList.remove("hidden")
let response = await fn(file);
loader.classList.add("hidden")
message.innerHTML = response.msg
}
input.click();
}
function render() {
let new_body =
body({},
...header(false, false, data.self.user_id),
div({id: 'top'},
div({id: 'banner'},
div({class: 'bg'},
banner(data.user.user_id)
),
isself ? div({class: 'changebanner', onclick: () => changeimage(updatebanner)}) : parse(''),
),
div({id: 'info'},
div({class: 'face'},
pfp(data.user.user_id),
isself ? div({class: 'changeavatar', onclick: () => changeimage(updateavatar)}) : parse(''),
),
div({class: 'infodata'},
span({class: 'bold ltext'},
parse(data.user.firstname + ' ' + data.user.lastname)
),
span({class: 'gtext'},
parse('Joined ' + parseDate(new Date(data.user.date)))
)
)
),
div({class: 'fullline', style: 'width: 80em; margin-bottom: 0; z-index: 0;'}),
div({class: 'profilebuttons'},
button({id: 'profilepostbutton', class: 'selected', onclick: () => swap(true)},
parse('Posts')
),
button({id: 'profileaboutbutton', onclick: () => swap(false)},
parse('About')
),
div({style: 'flex: 20'}),
isself ? button({class: 'logout', onclick: async () => {
const response = await logout()
if (response.status != 200) return;
location.href = '/login'
}},
parse('Logout')
)
: parse('')
)
),
div({id: 'posts'},
...data.posts.map(p => parsePost(p, data.users, data.self))
),
div({id: 'load'},
a({class: 'loadp bold gtext', onclick: async () => {
const posts = await load()
data.posts.push(... posts)
const el = document.getElementById("posts")
for (const post of posts) {
el.appendChild(
parsePost(post, data.users, data.self)
)
}
}},
parse('Load more posts')
)
),
div({id: 'about', class: 'post hidden'},
span({class: 'bold ltext'},
parse('About')
),
div({class: 'data'},
span({class: 'gtext bold'},
parse('Name: ' + data.user.firstname + ' ' + data.user.lastname)
),
span({class: 'gtext bold'},
parse('Email: ' + data.user.email)
),
span({class: 'gtext bold'},
parse('Gender ' + data.user.gender)
),
span({class: 'gtext bold'},
parse('Birthday: ' + parseMonth(data.user.month) + ' ' + data.user.day + ', ' + data.user.year)
),
span({class: 'gtext bold'},
parse('User ID: ' + data.user_id)
)
)
),
div({id: 'popup', class: 'hidden'},
div({class: 'createpost'},
div({class: 'close', onclick: () => document.getElementById('popup').classList.add('hidden')}),
span({class: 'ltext ctext bold'},
parse('Uploading')
),
div({class: 'fullline'}),
div({class: 'fullwidth'},
div({class: 'loading'},
div({}),
div({}),
div({}),
div({})
)
),
span({class: 'message ctext', style: 'padding-top: 10px'})
)
)
)
document.body.replaceWith(new_body)
if (data.posts.length < 10) {
document.getElementById('load').remove()
}
}
var isself = false
var page = 0
const data = {
self: {},
user: {},
users: {},
posts: []
}
async function load(id) {
if (id === undefined) {
id = data.user.user_id
}
const posts = (await loadusersposts(id, page)).json
if (posts == undefined) {
posts = []
}
if (posts.length < 1) {
let el = document.getElementsByClassName('loadp')[0]
if (el) {
el.remove()
}
return []
} else {
page++
}
const batch = Array.from(new Set(crawl('user_id', posts))).filter(id => data.users[id] == undefined)
if (!isself) {
batch.push(id)
}
if (batch.length != 0) {
const users = (await loadusers(batch)).json
if (users == undefined) {
users = []
}
for (const user of users) {
data.users[user.user_id] = user
}
}
return posts
}
async function init() {
let request = await loadself()
if (request.status === 429) {
let new_body =
body({},
...header(false, false)
)
document.body.replaceWith(new_body)
throw new Error("Rate limited");
}
data.self = request.json;
data.users[data.self.user_id] = data.self
var params = {};
for (const [key, value] of new URLSearchParams(location.search)) {
params[key] = value
}
let id;
if (params.id !== undefined && !isNaN(params.id)) {
id = parseInt(params.id);
} else {
id = data.self.user_id
}
isself = id === data.self.user_id
const posts = await load(id)
data.posts.push(... posts)
data.user = data.users[id]
render()
}
init()