From 06daacbbf60104d34496ca5c49a37c7483e59728 Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Mon, 22 Apr 2019 15:02:51 +0900 Subject: [PATCH] Added null checks and async functions --- scripts/Actions/AnimeList.ts | 26 +++++++++--- scripts/Actions/Audio.ts | 9 +++- scripts/Actions/Diff.ts | 16 ++++--- scripts/Actions/Editor.ts | 24 +++++++---- scripts/Actions/Explore.ts | 2 +- scripts/Actions/Forum.ts | 82 ++++++++++++++++++++++++------------ scripts/Actions/Object.ts | 39 +++++++++++------ scripts/Actions/Publish.ts | 22 ++++++---- scripts/AnimeNotifier.ts | 13 +++--- 9 files changed, 158 insertions(+), 75 deletions(-) diff --git a/scripts/Actions/AnimeList.ts b/scripts/Actions/AnimeList.ts index 75f9d10f..fb65d82e 100644 --- a/scripts/Actions/AnimeList.ts +++ b/scripts/Actions/AnimeList.ts @@ -5,6 +5,12 @@ export async function addAnimeToCollection(arn: AnimeNotifier, button: HTMLButto button.disabled = true let {animeId} = button.dataset + + if(!animeId) { + console.error("Button without anime ID:", button) + return + } + let apiEndpoint = arn.findAPIEndpoint(button) try { @@ -21,7 +27,7 @@ export async function addAnimeToCollection(arn: AnimeNotifier, button: HTMLButto } // Remove anime from collection -export function removeAnimeFromCollection(arn: AnimeNotifier, button: HTMLElement) { +export async function removeAnimeFromCollection(arn: AnimeNotifier, button: HTMLElement) { if(!confirm("Are you sure you want to remove it from your collection?")) { return } @@ -29,9 +35,19 @@ export function removeAnimeFromCollection(arn: AnimeNotifier, button: HTMLElemen button.textContent = "Removing..." let {animeId, nick} = button.dataset - let apiEndpoint = arn.findAPIEndpoint(button) - arn.post(apiEndpoint + "/remove/" + animeId) - .then(() => arn.app.load(`/+${nick}/animelist/` + (document.getElementById("Status") as HTMLSelectElement).value)) - .catch(err => arn.statusMessage.showError(err)) + if(!animeId || !nick) { + console.error("Button without nick or anime ID:", button) + return + } + + let apiEndpoint = arn.findAPIEndpoint(button) + let status = document.getElementById("Status") as HTMLSelectElement + + try { + await arn.post(apiEndpoint + "/remove/" + animeId) + await arn.app.load(`/+${nick}/animelist/` + status.value) + } catch(err) { + arn.statusMessage.showError(err) + } } \ No newline at end of file diff --git a/scripts/Actions/Audio.ts b/scripts/Actions/Audio.ts index a8e6ff55..3e268b33 100644 --- a/scripts/Actions/Audio.ts +++ b/scripts/Actions/Audio.ts @@ -2,7 +2,14 @@ import AnimeNotifier from "../AnimeNotifier" // Play audio export function playAudio(arn: AnimeNotifier, element: HTMLElement) { - arn.audioPlayer.play(element.dataset.mediaId, element.dataset.audioSrc) + let {mediaId, audioSrc} = element.dataset + + if(!mediaId || !audioSrc) { + console.error("Invalid media ID or audio source:", element) + return + } + + arn.audioPlayer.play(mediaId, audioSrc) } // Pause audio diff --git a/scripts/Actions/Diff.ts b/scripts/Actions/Diff.ts index 25079336..b3b70ea4 100644 --- a/scripts/Actions/Diff.ts +++ b/scripts/Actions/Diff.ts @@ -3,18 +3,20 @@ import { requestIdleCallback } from "../Utils" // Load export function load(arn: AnimeNotifier, element: HTMLElement) { - let url = element.dataset.url || (element as HTMLAnchorElement).getAttribute("href") + let url = element.dataset.url || (element as HTMLAnchorElement).href arn.app.load(url) } // Diff -export function diff(arn: AnimeNotifier, element: HTMLElement) { - let url = element.dataset.url || (element as HTMLAnchorElement).getAttribute("href") +export async function diff(arn: AnimeNotifier, element: HTMLElement) { + let url = element.dataset.url || (element as HTMLAnchorElement).href + + try { + await arn.diff(url) - arn.diff(url) - .then(() => { // Avoid instant layout thrashing requestIdleCallback(() => arn.scrollTo(element)) - }) - .catch(console.error) + } catch(err) { + arn.statusMessage.showError(err) + } } \ No newline at end of file diff --git a/scripts/Actions/Editor.ts b/scripts/Actions/Editor.ts index bf26497d..fb336d53 100644 --- a/scripts/Actions/Editor.ts +++ b/scripts/Actions/Editor.ts @@ -1,7 +1,7 @@ import AnimeNotifier from "../AnimeNotifier" // newAnimeDiffIgnore -export function newAnimeDiffIgnore(arn: AnimeNotifier, button: HTMLButtonElement) { +export async function newAnimeDiffIgnore(arn: AnimeNotifier, button: HTMLButtonElement) { if(!confirm("Are you sure you want to permanently ignore this difference?")) { return } @@ -9,14 +9,16 @@ export function newAnimeDiffIgnore(arn: AnimeNotifier, button: HTMLButtonElement let id = button.dataset.id let hash = button.dataset.hash - arn.post(`/api/new/ignoreanimedifference`, { - id, - hash - }) - .then(() => { + try { + await arn.post(`/api/new/ignoreanimedifference`, { + id, + hash + }) + arn.reloadContent() - }) - .catch(err => arn.statusMessage.showError(err)) + } catch(err) { + arn.statusMessage.showError(err) + } } // Import Kitsu anime @@ -26,6 +28,12 @@ export async function importKitsuAnime(arn: AnimeNotifier, button: HTMLButtonEle } let newTab = window.open() + + if(!newTab) { + arn.statusMessage.showError("Error opening new tab") + return + } + let animeId = button.dataset.id let response = await fetch(`/api/import/kitsu/anime/${animeId}`, { method: "POST", diff --git a/scripts/Actions/Explore.ts b/scripts/Actions/Explore.ts index a8fcdce4..f8ce3803 100644 --- a/scripts/Actions/Explore.ts +++ b/scripts/Actions/Explore.ts @@ -3,7 +3,7 @@ import { findAll } from "scripts/Utils" // Filter anime on explore page export function filterAnime(arn: AnimeNotifier, input: HTMLInputElement) { - let root = document.getElementById("filter-root") + let root = document.getElementById("filter-root") as HTMLElement let elementYear = document.getElementById("filter-year") as HTMLSelectElement let elementSeason = document.getElementById("filter-season") as HTMLSelectElement diff --git a/scripts/Actions/Forum.ts b/scripts/Actions/Forum.ts index 53be74c2..9d3778ba 100644 --- a/scripts/Actions/Forum.ts +++ b/scripts/Actions/Forum.ts @@ -4,24 +4,30 @@ import AnimeNotifier from "../AnimeNotifier" export function editPost(arn: AnimeNotifier, element: HTMLElement) { let postId = element.dataset.id - let render = document.getElementById("render-" + postId) - let toolbar = document.getElementById("toolbar-" + postId) - let title = document.getElementById("title-" + postId) - let source = document.getElementById("source-" + postId) - let edit = document.getElementById("edit-toolbar-" + postId) + if(!postId) { + console.error("Post missing post ID:", postId) + return + } + + let render = document.getElementById("render-" + postId) as HTMLElement + let toolbar = document.getElementById("toolbar-" + postId) as HTMLElement + let source = document.getElementById("source-" + postId) as HTMLElement + let edit = document.getElementById("edit-toolbar-" + postId) as HTMLElement render.classList.toggle("hidden") toolbar.classList.toggle("hidden") source.classList.toggle("hidden") edit.classList.toggle("hidden") + let title = document.getElementById("title-" + postId) + if(title) { title.classList.toggle("hidden") } } // Save post -export function savePost(arn: AnimeNotifier, element: HTMLElement) { +export async function savePost(arn: AnimeNotifier, element: HTMLElement) { let postId = element.dataset.id let source = document.getElementById("source-" + postId) as HTMLTextAreaElement let title = document.getElementById("title-" + postId) as HTMLInputElement @@ -38,26 +44,32 @@ export function savePost(arn: AnimeNotifier, element: HTMLElement) { let apiEndpoint = arn.findAPIEndpoint(element) - arn.post(apiEndpoint, updates) - .then(() => arn.reloadContent()) - .catch(err => arn.statusMessage.showError(err)) + try { + await arn.post(apiEndpoint, updates) + arn.reloadContent() + } catch(err) { + arn.statusMessage.showError(err) + } } // Delete post -export function deletePost(arn: AnimeNotifier, element: HTMLElement) { +export async function deletePost(arn: AnimeNotifier, element: HTMLElement) { if(!confirm(`Are you sure you want to delete this Post?`)) { return } let endpoint = arn.findAPIEndpoint(element) - arn.post(endpoint + "/delete") - .then(() => arn.reloadContent()) - .catch(err => arn.statusMessage.showError(err)) + try { + await arn.post(endpoint + "/delete") + arn.reloadContent() + } catch(err) { + arn.statusMessage.showError(err) + } } // Create post -export function createPost(arn: AnimeNotifier, element: HTMLElement) { +export async function createPost(arn: AnimeNotifier, element: HTMLElement) { let textarea = document.getElementById("new-post-text") as HTMLTextAreaElement let {parentId, parentType} = element.dataset @@ -68,14 +80,17 @@ export function createPost(arn: AnimeNotifier, element: HTMLElement) { tags: [] } - arn.post("/api/new/post", post) - .then(() => arn.reloadContent()) - .then(() => textarea.value = "") - .catch(err => arn.statusMessage.showError(err)) + try { + await arn.post("/api/new/post", post) + await arn.reloadContent() + textarea.value = "" + } catch(err) { + arn.statusMessage.showError(err) + } } // Create thread -export function createThread(arn: AnimeNotifier) { +export async function createThread(arn: AnimeNotifier) { let title = document.getElementById("title") as HTMLInputElement let text = document.getElementById("text") as HTMLTextAreaElement let category = document.getElementById("tag") as HTMLInputElement @@ -86,9 +101,12 @@ export function createThread(arn: AnimeNotifier) { tags: [category.value] } - arn.post("/api/new/thread", thread) - .then(() => arn.app.load("/forum/" + thread.tags[0])) - .catch(err => arn.statusMessage.showError(err)) + try { + await arn.post("/api/new/thread", thread) + await arn.app.load("/forum/" + thread.tags[0]) + } catch(err) { + arn.statusMessage.showError(err) + } } // Reply to a post @@ -97,6 +115,11 @@ export async function reply(arn: AnimeNotifier, element: HTMLElement) { let repliesId = `replies-${element.dataset.postId}` let replies = document.getElementById(repliesId) + if(!replies) { + console.error("Missing replies container:", element) + return + } + // Delete old reply area let oldReplyArea = document.getElementById("new-post") @@ -130,16 +153,16 @@ export function cancelReply(arn: AnimeNotifier, element: HTMLElement) { // Lock thread export function lockThread(arn: AnimeNotifier, element: HTMLButtonElement) { - setThreadLock(arn, element, true) + return setThreadLock(arn, element, true) } // Unlock thread export function unlockThread(arn: AnimeNotifier, element: HTMLButtonElement) { - setThreadLock(arn, element, false) + return setThreadLock(arn, element, false) } // Set thread locked state -function setThreadLock(arn: AnimeNotifier, element: HTMLButtonElement, state: boolean) { +async function setThreadLock(arn: AnimeNotifier, element: HTMLButtonElement, state: boolean) { let verb = state ? "lock" : "unlock" if(!confirm(`Are you sure you want to ${verb} this Thread?`)) { @@ -148,7 +171,10 @@ function setThreadLock(arn: AnimeNotifier, element: HTMLButtonElement, state: bo let endpoint = arn.findAPIEndpoint(element) - arn.post(`${endpoint}/${verb}`) - .then(() => arn.reloadContent()) - .catch(err => arn.statusMessage.showError(err)) + try { + await arn.post(`${endpoint}/${verb}`) + await arn.reloadContent() + } catch(err) { + arn.statusMessage.showError(err) + } } \ No newline at end of file diff --git a/scripts/Actions/Object.ts b/scripts/Actions/Object.ts index e4ce690e..63beb2b8 100644 --- a/scripts/Actions/Object.ts +++ b/scripts/Actions/Object.ts @@ -1,17 +1,30 @@ import AnimeNotifier from "../AnimeNotifier" // New -export function newObject(arn: AnimeNotifier, button: HTMLButtonElement) { +export async function newObject(arn: AnimeNotifier, button: HTMLButtonElement) { let dataType = button.dataset.type - arn.post(`/api/new/${dataType}`) - .then(response => response.json()) - .then(obj => arn.app.load(`/${dataType}/${obj.id}/edit`)) - .catch(err => arn.statusMessage.showError(err)) + if(!dataType) { + console.error("Missing data type:", button) + return + } + + try { + let response = await arn.post(`/api/new/${dataType}`) + + if(!response) { + throw `Failed creating ${dataType}` + } + + let json = await response.json() + await arn.app.load(`/${dataType}/${json.id}/edit`) + } catch(err) { + arn.statusMessage.showError(err) + } } // Delete -export function deleteObject(arn: AnimeNotifier, button: HTMLButtonElement) { +export async function deleteObject(arn: AnimeNotifier, button: HTMLButtonElement) { let confirmType = button.dataset.confirmType let returnPath = button.dataset.returnPath @@ -28,13 +41,15 @@ export function deleteObject(arn: AnimeNotifier, button: HTMLButtonElement) { let endpoint = arn.findAPIEndpoint(button) - arn.post(endpoint + "/delete") - .then(() => { + try { + await arn.post(endpoint + "/delete") + if(returnPath) { - arn.app.load(returnPath) + await arn.app.load(returnPath) } else { - arn.reloadContent() + await arn.reloadContent() } - }) - .catch(err => arn.statusMessage.showError(err)) + } catch(err) { + arn.statusMessage.showError(err) + } } \ No newline at end of file diff --git a/scripts/Actions/Publish.ts b/scripts/Actions/Publish.ts index 8c087c49..31597f93 100644 --- a/scripts/Actions/Publish.ts +++ b/scripts/Actions/Publish.ts @@ -1,19 +1,25 @@ import AnimeNotifier from "../AnimeNotifier" // Publish -export function publish(arn: AnimeNotifier, button: HTMLButtonElement) { +export async function publish(arn: AnimeNotifier, button: HTMLButtonElement) { let endpoint = arn.findAPIEndpoint(button) - arn.post(endpoint + "/publish") - .then(() => arn.app.load(arn.app.currentPath.replace("/edit", ""))) - .catch(err => arn.statusMessage.showError(err)) + try { + await arn.post(endpoint + "/publish") + await arn.app.load(arn.app.currentPath.replace("/edit", "")) + } catch(err) { + arn.statusMessage.showError(err) + } } // Unpublish -export function unpublish(arn: AnimeNotifier, button: HTMLButtonElement) { +export async function unpublish(arn: AnimeNotifier, button: HTMLButtonElement) { let endpoint = arn.findAPIEndpoint(button) - arn.post(endpoint + "/unpublish") - .then(() => arn.reloadContent()) - .catch(err => arn.statusMessage.showError(err)) + try { + await arn.post(endpoint + "/unpublish") + await arn.reloadContent() + } catch(err) { + arn.statusMessage.showError(err) + } } \ No newline at end of file diff --git a/scripts/AnimeNotifier.ts b/scripts/AnimeNotifier.ts index ac98d26e..cc2b0c96 100644 --- a/scripts/AnimeNotifier.ts +++ b/scripts/AnimeNotifier.ts @@ -514,7 +514,7 @@ export default class AnimeNotifier { e.dataTransfer.setData("text", element.dataset.index) }, false) - element.addEventListener("dblclick", e => { + element.addEventListener("dblclick", async e => { if(!element.draggable || !element.dataset.index) { return } @@ -527,10 +527,13 @@ export default class AnimeNotifier { let apiEndpoint = this.findAPIEndpoint(element) - this.post(apiEndpoint + "/use/" + element.dataset.index) - .then(() => this.reloadContent()) - .then(() => this.statusMessage.showInfo(`You used ${itemName}.`)) - .catch(err => this.statusMessage.showError(err)) + try { + await this.post(apiEndpoint + "/use/" + element.dataset.index) + await this.reloadContent() + this.statusMessage.showInfo(`You used ${itemName}.`) + } catch(err) { + this.statusMessage.showError(err) + } }, false) element.addEventListener("dragenter", e => {