diff --git a/src/App.js b/src/App.js
index b9b4111..8e7e277 100644
--- a/src/App.js
+++ b/src/App.js
@@ -2,7 +2,7 @@ import React from 'react';
import { Link } from 'react-router-dom';
const NameList = () => {
- const names = ['TicTacToe','TodoList','FoodOrderer'];
+ const names = ['TicTacToe','TodoList','FoodOrderer','RandomAnimeGirl'];
return (
diff --git a/src/RandomAnimeGirl.tsx b/src/RandomAnimeGirl.tsx
new file mode 100644
index 0000000..60403fb
--- /dev/null
+++ b/src/RandomAnimeGirl.tsx
@@ -0,0 +1,168 @@
+import React, { useState } from "react";
+import { blob } from "stream/consumers";
+import { Url } from "url";
+
+interface ApiResponse {
+ success: boolean;
+ status: number;
+ key?: string;
+ count?: number;
+ id?: string;
+ colors?: {
+ main: string;
+ palette: string[];
+ };
+ image?: {
+ original: {
+ url: string;
+ extension: string;
+ };
+ compressed: {
+ url: string;
+ extension: string;
+ };
+ };
+ metadata?: {
+ original: {
+ width: number;
+ height: number;
+ size: number;
+ extension: string;
+ };
+ compressed: {
+ width: number;
+ height: number;
+ size: number;
+ extension: string;
+ };
+ };
+ category?: string;
+ tags?: string[];
+ rating?: "safe" | "questionable";
+ anime?: {
+ title: string | null;
+ character: string | null;
+ };
+ source?: {
+ url: string | null;
+ direct: string | null;
+ };
+ attribution?: {
+ artist: {
+ username: string | null;
+ profile: string | null;
+ };
+ copyright: string | null;
+ };
+}
+
+
+
+class Api {
+ constructor() { }
+ static validEndpoints: string[] = ['catgirl', 'foxgirl', 'wolf-girl', 'animal-ears', 'tail', 'tail-with-ribbon', 'cuteness-is-justice', 'blue-archive', 'girl', 'young-girl', 'maid', 'maid-uniform', 'vtuber', 'w-sitting', 'lying-down', 'hands-forming-a-heart', 'wink', 'valentine', 'headphonesthigh-high-socks', 'knee-high-socks', 'white-tights', 'black-tights', 'heterochromia', 'uniform', 'sailor-uniform', 'hoodie', 'ribbon', 'white-hair', 'blue-hair', 'long-hair', 'blonde', 'blue-eyes', 'purple-eyes']
+ static baseUrl: string = "https://api.nekosia.cat/api/v1/images/"
+
+ async getFromEndpoint(endpoint: string): Promise
{
+ if (endpoint! in Api.validEndpoints) {
+ return { success: false, status: -1 }
+ }
+
+ try {
+ const response = await fetch(Api.baseUrl + endpoint)
+ if (!response.ok) {
+ throw new Error(`HTTP error! Status: ${response.status}`)
+ }
+
+ const data: ApiResponse = await response.json()
+ return data
+ } catch (error) {
+ console.error("Error fetching API:", error);
+ throw error; // Re-throw the error for caller to handle
+ }
+
+ }
+}
+
+async function getImage(data: ApiResponse): Promise {
+ if (data.source == undefined || data.source.direct == null) {
+ return null
+ }
+ const url = data.source.direct.replace('i.pximg.net', 'p.lolicon.cyou')
+ let result: Blob | null = null
+
+ const response = await fetch(url, { method: "GET" })
+
+ if (response.status != 200) {
+ if (response.status == 404 && data.image != undefined) { // 尝试使用备用的
+ const backup = await fetch(data.image.original.url, { method: "GET" })
+ if (backup.status == 200) {
+ result = await backup.blob()
+ }
+ }
+ } else {
+ result = await response.blob()
+ }
+
+ return result // null 就是获取失败了
+}
+
+function getImageUrl(data: ApiResponse): string | null {
+ if (data.source == undefined || data.source.direct == null) {
+ return null
+ }
+ const url = data.source.direct.replace('i.pximg.net', 'p.lolicon.cyou')
+ return url
+}
+
+
+function handleGetImage(type: string | null, setter: React.Dispatch>) {
+ let endpoint = `${type}`
+ if (type === null) {
+ const randomIndex = Math.floor(Math.random() * Api.validEndpoints.length);
+ endpoint = Api.validEndpoints[randomIndex]
+ }
+ let api = new Api();
+
+ (async () => {
+ try {
+ const result = await api.getFromEndpoint(endpoint)
+ const image = null
+ // const image = await getImage(result)
+ if (image != null) {
+ setter(URL.createObjectURL(image));
+ } else {
+ const imageUrl = getImageUrl(result)
+ if (imageUrl != null) {
+ setter(imageUrl)
+ }
+ }
+ } catch (error) {
+ throw error
+ }
+ })();
+}
+
+
+const RandomAnimeGirl = () => {
+ const [imageSrc, setImageSrc] = useState("https://p.lolicon.cyou/img-original/img/2023/09/06/19/20/27/111496024_p0.png")
+ return (
+
+
Random Image Viewer
+
+
+
+ )
+}
+
+export default RandomAnimeGirl
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index f6111e7..38fcba2 100644
--- a/src/index.js
+++ b/src/index.js
@@ -7,6 +7,7 @@ import TodoList from "./TodoList";
import NameList from "./App";
import FoodOrderer from "./FoodOrderer";
import { BrowserRouter, Routes, Route } from "react-router-dom";
+import RandomAnimeGirl from "./RandomAnimeGirl";
const root = createRoot(document.getElementById("root"));
root.render(
@@ -22,6 +23,7 @@ root.render(
} />
} />
} />
+ } />