xssbook/public/js/profile.js

366 lines
11 KiB
JavaScript
Raw Normal View History

2023-02-12 19:11:50 +00:00
import { div, pfp, banner, parse, button, body, a, span, crawl, parseDate, parseMonth } from './main.js'
2023-02-15 00:28:10 +00:00
import { loadself, loadusers, loadusersposts, updateavatar, updatebanner, logout, follow, follow_status, friends } from './api.js'
import { parsePost, parseUser, header } from './components.js'
2023-02-12 19:11:50 +00:00
2023-02-15 00:28:10 +00:00
function swap(tab) {
2023-02-15 18:32:43 +00:00
let buttons = []
buttons[0] = document.querySelector("#profilepostbutton");
buttons[1] = document.querySelector("#profileaboutbutton");
buttons[2] = document.querySelector("#profilefriendsbutton");
buttons[3] = document.querySelector("#profilefollowersbutton");
buttons[4] = document.querySelector("#profilefollowingbutton");
let sections = []
sections[0] = document.querySelector("#posts");
sections[1] = document.querySelector("#about");
sections[2] = document.querySelector("#friends");
sections[3] = document.querySelector("#followers");
sections[4] = document.querySelector("#following");
2023-02-15 00:28:10 +00:00
let load = document.querySelector(".loadp");
2023-02-15 18:32:43 +00:00
for (const i in buttons) {
if (i == tab) {
buttons[i].classList.add("selected")
sections[i].classList.remove("hidden")
} else {
buttons[i].classList.remove("selected")
sections[i].classList.add("hidden")
2023-02-15 00:28:10 +00:00
}
2023-02-15 18:32:43 +00:00
}
2023-02-15 00:28:10 +00:00
2023-02-15 18:32:43 +00:00
if (load) {
if (tab == 0) {
load.classList.remove("hidden")
} else {
2023-02-12 19:11:50 +00:00
load.classList.add("hidden")
}
}
}
2023-02-01 03:21:19 +00:00
function changeimage(fn) {
var input = document.createElement('input')
input.type = 'file'
input.accept= 'image/png'
input.onchange = async (e) => {
2023-02-02 01:56:09 +00:00
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")
2023-02-01 03:21:19 +00:00
var file = e.target.files[0];
if (file.type !== 'image/png') {
2023-02-02 01:56:09 +00:00
message.innerHTML = 'Image must be a PNG';
2023-02-01 03:21:19 +00:00
return
2023-02-02 01:56:09 +00:00
}
loader.classList.remove("hidden")
2023-02-01 03:21:19 +00:00
let response = await fn(file);
2023-02-02 01:56:09 +00:00
loader.classList.add("hidden")
message.innerHTML = response.msg
2023-02-01 03:21:19 +00:00
}
input.click();
}
2023-02-15 00:28:10 +00:00
function status_text(status) {
switch (status) {
case 1:
return 'Following ✓'
case 2:
return 'Follow Back'
case 3:
return 'Friends ✓'
default:
return 'Follow'
}
}
async function render() {
2023-01-26 22:29:16 +00:00
2023-02-15 00:28:10 +00:00
let status;
if (!isself) {
let response = await follow_status(data.user.user_id)
if (response.status == 200) {
status = parseInt(response.msg)
} else {
status = 0;
}
}
2023-02-15 18:32:43 +00:00
let response = (await friends(data.user.user_id)).json
if (response == undefined) {
response = []
2023-02-15 00:28:10 +00:00
}
2023-02-15 18:32:43 +00:00
let friends_arr = response[0];
let followers = response[1];
let following = response[2];
2023-02-15 00:28:10 +00:00
let new_body =
2023-02-12 19:11:50 +00:00
body({},
2023-07-26 05:04:39 +00:00
...header(false, false, false, data.self.user_id),
2023-02-12 19:11:50 +00:00
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)))
)
2023-02-15 00:28:10 +00:00
),
!isself ?
div({class: 'right'},
div({class: `follow ${status == 3 ? 'friend' : ''}`, onclick: async (event) => {
let button = event.target
if (button.tagName == 'SPAN') {
button = button.parentElement
}
let response
if (status % 2 == 0) {
response = await follow(true, data.user.user_id);
} else {
response = await follow(false, data.user.user_id);
}
if (response.status == 200) {
status = parseInt(response.msg)
} else {
return
}
button.firstChild.innerHTML = status_text(status)
if (status == 3) {
button.classList.add('friend')
} else {
button.classList.remove('friend')
}
}},
span({class: 'gtext'},
parse(status_text(status))
)
)
2023-02-12 19:11:50 +00:00
)
2023-02-15 00:28:10 +00:00
: parse('')
2023-02-12 19:11:50 +00:00
),
div({class: 'fullline', style: 'width: 80em; margin-bottom: 0; z-index: 0;'}),
div({class: 'profilebuttons'},
2023-02-15 00:28:10 +00:00
button({id: 'profilepostbutton', class: 'selected', onclick: () => swap(0)},
2023-02-12 19:11:50 +00:00
parse('Posts')
),
2023-02-15 00:28:10 +00:00
button({id: 'profileaboutbutton', onclick: () => swap(1)},
2023-02-12 19:11:50 +00:00
parse('About')
),
2023-02-15 00:28:10 +00:00
button({id: 'profilefriendsbutton', onclick: () => swap(2)},
parse('Friends')
),
2023-02-15 18:32:43 +00:00
button({id: 'profilefollowersbutton', onclick: () => swap(3)},
parse('Followers')
),
button({id: 'profilefollowingbutton', onclick: () => swap(4)},
parse('Following')
),
2023-02-12 19:11:50 +00:00
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)
2023-02-02 01:56:09 +00:00
2023-02-12 19:11:50 +00:00
const el = document.getElementById("posts")
2023-01-26 22:29:16 +00:00
2023-02-12 19:11:50 +00:00
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'},
2023-07-26 05:04:39 +00:00
parse('Gender: ' + data.user.gender)
2023-02-12 19:11:50 +00:00
),
span({class: 'gtext bold'},
parse('Birthday: ' + parseMonth(data.user.month) + ' ' + data.user.day + ', ' + data.user.year)
),
span({class: 'gtext bold'},
2023-02-15 18:32:43 +00:00
parse('User ID: ' + data.user.user_id)
2023-02-12 19:11:50 +00:00
)
)
),
2023-02-15 00:28:10 +00:00
div({id: 'friends', class: 'hidden'},
...friends_arr.map(u => parseUser(u))
),
2023-02-15 18:32:43 +00:00
div({id: 'followers', class: 'hidden'},
...followers.map(u => parseUser(u))
),
div({id: 'following', class: 'hidden'},
...following.map(u => parseUser(u))
),
2023-02-12 19:11:50 +00:00
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'})
)
)
)
2023-02-12 19:11:50 +00:00
document.body.replaceWith(new_body)
if (data.posts.length < 10) {
document.getElementById('load').remove()
2023-02-02 16:29:37 +00:00
}
2023-02-12 19:11:50 +00:00
2023-02-02 16:29:37 +00:00
}
var isself = false
2023-02-02 16:29:37 +00:00
var page = 0
2023-02-12 19:11:50 +00:00
const data = {
self: {},
user: {},
users: {},
posts: []
}
async function load(id) {
if (id === undefined) {
id = data.user.user_id
}
2023-01-26 22:29:16 +00:00
2023-02-02 16:29:37 +00:00
const posts = (await loadusersposts(id, page)).json
2023-02-12 21:44:45 +00:00
if (posts == undefined) {
posts = []
}
2023-02-12 19:11:50 +00:00
if (posts.length < 1) {
2023-02-12 21:44:45 +00:00
let el = document.getElementsByClassName('loadp')[0]
if (el) {
el.remove()
}
2023-02-02 16:29:37 +00:00
} else {
page++
}
2023-02-12 19:11:50 +00:00
const batch = Array.from(new Set(crawl('user_id', posts))).filter(id => data.users[id] == undefined)
2023-02-02 16:29:37 +00:00
if (!isself) {
batch.push(id)
}
2023-02-12 19:11:50 +00:00
if (batch.length != 0) {
2023-02-12 21:44:45 +00:00
const users = (await loadusers(batch)).json
if (users == undefined) {
users = []
}
2023-02-12 19:11:50 +00:00
for (const user of users) {
data.users[user.user_id] = user
2023-02-02 16:29:37 +00:00
}
2023-01-26 22:29:16 +00:00
}
2023-02-02 16:29:37 +00:00
return posts
}
2023-01-26 22:29:16 +00:00
2023-02-02 16:29:37 +00:00
async function init() {
2023-01-31 05:00:13 +00:00
2023-02-02 16:29:37 +00:00
let request = await loadself()
2023-02-12 19:11:50 +00:00
2023-01-31 05:00:13 +00:00
if (request.status === 429) {
2023-02-12 19:11:50 +00:00
let new_body =
body({},
...header(false, false)
)
document.body.replaceWith(new_body)
2023-01-31 05:00:13 +00:00
throw new Error("Rate limited");
}
2023-02-13 16:59:00 +00:00
if (request.json == undefined) {
location.href = '/login'
return
}
2023-01-31 05:00:13 +00:00
data.self = request.json;
2023-01-30 23:55:36 +00:00
data.users[data.self.user_id] = data.self
2023-02-02 16:29:37 +00:00
var params = {};
for (const [key, value] of new URLSearchParams(location.search)) {
params[key] = value
}
2023-02-12 19:11:50 +00:00
let id;
2023-02-02 16:29:37 +00:00
if (params.id !== undefined && !isNaN(params.id)) {
id = parseInt(params.id);
} else {
2023-01-30 23:55:36 +00:00
id = data.self.user_id
}
2023-01-30 23:55:36 +00:00
isself = id === data.self.user_id
2023-02-12 19:11:50 +00:00
const posts = await load(id)
2023-01-26 22:29:16 +00:00
data.posts.push(... posts)
2023-02-15 00:28:10 +00:00
2023-01-30 23:55:36 +00:00
data.user = data.users[id]
2023-02-12 19:11:50 +00:00
2023-01-26 22:29:16 +00:00
render()
}
2023-07-26 05:04:39 +00:00
init()