aboutsummaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
Diffstat (limited to 'utils')
-rw-r--r--utils/appendMetaToEpisodes.ts (renamed from utils/appendMetaToEpisodes.js)29
-rw-r--r--utils/combineImages.ts (renamed from utils/combineImages.js)21
-rw-r--r--utils/getFormat.ts (renamed from utils/getFormat.js)2
-rw-r--r--utils/getGreetings.ts (renamed from utils/getGreetings.js)0
-rw-r--r--utils/getRedisWithPrefix.ts (renamed from utils/getRedisWithPrefix.js)12
-rw-r--r--utils/getTimes.ts (renamed from utils/getTimes.js)36
-rw-r--r--utils/imageUtils.ts (renamed from utils/imageUtils.js)23
-rw-r--r--utils/parseMetaData.ts36
-rw-r--r--utils/request/index.ts111
-rw-r--r--utils/schedulesUtils.ts (renamed from utils/schedulesUtils.js)55
-rw-r--r--utils/useCountdownSeconds.js37
11 files changed, 280 insertions, 82 deletions
diff --git a/utils/appendMetaToEpisodes.js b/utils/appendMetaToEpisodes.ts
index 197788b..5f74df3 100644
--- a/utils/appendMetaToEpisodes.js
+++ b/utils/appendMetaToEpisodes.ts
@@ -1,8 +1,31 @@
-async function appendMetaToEpisodes(episodesData, images) {
+type Image = {
+ number?: number;
+ episode?: number;
+ img: string;
+ title: string;
+ description: string;
+};
+
+type Episode = {
+ number: number;
+ img?: string;
+ title?: string;
+ description?: string;
+};
+
+type ProviderEpisodes = {
+ episodes: Episode[];
+};
+
+async function appendMetaToEpisodes(
+ episodesData: ProviderEpisodes[],
+ images: Image[]
+): Promise<ProviderEpisodes[]> {
// Create a dictionary for faster lookup of images based on episode number
- const episodeImages = {};
+ const episodeImages: { [key: number]: Image } = {};
images.forEach((image) => {
- episodeImages[image.number || image.episode] = image;
+ image.episode && (episodeImages[image.episode] = image);
+ image.number && (episodeImages[image.number] = image);
});
// Iterate through each provider's episodes data
diff --git a/utils/combineImages.js b/utils/combineImages.ts
index abf34ed..01b7ef3 100644
--- a/utils/combineImages.js
+++ b/utils/combineImages.ts
@@ -1,6 +1,23 @@
-async function appendImagesToEpisodes(episodesData, images) {
+interface Image {
+ episode: number;
+ img: string;
+}
+
+interface Episode {
+ number: number;
+ img?: string;
+}
+
+interface ProviderEpisodes {
+ episodes: Episode[];
+}
+
+async function appendImagesToEpisodes(
+ episodesData: ProviderEpisodes[],
+ images: Image[]
+) {
// Create a dictionary for faster lookup of images based on episode number
- const episodeImages = {};
+ const episodeImages: { [key: number]: string } = {};
images.forEach((image) => {
episodeImages[image.episode] = image.img;
});
diff --git a/utils/getFormat.js b/utils/getFormat.ts
index 9a2e3e3..7f3eece 100644
--- a/utils/getFormat.js
+++ b/utils/getFormat.ts
@@ -11,7 +11,7 @@ const data = [
{ name: "One Shot", value: "ONE_SHOT" },
];
-export function getFormat(format) {
+export function getFormat(format: string) {
const results = data.find((item) => item.value === format);
return results?.name;
}
diff --git a/utils/getGreetings.js b/utils/getGreetings.ts
index 1dd2a53..1dd2a53 100644
--- a/utils/getGreetings.js
+++ b/utils/getGreetings.ts
diff --git a/utils/getRedisWithPrefix.js b/utils/getRedisWithPrefix.ts
index b85589b..dacf78e 100644
--- a/utils/getRedisWithPrefix.js
+++ b/utils/getRedisWithPrefix.ts
@@ -1,6 +1,6 @@
import { redis } from "@/lib/redis";
-export async function getValuesWithPrefix(prefix) {
+export async function getValuesWithPrefix(prefix: string) {
let cursor = "0"; // Start at the beginning of the keyspace
let values = [];
@@ -16,7 +16,9 @@ export async function getValuesWithPrefix(prefix) {
// Retrieve values for matching keys and add them to the array
for (const key of matchingKeys) {
const value = await redis.get(key);
- values.push(JSON.parse(value));
+ if (value !== null) {
+ values.push(JSON.parse(value));
+ }
}
// Update the cursor for the next iteration
@@ -26,7 +28,7 @@ export async function getValuesWithPrefix(prefix) {
return values;
}
-export async function countKeysWithPrefix(prefix) {
+export async function countKeysWithPrefix(prefix: string) {
let cursor = "0"; // Start at the beginning of the keyspace
let count = 0;
@@ -67,10 +69,10 @@ export async function getKeysWithNumericKeys() {
const allKeys = await redis.keys("*"); // Fetch all keys in Redis
const numericKeys = allKeys.filter((key) => /^\d+$/.test(key)); // Filter keys that contain only numbers
- const values = [];
+ const values: any[] = [];
for (const key of numericKeys) {
- const value = await redis.del(key);
+ await redis.del(key);
}
return values;
diff --git a/utils/getTimes.js b/utils/getTimes.ts
index 95df803..c3fe0ad 100644
--- a/utils/getTimes.js
+++ b/utils/getTimes.ts
@@ -1,4 +1,4 @@
-export function convertUnixToTime(timestamp) {
+export function convertUnixToTime(timestamp: number) {
const date = new Date(timestamp);
const hours = date.getHours();
const minutes = date.getMinutes();
@@ -34,7 +34,7 @@ export function getCurrentSeason() {
}
}
-export function convertUnixToCountdown(time) {
+export function convertUnixToCountdown(time: number) {
let date = new Date(time * 1000);
let days = date.getDay();
let hours = date.getHours();
@@ -57,7 +57,7 @@ export function convertUnixToCountdown(time) {
return countdown.trim();
}
-export function convertSecondsToTime(sec) {
+export function convertSecondsToTime(sec: number) {
let days = Math.floor(sec / (3600 * 24));
let hours = Math.floor((sec % (3600 * 24)) / 3600);
let minutes = Math.floor((sec % 3600) / 60);
@@ -85,8 +85,8 @@ export function convertSecondsToTime(sec) {
}
// Function to convert timestamp to AM/PM time format
-export const timeStamptoAMPM = (timestamp) => {
- const date = new Date(timestamp * 1000);
+export const timeStamptoAMPM = (timestamp: number | string) => {
+ const date = new Date(Number(timestamp) * 1000);
const hours = date.getHours();
const minutes = date.getMinutes();
const ampm = hours >= 12 ? "PM" : "AM";
@@ -95,19 +95,18 @@ export const timeStamptoAMPM = (timestamp) => {
return `${formattedHours}:${minutes.toString().padStart(2, "0")} ${ampm}`;
};
-export const timeStamptoHour = (timestamp) => {
- const options = { hour: "numeric", minute: "numeric", hour12: true };
+export const timeStamptoHour = (timestamp: number) => {
const currentTime = new Date().getTime() / 1000;
const formattedTime = new Date(timestamp * 1000).toLocaleTimeString(
undefined,
- options
+ { hour: "numeric", minute: "numeric", hour12: true }
);
const status = timestamp <= currentTime ? "aired" : "airing";
return `${status} at ${formattedTime}`;
};
-export function unixTimestampToRelativeTime(unixTimestamp) {
+export function unixTimestampToRelativeTime(unixTimestamp: number) {
const now = Math.floor(Date.now() / 1000); // Current Unix timestamp in seconds
let secondsDifference = now - unixTimestamp;
@@ -135,9 +134,26 @@ export function unixTimestampToRelativeTime(unixTimestamp) {
return "just now";
}
-export function unixToSeconds(unixTimestamp) {
+export function unixToSeconds(unixTimestamp: number) {
const now = Math.floor(Date.now() / 1000); // Current Unix timestamp in seconds
const secondsAgo = now - unixTimestamp;
return secondsAgo;
}
+
+export function realTimeCountdown(secondsLeft: number): string {
+ let countdown = "";
+ const intervalId = setInterval(() => {
+ secondsLeft--;
+ const hours = Math.floor(secondsLeft / 3600);
+ const minutes = Math.floor((secondsLeft % 3600) / 60);
+ const seconds = secondsLeft % 60;
+ countdown = `${hours.toString().padStart(2, "0")}:${minutes
+ .toString()
+ .padStart(2, "0")}:${seconds.toString().padStart(2, "0")}`;
+ if (secondsLeft <= 0) {
+ clearInterval(intervalId);
+ }
+ }, 1000);
+ return countdown;
+}
diff --git a/utils/imageUtils.js b/utils/imageUtils.ts
index 8025d5b..6220134 100644
--- a/utils/imageUtils.js
+++ b/utils/imageUtils.ts
@@ -1,4 +1,4 @@
-export function getHeaders(providerId) {
+export function getHeaders(providerId: string) {
switch (providerId) {
case "mangahere":
return { Referer: "https://mangahere.org" };
@@ -21,12 +21,14 @@ export function getRandomId() {
return Math.random().toString(36).substr(2, 9);
}
-export function truncateImgUrl(url) {
+export function truncateImgUrl(url: string | undefined) {
+ if (!url) return null;
+
// Find the index of .png if not found find the index of .jpg
let index =
url?.indexOf(".png") !== -1 ? url?.indexOf(".png") : url?.indexOf(".jpg");
- if (index !== -1) {
+ if (index && index !== -1) {
// If .png or .jpg is found
url = url?.slice(0, index + 4); // Slice the string from the start to the index of .png or .jpg plus 4 (the length of .png or .jpg)
} else {
@@ -36,3 +38,18 @@ export function truncateImgUrl(url) {
return url;
}
+
+export function parseImageProxy(
+ url: string | undefined | null,
+ providerId: string | undefined
+) {
+ if (!url) return;
+
+ return providerId
+ ? `https://aoi.moopa.live/utils/image-proxy?url=${truncateImgUrl(
+ url
+ )}${`&headers=${encodeURIComponent(
+ JSON.stringify({ Referer: providerId })
+ )}`}`
+ : url;
+}
diff --git a/utils/parseMetaData.ts b/utils/parseMetaData.ts
new file mode 100644
index 0000000..597c21c
--- /dev/null
+++ b/utils/parseMetaData.ts
@@ -0,0 +1,36 @@
+type Episode = {
+ id: string;
+ description: string | null;
+ hasDub: boolean;
+ img: string | null;
+ isFiller: boolean;
+ number: number;
+ rating: number | null;
+ title: string;
+ updatedAt: number;
+};
+
+type Provider = {
+ providerId: string;
+ data: Episode[];
+};
+
+export function getProviderWithMostEpisodesAndImage(
+ data: Provider[]
+): Provider | null {
+ let maxEpisodesProvider: Provider | null = null;
+
+ for (const provider of data) {
+ if (
+ !maxEpisodesProvider ||
+ provider.data.length > maxEpisodesProvider.data.length
+ ) {
+ const hasImage = provider.data.some((episode) => episode.img !== null);
+ if (hasImage) {
+ maxEpisodesProvider = provider;
+ }
+ }
+ }
+
+ return maxEpisodesProvider;
+}
diff --git a/utils/request/index.ts b/utils/request/index.ts
new file mode 100644
index 0000000..854ef2b
--- /dev/null
+++ b/utils/request/index.ts
@@ -0,0 +1,111 @@
+import axios, { AxiosRequestConfig } from "axios";
+import { getSession } from "next-auth/react";
+import { toast } from "sonner";
+
+function isAnilist(url: string | undefined): boolean {
+ return url?.includes("anilist.co") ?? false;
+}
+
+interface RequestOption extends RequestInit {
+ headers?: {
+ "Content-Type"?: string;
+ Authorization?: string;
+ };
+}
+
+const pls = {
+ // GET request handler
+ async get(
+ url: string,
+ options?: AxiosRequestConfig,
+ ctx?: any
+ ): Promise<any> {
+ try {
+ const session: any | null = isAnilist(url) ? await getSession(ctx) : null;
+ const controller = new AbortController();
+ const signal = controller.signal;
+
+ const response = await axios.get(url, { ...options, signal });
+ return response.data;
+ } catch (error: any) {
+ handleError(error);
+ // throw error;
+ }
+ },
+
+ // POST request handler
+ async post(url: string, options: RequestOption, ctx?: any): Promise<any> {
+ try {
+ const session: any | null = await getSession(ctx);
+ const accessToken: string | undefined = session?.user?.token;
+
+ const controller = new AbortController();
+ const signal = controller.signal;
+
+ const response = await fetch(url, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ ...(accessToken &&
+ isAnilist(url) && { Authorization: `Bearer ${accessToken}` }),
+ },
+ ...options,
+ signal,
+ });
+
+ const data = await response.json();
+ return [data, session];
+ } catch (error: any) {
+ handleError(error);
+ // throw error;
+ }
+ },
+};
+
+function handleError(error: {
+ response: { status: any; data: any };
+ message: any;
+}) {
+ console.log(error);
+ if (error.response) {
+ const { status, data } = error.response;
+ switch (status) {
+ case 400:
+ toast.error("400 Bad request", {
+ description: data?.message || error.message,
+ });
+ break;
+ case 401:
+ toast.error("401 Unauthorized", {
+ description: data?.message || error.message,
+ });
+ break;
+ case 403:
+ toast.error("403 Forbidden", {
+ description: data?.message || error.message,
+ });
+ break;
+ case 404:
+ toast.error(`Resource not found - 404`, {
+ description: data?.message || error.message,
+ });
+ break;
+ case 500:
+ toast.error("500 Internal server error", {
+ description: data?.message || error.message,
+ });
+ break;
+ default:
+ toast.error("An error occurred", {
+ description: data?.message || error.message,
+ });
+ break;
+ }
+
+ if (data && data.message) {
+ console.error("Error message:", data.message);
+ }
+ }
+}
+
+export default pls;
diff --git a/utils/schedulesUtils.js b/utils/schedulesUtils.ts
index cb8c474..606e3fa 100644
--- a/utils/schedulesUtils.js
+++ b/utils/schedulesUtils.ts
@@ -1,6 +1,20 @@
-// Function to transform the schedule data into the desired format
-export const transformSchedule = (schedule) => {
- const formattedSchedule = {};
+interface ScheduleItem {
+ airingAt: string;
+ // Add other properties of ScheduleItem if available
+}
+
+interface Schedule {
+ [day: string]: ScheduleItem[];
+}
+
+interface FormattedSchedule {
+ [day: string]: {
+ [time: string]: ScheduleItem[];
+ };
+}
+
+export const transformSchedule = (schedule: Schedule): FormattedSchedule => {
+ const formattedSchedule: FormattedSchedule = {};
for (const day of Object.keys(schedule)) {
formattedSchedule[day] = {};
@@ -19,8 +33,10 @@ export const transformSchedule = (schedule) => {
return formattedSchedule;
};
-export const sortScheduleByDay = (schedule) => {
- const daysOfWeek = [
+export const sortScheduleByDay = (
+ schedule: FormattedSchedule
+): FormattedSchedule => {
+ const daysOfWeek: string[] = [
"Saturday",
"Sunday",
"Monday",
@@ -30,17 +46,14 @@ export const sortScheduleByDay = (schedule) => {
"Friday",
];
- // Get the current day of the week (0 = Sunday, 1 = Monday, ...)
- const currentDay = new Date().getDay();
+ const currentDay: number = new Date().getDay();
- // Reorder days of the week to start with today
- const orderedDays = [
+ const orderedDays: string[] = [
...daysOfWeek.slice(currentDay),
...daysOfWeek.slice(0, currentDay),
];
- // Create a new object with sorted days
- const sortedSchedule = {};
+ const sortedSchedule: FormattedSchedule = {};
orderedDays.forEach((day) => {
if (schedule[day]) {
sortedSchedule[day] = schedule[day];
@@ -50,34 +63,34 @@ export const sortScheduleByDay = (schedule) => {
return sortedSchedule;
};
-export const filterScheduleByDay = (sortedSchedule, filterDay) => {
+export const filterScheduleByDay = (
+ sortedSchedule: FormattedSchedule,
+ filterDay: string
+): FormattedSchedule => {
if (filterDay === "All") return sortedSchedule;
- // Create a new object to store the filtered schedules
- const filteredSchedule = {};
- // Iterate through the keys (days) in sortedSchedule
+ const filteredSchedule: FormattedSchedule = {};
+
for (const day in sortedSchedule) {
- // Check if the current day matches the filterDay
if (day === filterDay) {
- // If it matches, add the schedules for that day to the filteredSchedule object
filteredSchedule[day] = sortedSchedule[day];
}
}
- // Return the filtered schedule
return filteredSchedule;
};
-export const filterFormattedSchedule = (formattedSchedule, filterDay) => {
+export const filterFormattedSchedule = (
+ formattedSchedule: FormattedSchedule,
+ filterDay: string
+): FormattedSchedule => {
if (filterDay === "All") return formattedSchedule;
- // Check if the selected day exists in the formattedSchedule
if (formattedSchedule.hasOwnProperty(filterDay)) {
return {
[filterDay]: formattedSchedule[filterDay],
};
}
- // If the selected day does not exist, return an empty object
return {};
};
diff --git a/utils/useCountdownSeconds.js b/utils/useCountdownSeconds.js
deleted file mode 100644
index df3cb63..0000000
--- a/utils/useCountdownSeconds.js
+++ /dev/null
@@ -1,37 +0,0 @@
-import { useEffect, useState } from "react";
-
-const useCountdown = (targetDate, update) => {
- const countDownDate = new Date(targetDate).getTime();
-
- const [countDown, setCountDown] = useState(
- countDownDate - new Date().getTime()
- );
-
- useEffect(() => {
- const interval = setInterval(() => {
- const newCountDown = countDownDate - new Date().getTime();
- setCountDown(newCountDown);
- if (newCountDown <= 0 && newCountDown > -1000) {
- update();
- }
- }, 1000);
-
- return () => clearInterval(interval);
- }, [countDownDate, update]);
-
- return getReturnValues(countDown);
-};
-
-const getReturnValues = (countDown) => {
- // calculate time left
- const days = Math.floor(countDown / (1000 * 60 * 60 * 24));
- const hours = Math.floor(
- (countDown % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)
- );
- const minutes = Math.floor((countDown % (1000 * 60 * 60)) / (1000 * 60));
- const seconds = Math.floor((countDown % (1000 * 60)) / 1000);
-
- return [days, hours, minutes, seconds];
-};
-
-export { useCountdown };