starshard/peafowl
Template
1
Fork 0
mirror of https://github.com/starshardstudio/peafowl.git synced 2024-11-24 05:54:19 +00:00

Add anime identifiers

This commit is contained in:
Steffo 2024-11-21 06:37:11 +01:00
parent 21ff234466
commit f5dc4778f9
Signed by: steffo
GPG key ID: 5ADA3868646C3FC0
6 changed files with 212 additions and 27 deletions

105
_cms.ts
View file

@ -181,7 +181,7 @@ cms.collection(
name: "identifiers", name: "identifiers",
type: "choose-list", type: "choose-list",
label: "Identifiers", label: "Identifiers",
description: "Details that unequivocabily and globally identify the game. Shouldn't be edited manually.", description: "Details that unequivocabily and globally identify the game. Edit manually at your own risk.",
fields: [ fields: [
{ {
name: "steam", name: "steam",
@ -193,22 +193,30 @@ cms.collection(
name: "appid", name: "appid",
type: "text", type: "text",
label: "AppID", label: "AppID",
description: "The AppID that the game has on Steam. Usually ends with a 0. Can be obtained from the store page link, after the /app/ segment.", description: "The AppID that the game has on Steam. Usually ends with a 0. Can be obtained from the store page link after the /app/ segment.",
},
{
name: "name",
type: "text",
label: "Name",
description: "The title of the game, as it appears on Steam."
}, },
{ {
name: "synced_on", name: "synced_on",
type: "date", type: "date",
label: "Last sync", label: "Last sync",
description: "The date of the last sync." description: "The date of the last sync via `deno task import-steam`."
} }
] ]
} },
{
name: "wikidata",
type: "object",
label: "Wikidata",
description: "The game, stored as a Wikidata item.",
fields: [
{
name: "q",
type: "number",
label: "Wikidata identifier",
description: "The ID that the item has on Wikidata. The number following the `Q`.",
},
]
},
] ]
}, },
{ {
@ -316,15 +324,84 @@ cms.collection(
label: "Mastered on", label: "Mastered on",
description: "The date on which you've achieved mastery of the anime.", description: "The date on which you've achieved mastery of the anime.",
}, },
/*
{ {
name: "identifiers", name: "identifiers",
type: "choose-list", type: "choose-list",
label: "Identifiers", label: "Identifiers",
description: "Details that unequivocabily and globally identify the anime. Shouldn't be edited manually.", description: "Details that unequivocabily and globally identify the anime. Edit manually at your own risk.",
fields: [] fields: [
{
name: "mal",
type: "object",
label: "MyAnimeList",
description: "The anime, as it is stored on MyAnimeList.",
fields: [
{
name: "id",
type: "text",
label: "MAL ID",
description: "The anime ID that the anime has on MyAnimeList. Can be obtained from the anime page link after the `/anime/` segment.",
},
]
},
{
name: "anidb",
type: "object",
label: "AniDB",
description: "The anime, as it is stored on AniDB.",
fields: [
{
name: "aid",
type: "text",
label: "AID",
description: "The anime ID that the anime has on AniDB. Can be obtained from the anime page link, after the `/anime/` segment, or from the `aid` query parameter.",
},
]
},
{
name: "annid",
type: "object",
label: "Anime News Network",
description: "The anime, as it is stored on Anime News Network.",
fields: [
{
name: "id",
type: "text",
label: "ANN ID",
description: "The anime ID that the anime has on AniDB. Can be obtained from the anime page link from the `id` query parameter.",
},
]
},
{
name: "anilist",
type: "object",
label: "Anilist",
description: "The anime, as it is stored on Anilist.",
fields: [
{
name: "id",
type: "text",
label: "Anilist ID",
description: "The anime ID that the anime has on Anilist. Can be obtained from the anime page link after the `/anime/` segment.",
},
]
},
{
name: "wikidata",
type: "object",
label: "Wikidata",
description: "The anime, stored as a Wikidata item.",
fields: [
{
name: "q",
type: "text",
label: "Wikidata identifier",
description: "The ID that the item has on Wikidata. The number following the `Q`.",
},
]
},
]
}, },
*/
{ {
name: "content", name: "content",
type: "markdown", type: "markdown",

View file

@ -1,5 +1,5 @@
import {formatDateIso} from "../_utils/date.ts" import {formatDateIso} from "../_utils/date.ts"
import {AnimeData, AnimeProgress, animeProgressToClassName, animeProgressToIconDef, animeProgressToTitle} from "../_utils/anime.ts" import {AnimeData, AnimeIdentifier, AnimeProgress, animeProgressToClassName, animeProgressToIconDef, animeProgressToTitle} from "../_utils/anime.ts"
import {ReviewInfo} from "../_components/ReviewInfo.tsx" import {ReviewInfo} from "../_components/ReviewInfo.tsx"
@ -102,6 +102,73 @@ export default function(data: AnimeData, helpers: Lume.Helpers) {
</ReviewInfo.MetadataRow> </ReviewInfo.MetadataRow>
) : null ) : null
const milestonesSeparator = ((data.identifiers?.length ?? 0) > 0) ? <hr/> : null
const identifiersRows = data.identifiers?.map((identifier: AnimeIdentifier, index: number) => {
switch(identifier.type) {
case "wikidata":
return (
<ReviewInfo.MetadataRow
key={index}
className={`review-identifier-wikidata`}
label={<span><i className={`fa-sharp fa-regular fa-barcode`}/>&nbsp;Wikidata</span>}
>
<a href={`https://www.wikidata.org/wiki/Q${identifier.q}`}>
Q{identifier.q}
</a>
</ReviewInfo.MetadataRow>
)
case "anidb":
return (
<ReviewInfo.MetadataRow
key={index}
className={`anime-identifier-anidb`}
label={<span><i className={`fa-sharp fa-regular fa-database`}/>&nbsp;AniDB</span>}
>
<a href={`https://anidb.net/anime/${identifier.aid}`}>
{identifier.aid}
</a>
</ReviewInfo.MetadataRow>
)
case "mal":
return (
<ReviewInfo.MetadataRow
key={index}
className={`anime-identifier-mal`}
label={<span><i className={`fa-sharp fa-regular fa-list-check`}/>&nbsp;MyAnimeList</span>}
>
<a href={`https://myanimelist.net/anime/${identifier.id}`}>
{identifier.id}
</a>
</ReviewInfo.MetadataRow>
)
case "ann":
return (
<ReviewInfo.MetadataRow
key={index}
className={`anime-identifier-ann`}
label={<span><i className={`fa-sharp fa-regular fa-circles-overlap`}/>&nbsp;Anime News Network</span>}
>
<a href={`https://www.animenewsnetwork.com/encyclopedia/anime.php?id=${identifier.id}`}>
{identifier.id}
</a>
</ReviewInfo.MetadataRow>
)
case "anilist":
return (
<ReviewInfo.MetadataRow
key={index}
className={`anime-identifier-anilist`}
label={<span><i className={`fa-sharp fa-regular fa-circles-overlap`}/>&nbsp;Anilist</span>}
>
<a href={`https://anilist.co/anime/${identifier.id}/`}>
{identifier.id}
</a>
</ReviewInfo.MetadataRow>
)
}
})
return ( return (
<main id={"anime-main"}> <main id={"anime-main"}>
<ReviewInfo <ReviewInfo
@ -118,6 +185,8 @@ export default function(data: AnimeData, helpers: Lume.Helpers) {
{startedOnRow} {startedOnRow}
{completedOnRow} {completedOnRow}
{masteredOnRow} {masteredOnRow}
{milestonesSeparator}
{identifiersRows}
</>} </>}
> >
{data.children} {data.children}

View file

@ -119,6 +119,18 @@ export default function(data: GameData, helpers: Lume.Helpers) {
const identifiersRows = data.identifiers?.map((identifier: GameIdentifier, index: number) => { const identifiersRows = data.identifiers?.map((identifier: GameIdentifier, index: number) => {
switch(identifier.type) { switch(identifier.type) {
case "wikidata":
return (
<ReviewInfo.MetadataRow
key={index}
className={`review-identifier-wikidata`}
label={<span><i className={`fa-sharp fa-regular fa-barcode`}/>&nbsp;Wikidata</span>}
>
<a href={`https://www.wikidata.org/wiki/Q${identifier.q}`}>
Q{identifier.q}
</a>
</ReviewInfo.MetadataRow>
)
case "steam": case "steam":
return ( return (
<ReviewInfo.MetadataRow <ReviewInfo.MetadataRow
@ -127,7 +139,7 @@ export default function(data: GameData, helpers: Lume.Helpers) {
label={<span><i className={`fa-brands fa-steam`}/>&nbsp;Steam</span>} label={<span><i className={`fa-brands fa-steam`}/>&nbsp;Steam</span>}
> >
<a href={`https://store.steampowered.com/app/${identifier.appid}/`}> <a href={`https://store.steampowered.com/app/${identifier.appid}/`}>
{identifier.name ?? identifier.appid} {identifier.appid}
</a> </a>
</ReviewInfo.MetadataRow> </ReviewInfo.MetadataRow>
) )

View file

@ -1,4 +1,26 @@
import { ReviewData } from "./review.ts"; import { ReviewData, ReviewIdentifier, ReviewWikidataIdentifier } from "./review.ts";
export interface AnimeAnidbIdentifier extends ReviewIdentifier {
type: "anidb";
aid: string;
}
export interface AnimeMalIdentifier extends ReviewIdentifier {
type: "mal";
id: string;
}
export interface AnimeAnnIdentifier extends ReviewIdentifier {
type: "ann";
id: string;
}
export interface AnimeAnilistIdentifier extends ReviewIdentifier {
type: "anilist";
id: string;
}
export type AnimeIdentifier = ReviewWikidataIdentifier | AnimeAnidbIdentifier | AnimeMalIdentifier | AnimeAnnIdentifier | AnimeAnilistIdentifier;
export interface AnimeData extends ReviewData { export interface AnimeData extends ReviewData {
name_original: string; name_original: string;

View file

@ -1,17 +1,12 @@
import { ReviewData } from "./review.ts"; import { ReviewData, ReviewIdentifier, ReviewWikidataIdentifier } from "./review.ts";
export interface GameBaseIdentifier { export interface GameSteamIdentifier extends ReviewIdentifier {
type: string; type: "steam";
appid: string;
synced_on?: string; synced_on?: string;
} }
export interface GameSteamIdentifier extends GameBaseIdentifier { export type GameIdentifier = ReviewWikidataIdentifier | GameSteamIdentifier;
type: "steam";
appid: string;
name?: string;
}
export type GameIdentifier = GameSteamIdentifier;
export interface GameData extends ReviewData { export interface GameData extends ReviewData {
active?: boolean; active?: boolean;

View file

@ -2,6 +2,16 @@ import {Rating} from "./rating.ts"
import {GlobalData} from "./site.ts" import {GlobalData} from "./site.ts"
export interface ReviewIdentifier {
type: string;
}
export interface ReviewWikidataIdentifier extends ReviewIdentifier {
type: "wikidata",
q: string,
}
export interface ReviewData extends GlobalData { export interface ReviewData extends GlobalData {
name?: string, name?: string,
name_sort?: string, name_sort?: string,