!* Switching to the fetch api from old xhr

Less jank and now also using a more flexbile
backend for fetching json data

!!! Error handling required as there is barely any safety atm
This commit is contained in:
shockrah 2022-03-26 22:33:09 -07:00
parent 40e2d9d4be
commit e31edb55ad
3 changed files with 84 additions and 72 deletions

View File

@ -1,6 +1,8 @@
// This module serves as convenience for admin users to upload/remove videos
// from their clippable instance. There are no fancy tricks as this is meant
// purely to be a UX thing.
//import { fetch_category_videos } from './category'
//import { fetch_categories } from './index'
let UID: null|string = null
@ -10,62 +12,67 @@ let KEY: null|string = null
* Requests to admin endpoints require the uid and api key be in the headers
* rather than the query string
*/
function setHeaders(xhr: XMLHttpRequest, uid?: string, key?: string) {
function setHeaders(uid?: string, key?: string) : Headers {
UID = (uid) ? uid : UID
KEY = (key) ? key : KEY
xhr.setRequestHeader('ADMIN-API-UID', uid ? uid : UID)
xhr.setRequestHeader('ADMIN-API-KEY', key ? key : KEY)
return new Headers({
'ADMIN-API-UID': UID,
'ADMIN-API-KEY': KEY
})
}
function ok_response(xhr: XMLHttpRequest) {
return xhr.getResponseHeader('Content-Type') == 'application/json' && xhr.status == 200
function ok(resp: Response) {
return resp.headers.get('Content-Type') == 'application/json' && resp.status == 200
}
function confirm_auth() {
let uid = document.getElementById('uid')
let key = document.getElementById('apikey')
function fetch_creds() :[string, string] {
let uid = (document.getElementById('uid') as HTMLTextAreaElement).value
let key = (document.getElementById('apikey') as HTMLTextAreaElement).value
return [uid, key]
let xhr = new XMLHttpRequest()
}
async function confirm_auth() {
const [uid, key] = fetch_creds()
xhr.onload = function() {
if(ok_response(this)) {
document.getElementById('login-display').hidden = true
document.getElementById('dashboard').hidden = false
document.getElementById('error').hidden = true
} else if(this.status == 403) {
document.getElementById('error').hidden = false
document.getElementById('error').textContent = 'Invalid credenentials'
} else {
document.getElementById('error').hidden = false
document.getElementById('error').textContent = `${this.statusText}`
}
const url = window.location.origin + '/admin/dashboard'
const response = await fetch(url, {
method: 'POST',
headers: setHeaders(uid, key)
})
if(ok(response)) {
document.getElementById('login-display').hidden = true
document.getElementById('dashboard').hidden = false
document.getElementById('error').hidden = true
} else if(response.status == 403) {
document.getElementById('error').hidden = false
document.getElementById('error').textContent = 'Invalid credenentials'
} else {
document.getElementById('error').hidden = false
document.getElementById('error').textContent = `${response.statusText}`
}
xhr.open('post', window.location.origin + '/admin/dashboard')
setHeaders(xhr, (uid as HTMLTextAreaElement).value, (key as HTMLTextAreaElement).value)
xhr.send()
}
function upload_video() {
async function upload_video() {
const video_file = document.getElementById('video-file') as HTMLInputElement
const filename = video_file.files[0].name
const category_el = document.getElementById('category') as HTMLInputElement
const cat = category_el.value
let xhr = new XMLHttpRequest()
xhr.onload = function() {
if(ok_response(this)) {
video_file.value = ''
document.getElementById('video-meta').hidden = true
document.getElementById('upload-response').textContent = `${filename} uploaded`
}
// TODO Error hanlding
const url = window.location.origin + `/admin/upload-video/${cat}/${filename}`
const [uid, key] = fetch_creds()
const response = await fetch(url , {
method: 'POST',
headers: setHeaders(uid, key),
body: video_file.files[0]
})
if(ok(response)) {
video_file.value = ''
document.getElementById('video-meta').hidden = true
document.getElementById('upload-response').textContent = `${filename} uploaded`
}
xhr.open('post', window.location.origin + `/admin/upload-video/${cat}/${filename}`)
setHeaders(xhr)
xhr.send(video_file.files[0])
}
export function populate_meta_form() {
@ -87,6 +94,9 @@ export function populate_meta_form() {
}
document.addEventListener('DOMContentLoaded', () => {
/*
* Setting up hooks required for functionality
*/
document.getElementById('video-file').onchange = populate_meta_form
document.getElementById('verify-login-btn').onclick = confirm_auth
document.getElementById('confirm-upload-btn').onclick = upload_video

View File

@ -1,4 +1,4 @@
export class Category {
class Category {
name: string
thumbnail: string|null
constructor(raw: any) {
@ -70,3 +70,18 @@ export class Category {
}
export async function fetch_categories() : Promise<Array<Category>> {
const endpoint = window.location.origin + '/api/categories'
let cats: Array<Category> = []
const response = await fetch(endpoint)
if(response.headers.get('Content-Type') == 'application/json') {
const raw = JSON.parse(await response.text())
for(const cat_raw of raw) {
cats.push(new Category(cat_raw))
}
}
return cats
}

View File

@ -3,8 +3,8 @@
* to initialize a page's JS environment
* when the document.readystate is changed
* */
import { Category } from './index'
import { VideoMeta } from './category'
import {fetch_categories } from './index'
import { fetch_category_videos } from './category'
import { populate_meta_form } from './admin'
export function category_ready_handler(e?: Event) : Event {
@ -15,22 +15,16 @@ export function category_ready_handler(e?: Event) : Event {
*/
if(document.readyState != 'complete') { return e }
let xml = new XMLHttpRequest()
xml.onload = function() {
if(this.getResponseHeader('Content-Type') == 'application/json') {
let raw = JSON.parse(this.responseText)
for(const cat_raw of raw) {
let cat = new VideoMeta(cat_raw)
cat.as_div()
}
fetch_category_videos()
.then(videos => {
for(const vid of videos) {
vid.as_div()
}
}
const endpoint = window.location.origin + '/api' + window.location.pathname
xml.open('GET', endpoint, true)
xml.send()
})
.catch(reason => {
// TODO: actual error handling
console.log(reason)
})
return e
}
@ -39,23 +33,16 @@ export function index_ready_handler(e?: Event) : Event {
if(document.readyState != 'complete') { return e }
// All we do here is basically make a get request to /api/categories
const endpoint = window.location.origin + '/api/categories'
let xml = new XMLHttpRequest()
xml.onload = function() {
if(this.getResponseHeader('Content-Type') == 'application/json') {
let raw = JSON.parse(this.responseText)
for(const cat_raw of raw) {
let cat = new Category(cat_raw)
cat.as_div()
}
fetch_categories()
.then(categories => {
for(const cat of categories) {
cat.as_div()
}
}
// Fire request
xml.open('GET', endpoint, true) // sync request
xml.send(null) // nothing required for stuff
})
.catch(reason => {
// TODO: actual error hanlding
console.log('index_ready_handler::fetch_categories rejection', reason)
})
return e
}