generated from nhcarrigan/template
feat: set up service to fetch comic data
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@ -40,3 +40,6 @@ testem.log
|
|||||||
# System files
|
# System files
|
||||||
.DS_Store
|
.DS_Store
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
|
||||||
|
# We upload this to our CDN.
|
||||||
|
comics.json
|
||||||
|
15
removeBadge.js
Normal file
15
removeBadge.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* @copyright nhcarrigan
|
||||||
|
* @license Naomi's Public License
|
||||||
|
* @author Naomi Carrigan
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run this in the Discord console to remove the bot badges from the app.
|
||||||
|
* This is how we create the appearance that the webhook is a user.
|
||||||
|
*/
|
||||||
|
const appBadges = document.querySelectorAll("[class^='botTag']")
|
||||||
|
for (const badge of appBadges) {
|
||||||
|
badge.remove();
|
||||||
|
}
|
75
src/app/comic-service.ts
Normal file
75
src/app/comic-service.ts
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/**
|
||||||
|
* @copyright nhcarrigan
|
||||||
|
* @license Naomi's Public License
|
||||||
|
* @author Naomi Carrigan
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Injectable } from "@angular/core";
|
||||||
|
|
||||||
|
const oneDay = 1000 * 60 * 60 * 24;
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: "root",
|
||||||
|
})
|
||||||
|
export class ComicService {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/class-literal-property-style -- I should turn this rule off.
|
||||||
|
private readonly comicsUrl: string = "https://cdn.yurigpt.com/comics.json";
|
||||||
|
|
||||||
|
private ttl = 0;
|
||||||
|
|
||||||
|
private comics: Array<{
|
||||||
|
number: number;
|
||||||
|
title: string;
|
||||||
|
date: string;
|
||||||
|
}> = [];
|
||||||
|
|
||||||
|
public constructor() {
|
||||||
|
void this.loadComics();
|
||||||
|
}
|
||||||
|
private static isObject(object: unknown): object is Record<string, unknown> {
|
||||||
|
return typeof object === "object" && object !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static validateComics(
|
||||||
|
comics: unknown,
|
||||||
|
): comics is Array<{ number: number; title: string; date: string }> {
|
||||||
|
if (!Array.isArray(comics)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return comics.every((comic) => {
|
||||||
|
if (!ComicService.isObject(comic)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
"number" in comic
|
||||||
|
&& "title" in comic
|
||||||
|
&& "date" in comic
|
||||||
|
&& typeof comic["number"] === "number"
|
||||||
|
&& typeof comic["title"] === "string"
|
||||||
|
&& typeof comic["date"] === "string"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async loadComics(): Promise<void> {
|
||||||
|
if (this.ttl > Date.now()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.comics = [];
|
||||||
|
const response = await fetch(this.comicsUrl);
|
||||||
|
const data: unknown = await response.json();
|
||||||
|
if (ComicService.validateComics(data)) {
|
||||||
|
this.comics = data.sort((a, b) => {
|
||||||
|
return a.number - b.number;
|
||||||
|
});
|
||||||
|
this.ttl = Date.now() + oneDay;
|
||||||
|
} else {
|
||||||
|
console.error("Invalid comics data format:", data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getComics(): Array<{ number: number; title: string; date: string }> {
|
||||||
|
return this.comics;
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user