clippable/ts/admin.ts
shockrah 4416d08994 + admin::populate_video_list now populates t he video list
The ul here is meant to serve as a quick
way to check what videos are being served
as well as removing videos

+ category::VideoMeta::as_li built for admin video list
This is basically how we spit this out onto
the DOM
2022-03-27 00:00:50 -07:00

124 lines
3.8 KiB
TypeScript

// 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, VideoMeta } from './category'
import { fetch_categories } from './index'
let UID: null|string = null
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(uid?: string, key?: string) : Headers {
UID = (uid) ? uid : UID
KEY = (key) ? key : KEY
return new Headers({
'ADMIN-API-UID': UID,
'ADMIN-API-KEY': KEY
})
}
function ok(resp: Response) {
return resp.headers.get('Content-Type') == 'application/json' && resp.status == 200
}
function fetch_creds() :[string, string] {
let uid = (document.getElementById('uid') as HTMLTextAreaElement).value
let key = (document.getElementById('apikey') as HTMLTextAreaElement).value
return [uid, key]
}
async function confirm_auth() {
const [uid, key] = fetch_creds()
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}`
}
}
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
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`
}
}
export function populate_meta_form() {
let file = document.getElementById('video-file') as HTMLInputElement
// When we remove the file this array becomes 0 so the check is required
if(file.files.length == 0) {
document.getElementById('video-meta').hidden = true
} else {
// Size in MB
let size = file.files[0].size / 1024 / 1000
document.getElementById('vmn').textContent = `${file.files[0].name}`
document.getElementById('vms').textContent = `${size} MB`
document.getElementById('vmt').textContent = `${file.files[0].type}`
document.getElementById('video-meta').hidden = false
}
}
async function populate_video_list() {
const categories = await fetch_categories()
let videos: Array<VideoMeta> = []
for(const cat of categories) {
const vids = await fetch_category_videos(cat.name)
for(const v of vids) {
videos.push(v)
}
}
const list_ref = document.getElementById("videos-list")
for(const video of videos) {
list_ref.appendChild(video.as_li())
}
}
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
populate_video_list()
.then(value => console.log('succesful list population: ', value))
.catch(reason => console.log('Failure in populate_video_list', reason))
})