summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/app/_components/archiveLinkElement.tsx84
-rw-r--r--src/app/anime/[animeId]/page.tsx18
-rw-r--r--src/app/article/_components/articleListElement.tsx12
-rw-r--r--src/app/layout.tsx2
4 files changed, 93 insertions, 23 deletions
diff --git a/src/app/_components/archiveLinkElement.tsx b/src/app/_components/archiveLinkElement.tsx
new file mode 100644
index 0000000..d97d904
--- /dev/null
+++ b/src/app/_components/archiveLinkElement.tsx
@@ -0,0 +1,84 @@
+import Link from "next/link";
+type ArticlePage = {
+ type: "article",
+ articleId: number,
+ subPageNumber?: number,
+}
+type AnimeTop = {
+ type: "animeTop",
+ animeId: number,
+};
+type AnimeReviewList = {
+ type: "animeReviewList",
+ animeId: number,
+ /** 0始まり */
+ pageNumber: number,
+};
+type AnimeReviewItem = {
+ type: "AnimeReviewItem",
+ animeId: number,
+ reviewId: number,
+};
+type Common = { showLinkUnderline?: boolean }
+type Option = (ArticlePage | AnimeTop | AnimeReviewList | AnimeReviewItem) & Common;
+export function ArciveLinkElement(option: Option) {
+ const officialLinkTitle = `公式のakiba-souken.com へのリンク。閉鎖後は繋がらなくなるはず`;
+ const iaSearchResultLinkTitle = `InternetArchive の検索結果へのリンク`;
+ const iframeLinkTitle = `Iframeを使ってInternetArchiveに記録されたアーカイブを表示します`;
+ let originalUrl = "";
+ let iframeSrc = "";
+ let suffixPrivate: JSX.Element = <></>;
+ let className = "";
+ if (option.type == "article") {
+ if (option.subPageNumber == null) {
+ originalUrl = `https://akiba-souken.com/article/${option.articleId}/`;
+ iframeSrc = `article-${option.articleId}`;
+ } else {
+ originalUrl = `https://akiba-souken.com/article/${option.articleId}/?page=${option.subPageNumber}`;
+ iframeSrc = `article-${option.articleId}-${option.subPageNumber}`;
+ suffixPrivate = <>Page:{option.subPageNumber}</>
+ }
+ } else if (option.type == "animeTop") {
+ originalUrl = `https://akiba-souken.com/anime/${option.animeId}/`;
+ iframeSrc = `anime-${option.animeId}`
+ } else if (option.type == "animeReviewList") {
+ if (option.pageNumber == 0) {
+ originalUrl = `https://akiba-souken.com/anime/${option.animeId}/review/`;
+ iframeSrc = `anime-${option.animeId}-review`
+ } else {
+ const page = option.pageNumber + 1;
+ originalUrl = `https://akiba-souken.com/anime/${option.animeId}/?page=${page}`;
+ iframeSrc = `anime-${option.animeId}-review-p${page}`
+ }
+ } else if (option.type == "AnimeReviewItem") {
+ originalUrl = `https://akiba-souken.com/anime/${option.animeId}/review/${option.reviewId}`;
+ iframeSrc = `anime-${option.animeId}-review-${option.reviewId}`;
+ } else {
+ throw new Error();
+ }
+ if (option.showLinkUnderline == true) {
+ className = `original-href`;
+ }
+ return (
+ <>
+ <a
+ href={originalUrl}
+ target="_blank"
+ className={`transition duration-300 ease-in-out hover:text-gray-900 ${className}`}
+ title={officialLinkTitle}
+ >公式</a>
+ <a
+ href={`https://web.archive.org/web/*/${originalUrl}`}
+ target="_blank"
+ className={`transition duration-300 ease-in-out hover:text-gray-900 ${className}`}
+ title={iaSearchResultLinkTitle}
+ >IA検索結果</a>
+ <Link
+ href={`/iframe?src=${iframeSrc}`}
+ className={`transition duration-300 ease-in-out hover:text-gray-900 ${className}`}
+ title={iframeLinkTitle}
+ >IAをiframe</Link>
+ {suffixPrivate}
+ </>
+ )
+} \ No newline at end of file
diff --git a/src/app/anime/[animeId]/page.tsx b/src/app/anime/[animeId]/page.tsx
index a92cda8..4c5372e 100644
--- a/src/app/anime/[animeId]/page.tsx
+++ b/src/app/anime/[animeId]/page.tsx
@@ -3,6 +3,7 @@ import style from "./style.module.css";
import dateformat from "dateformat";
import { AnimeLoader, AnimeLoaderData } from "../../../util/animeLoader";
import Link from "next/link";
+import { ArciveLinkElement } from "../../_components/archiveLinkElement";
dateformat.i18n.dayNames = [
'日', '月', '火', '水', '木', '金', '土',
'日曜日', '月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日'
@@ -43,9 +44,7 @@ export default async function Page(context: PageType) {
<div>
<span>アキバ総研のアニメ個別URL:</span>
<span className="inline-flex gap-4">
- <a href={`https://akiba-souken.com/anime/${loadedData.animeId}/`} target="_blank" className={`${style["a"]}`}>公式</a>
- <a href={`https://web.archive.org/web/*/https://akiba-souken.com/anime/${loadedData.animeId}/`} target="_blank" className={`${style["a"]}`}>IA検索結果</a>
- <Link href={`/iframe?src=anime-${loadedData.animeId}`} className={`${style["a"]}`}>IAをiframe</Link>
+ {ArciveLinkElement({ type: "animeTop", animeId: loadedData.animeId, showLinkUnderline: true })}
</span>
</div>
{titleReviewScore(loadedData.titleReviewScore)}
@@ -114,22 +113,17 @@ function titleReviewList(animeId: number, list: AnimeLoaderData["titleReviewList
<div key={`review-list-${i}`}>
<span>新着 {itemFrom}~{itemTo}件目</span>
<span className="inline-flex gap-4">
- <a href={`https://akiba-souken.com/anime/${animeId}/review/`} target="_blank" className={`${style["a"]}`}>公式</a>
- <a href={`https://web.archive.org/web/*/https://akiba-souken.com/anime/${animeId}/review/`} target="_blank" className={`${style["a"]}`}>IA検索結果</a>
- <Link href={`/iframe?src=anime-${animeId}-review`} className={`${style["a"]}`}>IAをiframe</Link>
+ {ArciveLinkElement({ type: "animeReviewList", animeId: animeId, pageNumber: i, showLinkUnderline: true })}
</span>
</div>
);
} else {
// 2ページ目移行
- const page = i + 1;
reviewListLinks.push(
<div key={`review-list-${i}`}>
<span>新着 {itemFrom}~{itemTo}件目</span>
<span className="inline-flex gap-4">
- <a href={`https://akiba-souken.com/anime/${animeId}/review/?page=${page}`} target="_blank" className={`${style["a"]}`}>公式</a>
- <a href={`https://web.archive.org/web/*/https://akiba-souken.com/anime/${animeId}/review/?page=${page}`} target="_blank" className={`${style["a"]}`}>IA検索結果</a>
- <Link href={`/iframe?src=anime-${animeId}-review-p${page}`} className={`${style["a"]}`}>IAをiframe</Link>
+ {ArciveLinkElement({ type: "animeReviewList", animeId: animeId, pageNumber: i, showLinkUnderline: true })}
</span>
</div>
);
@@ -146,9 +140,7 @@ function titleReviewList(animeId: number, list: AnimeLoaderData["titleReviewList
<div key={`review-list-${v.reviewId}`}>
<span className="inline-flex gap-4">
<span>{index + 1}/{list.length}</span>
- <a href={`https://akiba-souken.com/anime/${animeId}/review/${v.reviewId}/`} target="_blank" className={`${style["a"]}`}>公式</a>
- <a href={`https://web.archive.org/web/*/https://akiba-souken.com/anime/${animeId}/review/${v.reviewId}/`} target="_blank" className={`${style["a"]}`}>IA検索結果</a>
- <Link href={`/iframe?src=anime-${animeId}-review-${v.reviewId}`} className={`${style["a"]}`}>IAをiframe</Link>
+ {ArciveLinkElement({ type: "AnimeReviewItem", animeId: animeId, reviewId: v.reviewId, showLinkUnderline: true })}
<span>投稿日時:{timestampStr}</span>
<span>スコア:{v.score}</span>
<span>ネタバレ:{v.isSpoiler ? "はい" : "いいえ"}</span>
diff --git a/src/app/article/_components/articleListElement.tsx b/src/app/article/_components/articleListElement.tsx
index 27c7862..2c23f59 100644
--- a/src/app/article/_components/articleListElement.tsx
+++ b/src/app/article/_components/articleListElement.tsx
@@ -2,6 +2,7 @@ import Link from "next/link";
import dateformat from "dateformat";
import { ArticleLoader } from "../../../util/articleLoader";
import { TableElement } from "../../_components/tableElements";
+import { ArciveLinkElement } from "../../_components/archiveLinkElement";
dateformat.i18n.dayNames = [
'日', '月', '火', '水', '木', '金', '土',
'日曜日', '月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日'
@@ -22,9 +23,6 @@ export function ArticleListElement(displayData: DisplayData[], categoryTag: Cate
return result;
}
function getDisplayData(d: DisplayData, categoryTag: CategoryTagData) {
- const officialLinkTitle = `公式のakiba-souken.com へのリンク。閉鎖後は繋がらなくなるはず`;
- const iaSearchResultLinkTitle = `InternetArchive の検索結果へのリンク`;
- const iframeLinkTitle = `Iframeを使ってInternetArchiveに記録されたアーカイブを表示します`;
const topCategory = d.breadLinks[0];
const timestampStr = dateformat(new Date(d.timestampMs), "yyyy/mm/dd(ddd)HH:MM");
const originalUrl = `https://akiba-souken.com/article/${d.articleId}/`;
@@ -38,9 +36,7 @@ function getDisplayData(d: DisplayData, categoryTag: CategoryTagData) {
for (let page = 2; page <= d.maxPageNumber; page++) {
result.push(
<div className="flex gap-4 text-xs text-gray-300" key={`page-${page}`}>
- <a href={`https://akiba-souken.com/article/${d.articleId}/?page=${page}`} target="_blank" className="transition duration-300 ease-in-out hover:text-gray-900" title={officialLinkTitle}>公式</a>
- <a href={`https://web.archive.org/web/*/https://akiba-souken.com/article/${d.articleId}/?page=${page}`} target="_blank" className="transition duration-300 ease-in-out hover:text-gray-900" title={iaSearchResultLinkTitle}>IA検索結果</a>
- <Link href={`/iframe?src=article-${d.articleId}-${page}`} className="transition duration-300 ease-in-out hover:text-gray-900" title={iframeLinkTitle}>IAをiframe</Link> Page:{page}
+ {ArciveLinkElement({ type: "article", articleId: d.articleId, subPageNumber: page })}
</div>
);
}
@@ -106,9 +102,7 @@ function getDisplayData(d: DisplayData, categoryTag: CategoryTagData) {
element: <>
<div>{d.title}</div>
<div className="flex gap-4 text-xs text-gray-300">
- <a href={originalUrl} target="_blank" className="transition duration-300 ease-in-out hover:text-gray-900" title={officialLinkTitle}>公式</a>
- <a href={`https://web.archive.org/web/*/${originalUrl}`} target="_blank" className="transition duration-300 ease-in-out hover:text-gray-900" title={iaSearchResultLinkTitle}>IA検索結果</a>
- <Link href={`/iframe?src=article-${d.articleId}`} className="transition duration-300 ease-in-out hover:text-gray-900" title={iframeLinkTitle}>IAをiframe</Link>
+ {ArciveLinkElement({ type: "article", articleId: d.articleId })}
{breadElement}
{tagElement}
{hatebuElement}
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 9d5b2b9..aa0dad7 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -20,7 +20,7 @@ export default function RootLayout({
<NavigationHeader></NavigationHeader>
{children}
<div>
- 全てのデータは<a href="https://akiba-souken.com/" target="_blank">アキバ総研</a>より。
+ 全てのデータは<a href="https://akiba-souken.com/" target="_blank" className="original-href">アキバ総研</a>より。
</div>
</body>
</html>