import { USER_AGENT, ENDPOINTS } from "./config"; export const HEADERS = { "User-Agent": USER_AGENT, "Content-Type": "application/json; charset=UTF-8", }; type Success = { data: T; error: null; }; type Failure = { data: null; error: E; }; type Result = Success | Failure; export async function tryCatch( promise: Promise ): Promise> { try { const data = await promise; return { data, error: null }; } catch (error) { return { data: null, error: error as E }; } } export async function tryCatchPlayer( promise: Promise ): Promise> { try { const res: Awaited = await promise; const data = await res.json(); if (!res.ok) { if (data.message) { return { data: null, error: { message: data.message, code: res.status, }, }; } else if (data.detail) { return { data: null, error: { message: data.detail, code: res.status, }, }; } else { return { data: null, error: { message: res.statusText, code: res.status, }, }; } } return { data, error: null }; } catch (error) { return { data: null, error: error as E }; } } export async function tryCatchAPI( promise: Promise ): Promise> { try { const res: Awaited = await promise; // if (!res.ok) { // return { // data: null, // error: { // message: res.statusText, // code: res.status, // }, // }; // } if ( res.headers.get("content-length") && Number(res.headers.get("content-length")) == 0 ) { return { data: null, error: { message: "Not Found", code: 404, }, }; } const data: Awaited = await res.json(); if (data.code != 0) { return { data: null, error: { message: "API Returned an Error", code: data.code || 500, }, }; } return { data, error: null }; } catch (error) { return { data: null, error: error }; } } export const useSWRfetcher = async (url: string) => { const { data, error } = await tryCatchAPI(fetch(url)); if (error) { throw error; } return data; }; export const fetchDataViaGet = async ( url: string, API_V2: string | boolean = false, addHeaders?: Record ) => { if (API_V2) { HEADERS["API-Version"] = "v2"; } const { data, error } = await tryCatchAPI( fetch(url, { headers: { ...HEADERS, ...addHeaders }, }) ); return { data, error }; }; export const fetchDataViaPost = async ( url: string, body: string, API_V2: string | boolean = false, addHeaders?: Record ) => { if (API_V2) { HEADERS["API-Version"] = "v2"; } const { data, error } = await tryCatchAPI( fetch(url, { method: "POST", body: body, headers: { ...HEADERS, ...addHeaders }, }) ); return { data, error }; }; export function setJWT(user_id: number | string, jwt: string) { const data = { jwt: jwt, user_id: user_id }; localStorage.setItem("JWT", JSON.stringify(data)); } export function getJWT() { const data = localStorage.getItem("JWT"); return JSON.parse(data); } export function removeJWT() { localStorage.removeItem("JWT"); } export function numberDeclension( number: number, one: string, two: string, five: string ) { if (number > 10 && [11, 12, 13, 14].includes(number % 100)) return five; let last_num = number % 10; if (last_num == 1) return one; if ([2, 3, 4].includes(last_num)) return two; if ([5, 6, 7, 8, 9, 0].includes(last_num)) return five; } const months = [ "янв.", "фев.", "мар.", "апр.", "мая", "июня", "июля", "авг.", "сен.", "окт.", "ноя.", "дек.", ]; export function unixToDate( unix: number, type: "full" | "dayMonth" | "dayMonthYear" ) { const date = new Date(unix * 1000); if (type === "full") return ( date.getDate() + " " + months[date.getMonth()] + " " + date.getFullYear() + ", " + `${date.getHours()}`.padStart(2, "0") + ":" + `${date.getMinutes()}`.padStart(2, "0") ); if (type === "dayMonth") return date.getDate() + " " + months[date.getMonth()]; if (type === "dayMonthYear") return ( date.getDate() + " " + months[date.getMonth()] + " " + date.getFullYear() ); } export function sinceUnixDate(unixInSeconds: number) { const unix = Math.floor(unixInSeconds * 1000); const date = new Date(unix); const currentDate = new Date().valueOf(); const dateDifferenceSeconds = new Date(currentDate - unix).getTime() / 1000; const minutes = Math.floor(dateDifferenceSeconds / 60); const hours = Math.floor(dateDifferenceSeconds / 3600); const days = Math.floor(dateDifferenceSeconds / 86400); const minutesName = numberDeclension(minutes, "минута", "минуты", "минут"); const hoursName = numberDeclension(hours, "час", "часа", "часов"); const daysName = numberDeclension(days, "день", "дня", "дней"); if (dateDifferenceSeconds < 60) return "менее минуты назад"; if (dateDifferenceSeconds < 3600) return `${minutes} ${minutesName} назад`; if (dateDifferenceSeconds < 86400) return `${hours} ${hoursName} назад`; if (dateDifferenceSeconds < 2592000) return `${days} ${daysName} назад`; return ( date.getDate() + " " + months[date.getMonth()] + " " + date.getFullYear() ); } export function minutesToTime(min: number) { const seconds = min * 60; const epoch = new Date(0); const date = new Date(seconds * 1000); const diffInMinutes = new Date(date.getTime() - epoch.getTime()).getTime() / 1000 / 60; let days = Math.floor(diffInMinutes / 1440); if (days < 0) days = 0; const daysToMinutes = days * 1440; let hours = Math.floor((diffInMinutes - daysToMinutes) / 60); if (hours < 0) hours = 0; const hoursToMinutes = hours * 60; let minutes = diffInMinutes - daysToMinutes - hoursToMinutes; if (minutes < 0) minutes = 0; const dayDisplay = days > 0 ? `${days} ${numberDeclension(days, "день", "дня", "дней")}` : ""; const hourDisplay = hours > 0 ? `${hours} ${numberDeclension(hours, "час", "часа", "часов")}` : ""; const minuteDisplay = minutes > 0 ? `${minutes} ${numberDeclension(minutes, "минута", "минуты", "минут")}` : ""; if (days > 0 && hours > 0 && minutes > 0) return `${dayDisplay}, ${hourDisplay}, ${minuteDisplay}`; if (days > 0 && hours > 0) return `${dayDisplay}, ${hourDisplay}`; if (days > 0 && minutes > 0) return `${dayDisplay}, ${minuteDisplay}`; if (hours > 0 && minutes > 0) return `${hourDisplay}, ${minuteDisplay}`; if (days > 0) return dayDisplay; if (hours > 0) return hourDisplay; if (minutes > 0) return minuteDisplay; } const StatusList: Record = { last: null, finished: 1, ongoing: 2, announce: 3, }; export async function _FetchHomePageReleases( status: string, token: string | null, page: string | number = 0 ) { let statusId: null | number = null; let categoryId: null | number = null; if (status == "films") { categoryId = 2; } else { statusId = StatusList[status]; } const body = { country: null, season: null, sort: 0, studio: null, age_ratings: [], category_id: categoryId, end_year: null, episode_duration_from: null, episode_duration_to: null, episodes_from: null, episodes_to: null, genres: [], profile_list_exclusions: [], start_year: null, status_id: statusId, types: [], is_genres_exclude_mode_enabled: false, }; let url: string; url = `${ENDPOINTS.filter}/${page}`; if (token) { url += `?token=${token}`; } const data: Object = fetch(url, { method: "POST", headers: HEADERS, body: JSON.stringify(body), }) .then((response) => { if (response.ok) { return response.json(); } else { throw new Error("Error fetching data"); } }) .then((data: Object) => { return data; }) .catch((error) => { console.log(error); return null; }); return data; } export const BookmarksList = { watching: 1, planned: 2, watched: 3, delayed: 4, abandoned: 5, }; export const SortList = { adding_descending: 1, adding_ascending: 2, year_descending: 3, year_ascending: 4, alphabet_descending: 5, alphabet_ascending: 6, }; export function b64toBlob( b64Data: string, contentType: string, sliceSize?: number ) { contentType = contentType || ""; sliceSize = sliceSize || 512; var byteCharacters = atob(b64Data); var byteArrays = []; for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) { var slice = byteCharacters.slice(offset, offset + sliceSize); var byteNumbers = new Array(slice.length); for (var i = 0; i < slice.length; i++) { byteNumbers[i] = slice.charCodeAt(i); } var byteArray = new Uint8Array(byteNumbers); byteArrays.push(byteArray); } var blob = new Blob(byteArrays, { type: contentType }); return blob; }