From 4408da41647b0bafc0efcd20124b769b647cc9a6 Mon Sep 17 00:00:00 2001 From: Khadim Date: Thu, 14 Sep 2023 15:05:31 +0200 Subject: [PATCH] Impl. Feedback --- web/ts/api/admin-lecture-list.ts | 42 +++++++++--------- web/ts/utilities/fetch-wrappers.ts | 71 ++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 20 deletions(-) diff --git a/web/ts/api/admin-lecture-list.ts b/web/ts/api/admin-lecture-list.ts index f5d37342d..68b744e04 100644 --- a/web/ts/api/admin-lecture-list.ts +++ b/web/ts/api/admin-lecture-list.ts @@ -1,6 +1,14 @@ -import { del, get, post, put } from "../utilities/fetch-wrappers"; +import { + del, + get, + patch, + post, + postFormData, + PostFormDataListener, + put, + uploadFile, +} from "../utilities/fetch-wrappers"; import { StatusCodes } from "http-status-codes"; -import { Delete, patchData, postData, postFormData, putData, uploadFile, UploadFileListener } from "../global"; export interface UpdateLectureMetaRequest { name?: string; @@ -145,13 +153,10 @@ export const AdminLectureList = { * @param request */ updateMetadata: async function (courseId: number, lectureId: number, request: UpdateLectureMetaRequest) { - console.log({ - request, - }); const promises = []; if (request.name !== undefined) { promises.push( - postData(`/api/course/${courseId}/renameLecture/${lectureId}`, { + post(`/api/course/${courseId}/renameLecture/${lectureId}`, { name: request.name, }), ); @@ -159,7 +164,7 @@ export const AdminLectureList = { if (request.description !== undefined) { promises.push( - putData(`/api/course/${courseId}/updateDescription/${lectureId}`, { + put(`/api/course/${courseId}/updateDescription/${lectureId}`, { name: request.description, }), ); @@ -167,7 +172,7 @@ export const AdminLectureList = { if (request.lectureHallId !== undefined) { promises.push( - postData("/api/setLectureHall", { + post("/api/setLectureHall", { streamIds: [lectureId], lectureHall: request.lectureHallId, }), @@ -176,7 +181,7 @@ export const AdminLectureList = { if (request.isChatEnabled !== undefined) { promises.push( - patchData(`/api/stream/${lectureId}/chat/enabled`, { + patch(`/api/stream/${lectureId}/chat/enabled`, { lectureId, isChatEnabled: request.isChatEnabled, }), @@ -195,8 +200,8 @@ export const AdminLectureList = { * @param courseId * @param lectureId */ - saveSeriesMetadata: async (courseId: number, lectureId: number) => { - return await postData(`/api/course/${courseId}/updateLectureSeries/${lectureId}`); + saveSeriesMetadata: async (courseId: number, lectureId: number): Promise => { + await post(`/api/course/${courseId}/updateLectureSeries/${lectureId}`); }, /** @@ -205,12 +210,9 @@ export const AdminLectureList = { * @param isPrivate */ setPrivate: async (lectureId: number, isPrivate: boolean): Promise => { - const res = await patchData(`/api/stream/${lectureId}/visibility`, { + await patch(`/api/stream/${lectureId}/visibility`, { private: isPrivate, }); - if (res.status !== StatusCodes.OK) { - throw Error(res.body.toString()); - } }, /** @@ -226,7 +228,7 @@ export const AdminLectureList = { lectureId: number, videoType: string, file: File, - listener: UploadFileListener = {}, + listener: PostFormDataListener = {}, ) => { await uploadFile( `/api/course/${courseId}/uploadVODMedia?streamID=${lectureId}&videoType=${videoType}`, @@ -246,7 +248,7 @@ export const AdminLectureList = { courseId: number, lectureId: number, file: File, - listener: UploadFileListener = {}, + listener: PostFormDataListener = {}, ) => { return await uploadFile(`/api/stream/${lectureId}/files?type=file`, file, listener); }, @@ -262,7 +264,7 @@ export const AdminLectureList = { courseId: number, lectureId: number, url: string, - listener: UploadFileListener = {}, + listener: PostFormDataListener = {}, ) => { const vodUploadFormData = new FormData(); vodUploadFormData.append("file_url", url); @@ -270,7 +272,7 @@ export const AdminLectureList = { }, deleteAttachment: async (courseId: number, lectureId: number, attachmentId: number) => { - return Delete(`/api/stream/${lectureId}/files/${attachmentId}`); + return del(`/api/stream/${lectureId}/files/${attachmentId}`); }, /** @@ -289,7 +291,7 @@ export const AdminLectureList = { * @param lectureIds */ delete: async function (courseId: number, lectureIds: number[]): Promise { - return await postData(`/api/course/${courseId}/deleteLectures`, { + return await post(`/api/course/${courseId}/deleteLectures`, { streamIDs: lectureIds, }); }, diff --git a/web/ts/utilities/fetch-wrappers.ts b/web/ts/utilities/fetch-wrappers.ts index 797912d56..ed4bf4f0c 100644 --- a/web/ts/utilities/fetch-wrappers.ts +++ b/web/ts/utilities/fetch-wrappers.ts @@ -42,6 +42,44 @@ export async function post(url: string, body: object = {}) { }); } +export interface PostFormDataListener { + onProgress?: (progress: number) => void; +} + +/** + * Wrapper for XMLHttpRequest to send form data via POST + * @param {string} url URL to send to + * @param {FormData} body form-data + * @param {PostFormDataListener} listener attached progress listeners + * @return {Promise} + */ +export function postFormData( + url: string, + body: FormData, + listener: PostFormDataListener = {}, +): Promise { + const xhr = new XMLHttpRequest(); + return new Promise((resolve, reject) => { + xhr.onloadend = () => { + if (xhr.status === 200) { + resolve(xhr); + } else { + reject(xhr); + } + }; + xhr.upload.onprogress = (e: ProgressEvent) => { + if (!e.lengthComputable) { + return; + } + if (listener.onProgress) { + listener.onProgress(Math.floor(100 * (e.loaded / e.total))); + } + }; + xhr.open("POST", url); + xhr.send(body); + }); +} + /** * Wrapper for Javascript's fetch function for PUT * @param {string} url URL to fetch @@ -63,6 +101,27 @@ export async function put(url = "", body: object = {}) { }); } +/** + * Wrapper for Javascript's fetch function for PATCH + * @param {string} url URL to fetch + * @param {object} body Data object to put + * @return {Promise} + */ +export async function patch(url = "", body = {}) { + return await fetch(url, { + method: "PATCH", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(body), + }).then((res) => { + if (!res.ok) { + throw Error(res.statusText); + } + return res; + }); +} + /** * Wrapper for Javascript's fetch function for DELETE * @param {string} url URL to fetch @@ -71,3 +130,15 @@ export async function put(url = "", body: object = {}) { export async function del(url: string) { return await fetch(url, { method: "DELETE" }); } + +/** + * Wrapper for XMLHttpRequest to upload a file + * @param url URL to upload to + * @param file File to be uploaded + * @param listener Upload progress listeners + */ +export function uploadFile(url: string, file: File, listener: PostFormDataListener = {}): Promise { + const vodUploadFormData = new FormData(); + vodUploadFormData.append("file", file); + return postFormData(url, vodUploadFormData, listener); +}