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

View File

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