Skip to content

Commit

Permalink
Update: Use suspense and async atom
Browse files Browse the repository at this point in the history
  • Loading branch information
Hayao0819 committed Jun 15, 2024
1 parent 496d815 commit d1e2a0c
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 64 deletions.
68 changes: 34 additions & 34 deletions src/app/(hayao)/playground/niconico/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import { useMemo, useState } from "react";
import { Suspense, useMemo, useState } from "react";
import { Checkbox, Form, Input } from "react-daisyui";

import Link from "@/components/elements/Link";
Expand Down Expand Up @@ -34,45 +34,45 @@ export default function Niconico() {
const [search, setSearch] = useSearch();
const [musicOnly, setMusicOnly] = useState<boolean>(false);

const { info, error } = useVideoList();
const info = useVideoList();

const header = useMemo(() => <Header />, []);

if (error) return <CommonSpacer>{error.message}</CommonSpacer>;

return (
<CommonSpacer>
<div>
{header}
<Form className="my-10">
<Input value={search.join(" ")} onChange={(e) => setSearch(e.target.value)} className="w-full" />
<Form.Label title="音楽のみ" className="mx-auto w-fit child:mx-2">
<Checkbox checked={musicOnly} onChange={(e) => setMusicOnly(e.target.checked)} />
</Form.Label>
</Form>
</div>
<Suspense fallback={<>Loading...</>}>
<div>
{header}
<Form className="my-10">
<Input value={search.join(" ")} onChange={(e) => setSearch(e.target.value)} className="w-full" />
<Form.Label title="音楽のみ" className="mx-auto w-fit child:mx-2">
<Checkbox checked={musicOnly} onChange={(e) => setMusicOnly(e.target.checked)} />
</Form.Label>
</Form>
</div>

<ul className="grid grid-cols-2 gap-3">
{info &&
Array.from(info?.values())

<ul className="grid grid-cols-2 gap-3">
{info &&
Array.from(info?.values())
//.filter((v) => v.title.includes(search))
.filter((v) => search.every((s) => v.title.includes(s)))
.filter((v) => !musicOnly || v.cT === "music")
.map((v) => {
return (
<li key={v.id} className="">
<a
href={`https://www.nicovideo.jp/watch_tmp/${v.id}`}
target="_blank"
rel="noreferrer"
className="flex cursor-pointer"
>
<span className=" flex items-center p-3 align-middle">{v.title}</span>
</a>
</li>
);
})}
</ul>
.filter((v) => search.every((s) => v.title.includes(s)))
.filter((v) => !musicOnly || v.cT === "music")
.map((v) => {
return (
<li key={v.id} className="">
<a
href={`https://www.nicovideo.jp/watch_tmp/${v.id}`}
target="_blank"
rel="noreferrer"
className="flex cursor-pointer"
>
<span className=" flex items-center p-3 align-middle">{v.title}</span>
</a>
</li>
);
})}
</ul>
</Suspense>
</CommonSpacer>
);
}
49 changes: 19 additions & 30 deletions src/app/(hayao)/playground/niconico/video.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Dispatch, SetStateAction, useEffect, useState } from "react";
import { atom, useAtomValue } from "jotai";
import { Dispatch, SetStateAction, useState } from "react";

const apiUrl =
process.env.NODE_ENV === "development" ? "http://localhost:3000/api/niconico" : "https://nicorekari.nanasi-rasi.net/DB.json";
Expand All @@ -12,8 +13,6 @@ interface Video {
cT: string;
}

export type ClickList = { [key: string]: boolean };

export type VideoList = Map<string, Video>;

export const useSearch = (): [string[], Dispatch<SetStateAction<string>>] => {
Expand All @@ -22,30 +21,20 @@ export const useSearch = (): [string[], Dispatch<SetStateAction<string>>] => {
return [replaced, setSearch];
};

export const useVideoList = () => {
const [info, setInfo] = useState<VideoList | null>(null);
const [error, setError] = useState<Error | null>(null);

//const [catList, setCatList] = useState<string[]>([]);

useEffect(() => {
(async () => {
// fetch data
const res = await fetch(apiUrl);
if (!res.ok) {
setError(new Error(res.statusText));
throw new Error(res.statusText);
}
const json = await res.json();

// set videoList
const videoMap = new Map<string, Video>();
Object.keys(json).forEach((key) => {
videoMap.set(key, json[key]);
});
setInfo(videoMap);
})();
}, []);

return { info, error };
};
const videoListAtom = atom(async () => {
// fetch data
const res = await fetch(apiUrl);
if (!res.ok) {
throw new Error(res.statusText);
}
const json = await res.json();

// set videoList
const videoMap = new Map<string, Video>();
Object.keys(json).forEach((key) => {
videoMap.set(key, json[key]);
});
return videoMap;
});

export const useVideoList = () => useAtomValue(videoListAtom);

0 comments on commit d1e2a0c

Please sign in to comment.