diff --git a/.gitignore b/.gitignore
index 88b6f0d..027613e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,7 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+/testing_logs/*
+
# dependencies
/node_modules
/.pnp
@@ -35,3 +37,5 @@ yarn-error.log*
# typescript
*.tsbuildinfo
+
+!.gitkeep
diff --git a/package-lock.json b/package-lock.json
index 69604da..5628ae9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4,6 +4,7 @@
"requires": true,
"packages": {
"": {
+ "name": "accords-library.com",
"dependencies": {
"@fontsource/material-icons": "^4.5.2",
"@fontsource/material-icons-rounded": "^4.5.2",
@@ -21,6 +22,7 @@
"@tailwindcss/typography": "^0.5.2",
"@types/node": "17.0.18",
"@types/react": "17.0.39",
+ "@types/react-dom": "^17.0.11",
"eslint": "8.9.0",
"eslint-config-next": "12.1.0",
"tailwindcss": "^3.0.23",
@@ -496,6 +498,15 @@
"csstype": "^3.0.2"
}
},
+ "node_modules/@types/react-dom": {
+ "version": "17.0.11",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.11.tgz",
+ "integrity": "sha512-f96K3k+24RaLGVu/Y2Ng3e1EbZ8/cVJvypZWd7cy0ofCBaf2lcM46xNhycMZ2xGwbBjRql7hOlZ+e2WlJ5MH3Q==",
+ "dev": true,
+ "dependencies": {
+ "@types/react": "*"
+ }
+ },
"node_modules/@types/scheduler": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
@@ -976,7 +987,6 @@
"dependencies": {
"anymatch": "~3.1.2",
"braces": "~3.0.2",
- "fsevents": "~2.3.2",
"glob-parent": "~5.1.2",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
@@ -2510,17 +2520,6 @@
"integrity": "sha512-s885kWvnIlxsUFHq9UGyIyLiuD0G3BUC/xrH0CEnH5lHEWkwQcHOORgbDF0hbrW9vr/7am4ETfX4A7M6DjrE7Q==",
"dependencies": {
"@next/env": "12.1.0",
- "@next/swc-android-arm64": "12.1.0",
- "@next/swc-darwin-arm64": "12.1.0",
- "@next/swc-darwin-x64": "12.1.0",
- "@next/swc-linux-arm-gnueabihf": "12.1.0",
- "@next/swc-linux-arm64-gnu": "12.1.0",
- "@next/swc-linux-arm64-musl": "12.1.0",
- "@next/swc-linux-x64-gnu": "12.1.0",
- "@next/swc-linux-x64-musl": "12.1.0",
- "@next/swc-win32-arm64-msvc": "12.1.0",
- "@next/swc-win32-ia32-msvc": "12.1.0",
- "@next/swc-win32-x64-msvc": "12.1.0",
"caniuse-lite": "^1.0.30001283",
"postcss": "8.4.5",
"styled-jsx": "5.0.0",
@@ -3986,6 +3985,15 @@
"csstype": "^3.0.2"
}
},
+ "@types/react-dom": {
+ "version": "17.0.11",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.11.tgz",
+ "integrity": "sha512-f96K3k+24RaLGVu/Y2Ng3e1EbZ8/cVJvypZWd7cy0ofCBaf2lcM46xNhycMZ2xGwbBjRql7hOlZ+e2WlJ5MH3Q==",
+ "dev": true,
+ "requires": {
+ "@types/react": "*"
+ }
+ },
"@types/scheduler": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
diff --git a/package.json b/package.json
index f295064..5044c59 100644
--- a/package.json
+++ b/package.json
@@ -5,8 +5,7 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
- "lint": "next lint",
- "text": "NODE_ENV=test next build"
+ "lint": "next lint"
},
"dependencies": {
"@fontsource/material-icons": "^4.5.2",
@@ -25,6 +24,7 @@
"@tailwindcss/typography": "^0.5.2",
"@types/node": "17.0.18",
"@types/react": "17.0.39",
+ "@types/react-dom": "^17.0.11",
"eslint": "8.9.0",
"eslint-config-next": "12.1.0",
"tailwindcss": "^3.0.23",
diff --git a/public/site.webmanifest b/public/site.webmanifest
index 4308fbd..6828582 100644
--- a/public/site.webmanifest
+++ b/public/site.webmanifest
@@ -1,11 +1,10 @@
{
- "name": "Accord's Library",
- "short_name": "Accord's Lib",
- "start_url": ".",
- "display": "standalone",
"background_color": "#FFEDD8",
- "theme_color": "#FFEDD8",
+ "categories": ["books", "education", "entertainment", "news", "games"],
"description": "Accord's Library aims at gathering and archiving all of Yoko Taro’s work. Yoko Taro is a Japanese video game director and scenario writer.",
+ "dir": "auto",
+ "display": "fullscreen",
+
"icons": [
{
"src": "/android-chrome-192x192.png",
@@ -17,5 +16,44 @@
"sizes": "512x512",
"type": "image/png"
}
- ]
+ ],
+
+ "name": "Accord's Library",
+ "short_name": "Accord's Lib",
+ "start_url": ".",
+
+ "shortcuts": [
+ {
+ "name": "Library",
+ "url": "/library",
+ "description": "Browse all physical and digital media"
+ },
+ {
+ "name": "Contents",
+ "url": "/contents",
+ "description": "Explore all content and filter by type or category"
+ },
+ {
+ "name": "Wiki",
+ "url": "/wiki",
+ "description": "An encyclopedia for everything related to DrakeNieR"
+ },
+ {
+ "name": "Chronicles",
+ "url": "/chronicles",
+ "description": "Experience all events and content in chronological order"
+ },
+ {
+ "name": "News",
+ "url": "/news",
+ "description": "All the latest info"
+ },
+ {
+ "name": "Gallery",
+ "url": "/gallery",
+ "description": "Thousands of offcial artworks"
+ }
+ ],
+
+ "theme_color": "#FFEDD8"
}
diff --git a/run_accords_build.sh b/run_accords_build.sh
index 2e23821..e63f0de 100755
--- a/run_accords_build.sh
+++ b/run_accords_build.sh
@@ -1 +1 @@
-npx next build
+npx next build
\ No newline at end of file
diff --git a/run_accords_testing.sh b/run_accords_testing.sh
new file mode 100755
index 0000000..0ea2be6
--- /dev/null
+++ b/run_accords_testing.sh
@@ -0,0 +1,2 @@
+NODE_ENV=test
+npx next build |& tee ./testing_logs/$(date +"%Y-%m-%d---%H-%M-%S").log
\ No newline at end of file
diff --git a/src/components/AppLayout.tsx b/src/components/AppLayout.tsx
index 3bac0e7..40f5890 100644
--- a/src/components/AppLayout.tsx
+++ b/src/components/AppLayout.tsx
@@ -7,7 +7,7 @@ import Head from "next/head";
import { useSwipeable } from "react-swipeable";
import { useRouter } from "next/router";
import Button from "components/Button";
-import { getOgImage, prettyLanguage } from "queries/helpers";
+import { getOgImage, OgImage, prettyLanguage } from "queries/helpers";
import { useMediaCoarse, useMediaMobile } from "hooks/useMediaQuery";
import ReactTooltip from "react-tooltip";
import { useAppLayout } from "contexts/AppLayoutContext";
@@ -22,10 +22,10 @@ type AppLayoutProps = {
navTitle: string;
thumbnail?: StrapiImage;
description?: string;
+ extra?: React.ReactNode;
};
export default function AppLayout(props: AppLayoutProps): JSX.Element {
- const titlePrefix = "Accord’s Library";
const router = useRouter();
const isMobile = useMediaMobile();
const isCoarse = useMediaCoarse();
@@ -75,9 +75,21 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
const turnSubIntoContent = props.subPanel && !props.contentPanel;
- const ogImage = getOgImage(ImageQuality.Og, props.thumbnail);
+ const titlePrefix = "Accord’s Library";
+ const metaImage: OgImage = props.thumbnail
+ ? getOgImage(ImageQuality.Og, props.thumbnail)
+ : {
+ image: "/default_og.jpg",
+ width: 1200,
+ height: 630,
+ alt: "Accord's Library Logo",
+ };
const ogTitle = props.title ? props.title : props.navTitle;
+ const metaDescription = props.description
+ ? props.description
+ : "Accord's Library aims at gathering and archiving all of Yoko Taro’s work. Yoko Taro is a Japanese video game director and scenario writer.";
+
return (
-
-
+
+
>
)}
- {ogImage && (
- <>
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
- >
- )}
+
{/* Navbar */}
@@ -263,6 +265,8 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
className="drop-shadow-shade-xl !opacity-100 !bg-light !rounded-lg after:!border-r-light text-left !text-black"
/>
+
+ {props.extra}
);
}
diff --git a/src/components/Chip.tsx b/src/components/Chip.tsx
index 20b4c6b..e490ddc 100644
--- a/src/components/Chip.tsx
+++ b/src/components/Chip.tsx
@@ -1,12 +1,25 @@
type ChipProps = {
className?: string;
children: React.ReactChild | React.ReactChild[];
+ "data-tip"?: string;
+ "data-for"?: string;
+ "data-html"?: boolean;
+ "data-multiline"?: boolean;
};
export default function Chip(props: ChipProps): JSX.Element {
return (
{props.children}
diff --git a/src/components/Chronology/ChronologyItemComponent.tsx b/src/components/Chronology/ChronologyItemComponent.tsx
index 2afe59b..090fb92 100644
--- a/src/components/Chronology/ChronologyItemComponent.tsx
+++ b/src/components/Chronology/ChronologyItemComponent.tsx
@@ -87,7 +87,7 @@ export default function ChronologyItemComponent(
{translation.status !==
Enum_Componenttranslationschronologyitem_Status.Done && (
-
- {translation.status}
-
+ {translation.status}
+
)}
{translation.title ?
{translation.title} : ""}
diff --git a/src/components/Content/ThumbnailHeader.tsx b/src/components/Content/ThumbnailHeader.tsx
index 4f18163..13f1c3a 100644
--- a/src/components/Content/ThumbnailHeader.tsx
+++ b/src/components/Content/ThumbnailHeader.tsx
@@ -5,6 +5,7 @@ import {
import { prettySlug } from "queries/helpers";
import Button from "components/Button";
import Img, { ImageQuality } from "components/Img";
+import InsetBox from "components/InsetBox";
export type ThumbnailHeaderProps = {
content: {
@@ -25,7 +26,7 @@ export default function ThumbnailHeader(
return (
<>
-
+
{content.thumbnail.data ? (
+ {content.titles.length > 0 && content.titles[0].description && (
+
{content.titles[0].description}
+ )}
>
);
}
diff --git a/src/components/Img.tsx b/src/components/Img.tsx
index 76262bd..8723bbb 100644
--- a/src/components/Img.tsx
+++ b/src/components/Img.tsx
@@ -56,6 +56,7 @@ type ImgProps = {
layout?: ImageProps["layout"];
objectFit?: ImageProps["objectFit"];
priority?: ImageProps["priority"];
+ rawImg?: boolean;
};
export default function Img(props: ImgProps): JSX.Element {
@@ -64,20 +65,37 @@ export default function Img(props: ImgProps): JSX.Element {
props.image.height,
props.quality ? props.quality : ImageQuality.Small
);
- return (
-
- );
+
+ if (props.rawImg) {
+ return (
+ // eslint-disable-next-line @next/next/no-img-element
+
+ );
+ } else {
+ return (
+
+ );
+ }
}
diff --git a/src/components/PanelComponents/NavOption.tsx b/src/components/PanelComponents/NavOption.tsx
index df91024..be793d4 100644
--- a/src/components/PanelComponents/NavOption.tsx
+++ b/src/components/PanelComponents/NavOption.tsx
@@ -1,6 +1,7 @@
import { useRouter } from "next/router";
import Link from "next/link";
import { MouseEventHandler } from "react";
+import ReactDOMServer from "react-dom/server";
type NavOptionProps = {
url: string;
@@ -29,16 +30,14 @@ export default function NavOption(props: NavOptionProps): JSX.Element {
onClick={props.onClick}
data-html
data-multiline
- data-tip={`
-
-
${props.title}
- ${
- props.subtitle
- ? `
${props.subtitle}
`
- : ""
- }
+ data-tip={ReactDOMServer.renderToStaticMarkup(
+
+
{props.title}
+ {props.subtitle && (
+
{props.subtitle}
+ )}
- `}
+ )}
data-for={props.tooltipId}
className={`grid grid-flow-col grid-cols-[auto] auto-cols-fr justify-center ${
props.icon ? "text-left" : "text-center"
diff --git a/src/components/Panels/MainPanel.tsx b/src/components/Panels/MainPanel.tsx
index 4db6f4f..1ac3b2f 100644
--- a/src/components/Panels/MainPanel.tsx
+++ b/src/components/Panels/MainPanel.tsx
@@ -183,6 +183,7 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
)}
@@ -201,12 +202,14 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
+ )}
+ data-for={"RecordersTooltip"}
+ data-multiline
+ data-html
+ >
+ {recorder.attributes.anonymize
+ ? `Recorder#${recorder.attributes.anonymous_code}`
+ : recorder.attributes.username}
+
+ );
+}
diff --git a/src/graphql/operation.graphql b/src/graphql/operation.graphql
index f55d745..c73773f 100644
--- a/src/graphql/operation.graphql
+++ b/src/graphql/operation.graphql
@@ -73,7 +73,7 @@ query getWebsiteInterface($language_code: String) {
}
query getEras($language_code: String) {
- chronologyEras {
+ chronologyEras(sort: "starting_year") {
data {
id
attributes {
@@ -730,6 +730,7 @@ query getContent($slug: String, $language_code: String) {
pre_title
title
subtitle
+ description
}
categories {
data {
@@ -817,6 +818,7 @@ query getContentText($slug: String, $language_code: String) {
pre_title
title
subtitle
+ description
}
categories {
data {
@@ -875,16 +877,28 @@ query getContentText($slug: String, $language_code: String) {
source_language {
data {
attributes {
- name
+ code
}
}
}
transcribers {
data {
+ id
attributes {
username
anonymize
anonymous_code
+ pronouns
+ bio(filters: { language: { code: { eq: $language_code } } }) {
+ bio
+ }
+ languages {
+ data {
+ attributes {
+ code
+ }
+ }
+ }
avatar {
data {
attributes {
@@ -902,10 +916,22 @@ query getContentText($slug: String, $language_code: String) {
}
translators {
data {
+ id
attributes {
username
anonymize
anonymous_code
+ pronouns
+ bio(filters: { language: { code: { eq: $language_code } } }) {
+ bio
+ }
+ languages {
+ data {
+ attributes {
+ code
+ }
+ }
+ }
avatar {
data {
attributes {
@@ -923,10 +949,22 @@ query getContentText($slug: String, $language_code: String) {
}
proofreaders {
data {
+ id
attributes {
username
anonymize
anonymous_code
+ pronouns
+ bio(filters: { language: { code: { eq: $language_code } } }) {
+ bio
+ }
+ languages {
+ data {
+ attributes {
+ code
+ }
+ }
+ }
avatar {
data {
attributes {
diff --git a/src/graphql/operations-types.ts b/src/graphql/operations-types.ts
index 0aeff4e..50863f1 100644
--- a/src/graphql/operations-types.ts
+++ b/src/graphql/operations-types.ts
@@ -996,6 +996,7 @@ export type GetContentQuery = {
pre_title: string;
title: string;
subtitle: string;
+ description: string;
}>;
categories: {
__typename: "CategoryRelationResponseCollection";
@@ -1116,6 +1117,7 @@ export type GetContentTextQuery = {
pre_title: string;
title: string;
subtitle: string;
+ description: string;
}>;
categories: {
__typename: "CategoryRelationResponseCollection";
@@ -1194,18 +1196,34 @@ export type GetContentTextQuery = {
__typename: "LanguageEntityResponse";
data: {
__typename: "LanguageEntity";
- attributes: { __typename: "Language"; name: string };
+ attributes: { __typename: "Language"; code: string };
};
};
transcribers: {
__typename: "RecorderRelationResponseCollection";
data: Array<{
__typename: "RecorderEntity";
+ id: string;
attributes: {
__typename: "Recorder";
username: string;
anonymize: boolean;
anonymous_code: string;
+ pronouns: string;
+ bio: Array<{
+ __typename: "ComponentTranslationsBio";
+ bio: string;
+ }>;
+ languages: {
+ __typename: "LanguageRelationResponseCollection";
+ data: Array<{
+ __typename: "LanguageEntity";
+ attributes: {
+ __typename: "Language";
+ code: string;
+ };
+ }>;
+ };
avatar: {
__typename: "UploadFileEntityResponse";
data: {
@@ -1228,11 +1246,27 @@ export type GetContentTextQuery = {
__typename: "RecorderRelationResponseCollection";
data: Array<{
__typename: "RecorderEntity";
+ id: string;
attributes: {
__typename: "Recorder";
username: string;
anonymize: boolean;
anonymous_code: string;
+ pronouns: string;
+ bio: Array<{
+ __typename: "ComponentTranslationsBio";
+ bio: string;
+ }>;
+ languages: {
+ __typename: "LanguageRelationResponseCollection";
+ data: Array<{
+ __typename: "LanguageEntity";
+ attributes: {
+ __typename: "Language";
+ code: string;
+ };
+ }>;
+ };
avatar: {
__typename: "UploadFileEntityResponse";
data: {
@@ -1255,11 +1289,27 @@ export type GetContentTextQuery = {
__typename: "RecorderRelationResponseCollection";
data: Array<{
__typename: "RecorderEntity";
+ id: string;
attributes: {
__typename: "Recorder";
username: string;
anonymize: boolean;
anonymous_code: string;
+ pronouns: string;
+ bio: Array<{
+ __typename: "ComponentTranslationsBio";
+ bio: string;
+ }>;
+ languages: {
+ __typename: "LanguageRelationResponseCollection";
+ data: Array<{
+ __typename: "LanguageEntity";
+ attributes: {
+ __typename: "Language";
+ code: string;
+ };
+ }>;
+ };
avatar: {
__typename: "UploadFileEntityResponse";
data: {
diff --git a/src/graphql/schema.graphql b/src/graphql/schema.graphql
index d16a8c1..890a052 100644
--- a/src/graphql/schema.graphql
+++ b/src/graphql/schema.graphql
@@ -398,6 +398,23 @@ type ComponentCollectionsComponentLibraryObiBelt {
inside_full: UploadFileEntityResponse
}
+input ComponentCollectionsComponentTitlesFiltersInput {
+ title: StringFilterInput
+ and: [ComponentCollectionsComponentTitlesFiltersInput]
+ or: [ComponentCollectionsComponentTitlesFiltersInput]
+ not: ComponentCollectionsComponentTitlesFiltersInput
+}
+
+input ComponentCollectionsComponentTitlesInput {
+ id: ID
+ title: String
+}
+
+type ComponentCollectionsComponentTitles {
+ id: ID!
+ title: String!
+}
+
input ComponentCollectionsComponentWeaponStoryFiltersInput {
source: SourceFiltersInput
categories: CategoryFiltersInput
@@ -428,6 +445,17 @@ type ComponentCollectionsComponentWeaponStory {
): CategoryRelationResponseCollection
}
+type ComponentCollectionsComponentWikiDefinition {
+ id: ID!
+ definition: String
+ categories(
+ filters: CategoryFiltersInput
+ pagination: PaginationArg = {}
+ sort: [String] = []
+ ): CategoryRelationResponseCollection
+ source: SourceEntityResponse
+}
+
type ComponentMetadataAudio {
id: ID!
subtype: AudioSubtypeEntityResponse
@@ -771,6 +799,69 @@ type ComponentSetsVideoSet {
notes: String
}
+enum ENUM_COMPONENTSETSWIKISET_STATUS {
+ Incomplete
+ Draft
+ Review
+ Done
+}
+
+input ComponentSetsWikiSetFiltersInput {
+ language: LanguageFiltersInput
+ status: StringFilterInput
+ summary: StringFilterInput
+ body: StringFilterInput
+ source_language: LanguageFiltersInput
+ authors: RecorderFiltersInput
+ translators: RecorderFiltersInput
+ proofreaders: RecorderFiltersInput
+ and: [ComponentSetsWikiSetFiltersInput]
+ or: [ComponentSetsWikiSetFiltersInput]
+ not: ComponentSetsWikiSetFiltersInput
+}
+
+input ComponentSetsWikiSetInput {
+ id: ID
+ language: ID
+ status: ENUM_COMPONENTSETSWIKISET_STATUS
+ titles: [ComponentCollectionsComponentTitlesInput]
+ summary: String
+ body: String
+ source_language: ID
+ authors: [ID]
+ translators: [ID]
+ proofreaders: [ID]
+}
+
+type ComponentSetsWikiSet {
+ id: ID!
+ language: LanguageEntityResponse
+ status: ENUM_COMPONENTSETSWIKISET_STATUS!
+ titles(
+ filters: ComponentCollectionsComponentTitlesFiltersInput
+ pagination: PaginationArg = {}
+ sort: [String] = []
+ ): [ComponentCollectionsComponentTitles]
+ summary: String
+ body: String
+ source_language: LanguageEntityResponse
+ authors(
+ filters: RecorderFiltersInput
+ pagination: PaginationArg = {}
+ sort: [String] = []
+ ): RecorderRelationResponseCollection
+ translators(
+ filters: RecorderFiltersInput
+ pagination: PaginationArg = {}
+ sort: [String] = []
+ ): RecorderRelationResponseCollection
+ proofreaders(
+ filters: RecorderFiltersInput
+ pagination: PaginationArg = {}
+ sort: [String] = []
+ ): RecorderRelationResponseCollection
+}
+
type ComponentSourceUrlSource {
id: ID!
title: String
@@ -794,9 +885,30 @@ type ComponentTranslationsAudioSets {
credits: ComponentBasicsCredits!
}
+input ComponentTranslationsBioFiltersInput {
+ language: LanguageFiltersInput
+ bio: StringFilterInput
+ and: [ComponentTranslationsBioFiltersInput]
+ or: [ComponentTranslationsBioFiltersInput]
+ not: ComponentTranslationsBioFiltersInput
+}
+
+input ComponentTranslationsBioInput {
+ id: ID
+ language: ID
+ bio: String
+}
+
+type ComponentTranslationsBio {
+ id: ID!
+ language: LanguageEntityResponse
+ bio: String
+}
+
input ComponentTranslationsChronologyEraFiltersInput {
title: StringFilterInput
language: LanguageFiltersInput
+ description: StringFilterInput
and: [ComponentTranslationsChronologyEraFiltersInput]
or: [ComponentTranslationsChronologyEraFiltersInput]
not: ComponentTranslationsChronologyEraFiltersInput
@@ -806,12 +918,14 @@ input ComponentTranslationsChronologyEraInput {
id: ID
title: String
language: ID
+ description: String
}
type ComponentTranslationsChronologyEra {
id: ID!
- title: String
+ title: String!
language: LanguageEntityResponse
+ description: String
}
enum ENUM_COMPONENTTRANSLATIONSCHRONOLOGYITEM_STATUS {
@@ -1017,6 +1131,7 @@ input ComponentTranslationsTitleFiltersInput {
title: StringFilterInput
subtitle: StringFilterInput
pre_title: StringFilterInput
+ description: StringFilterInput
and: [ComponentTranslationsTitleFiltersInput]
or: [ComponentTranslationsTitleFiltersInput]
not: ComponentTranslationsTitleFiltersInput
@@ -1028,6 +1143,7 @@ input ComponentTranslationsTitleInput {
title: String
subtitle: String
pre_title: String
+ description: String
}
type ComponentTranslationsTitle {
@@ -1036,6 +1152,7 @@ type ComponentTranslationsTitle {
title: String!
subtitle: String
pre_title: String
+ description: String
}
enum ENUM_COMPONENTTRANSLATIONSVIDEOSETS_STATUS {
@@ -2051,6 +2168,7 @@ input RecorderFiltersInput {
anonymize: BooleanFilterInput
anonymous_code: StringFilterInput
languages: LanguageFiltersInput
+ pronouns: StringFilterInput
createdAt: DateTimeFilterInput
updatedAt: DateTimeFilterInput
and: [RecorderFiltersInput]
@@ -2064,6 +2182,8 @@ input RecorderInput {
anonymous_code: String
avatar: ID
languages: [ID]
+ pronouns: String
+ bio: [ComponentTranslationsBioInput]
}
type Recorder {
@@ -2076,6 +2196,12 @@ type Recorder {
pagination: PaginationArg = {}
sort: [String] = []
): LanguageRelationResponseCollection
+ pronouns: String
+ bio(
+ filters: ComponentTranslationsBioFiltersInput
+ pagination: PaginationArg = {}
+ sort: [String] = []
+ ): [ComponentTranslationsBio]
createdAt: DateTime
updatedAt: DateTime
}
@@ -2359,12 +2485,7 @@ input WebsiteInterfaceFiltersInput {
language: LanguageFiltersInput
main_library: StringFilterInput
main_library_description: StringFilterInput
- main_hub: StringFilterInput
- main_hub_description: StringFilterInput
- main_chronology: StringFilterInput
- main_chronology_description: StringFilterInput
main_news: StringFilterInput
- main_data: StringFilterInput
main_merch: StringFilterInput
main_gallery: StringFilterInput
main_archives: StringFilterInput
@@ -2394,13 +2515,6 @@ input WebsiteInterfaceFiltersInput {
global_price: StringFilterInput
library_item_physical_size: StringFilterInput
library_item_type_information: StringFilterInput
- chronology_description: StringFilterInput
- chronology_timelines: StringFilterInput
- chronology_timelines_description: StringFilterInput
- chronology_overview: StringFilterInput
- chronology_overview_description: StringFilterInput
- chronology_walkthrough: StringFilterInput
- chronology_walkthrough_description: StringFilterInput
library_item_front_matter: StringFilterInput
library_item_back_matter: StringFilterInput
library_item_type_textual: StringFilterInput
@@ -2419,6 +2533,21 @@ input WebsiteInterfaceFiltersInput {
global_hardcover: StringFilterInput
global_left_to_right: StringFilterInput
global_right_to_left: StringFilterInput
+ main_wiki: StringFilterInput
+ main_wiki_description: StringFilterInput
+ main_chronicles: StringFilterInput
+ main_chronicles_description: StringFilterInput
+ library_items: StringFilterInput
+ library_items_description: StringFilterInput
+ library_content: StringFilterInput
+ library_content_description: StringFilterInput
+ wiki_description: StringFilterInput
+ news_description: StringFilterInput
+ chronicles_description: StringFilterInput
+ gallery_description: StringFilterInput
+ archives_description: StringFilterInput
+ about_us_description: StringFilterInput
+ merch_description: StringFilterInput
createdAt: DateTimeFilterInput
updatedAt: DateTimeFilterInput
and: [WebsiteInterfaceFiltersInput]
@@ -2430,12 +2559,7 @@ input WebsiteInterfaceInput {
language: ID
main_library: String
main_library_description: String
- main_hub: String
- main_hub_description: String
- main_chronology: String
- main_chronology_description: String
main_news: String
- main_data: String
main_merch: String
main_gallery: String
main_archives: String
@@ -2465,13 +2589,6 @@ input WebsiteInterfaceInput {
global_price: String
library_item_physical_size: String
library_item_type_information: String
- chronology_description: String
- chronology_timelines: String
- chronology_timelines_description: String
- chronology_overview: String
- chronology_overview_description: String
- chronology_walkthrough: String
- chronology_walkthrough_description: String
library_item_front_matter: String
library_item_back_matter: String
library_item_type_textual: String
@@ -2490,18 +2607,28 @@ input WebsiteInterfaceInput {
global_hardcover: String
global_left_to_right: String
global_right_to_left: String
+ main_wiki: String
+ main_wiki_description: String
+ main_chronicles: String
+ main_chronicles_description: String
+ library_items: String
+ library_items_description: String
+ library_content: String
+ library_content_description: String
+ wiki_description: String
+ news_description: String
+ chronicles_description: String
+ gallery_description: String
+ archives_description: String
+ about_us_description: String
+ merch_description: String
}
type WebsiteInterface {
language: LanguageEntityResponse
main_library: String
main_library_description: String
- main_hub: String
- main_hub_description: String
- main_chronology: String
- main_chronology_description: String
main_news: String
- main_data: String
main_merch: String
main_gallery: String
main_archives: String
@@ -2531,13 +2658,6 @@ type WebsiteInterface {
global_price: String
library_item_physical_size: String
library_item_type_information: String
- chronology_description: String
- chronology_timelines: String
- chronology_timelines_description: String
- chronology_overview: String
- chronology_overview_description: String
- chronology_walkthrough: String
- chronology_walkthrough_description: String
library_item_front_matter: String
library_item_back_matter: String
library_item_type_textual: String
@@ -2556,6 +2676,21 @@ type WebsiteInterface {
global_hardcover: String
global_left_to_right: String
global_right_to_left: String
+ main_wiki: String
+ main_wiki_description: String
+ main_chronicles: String
+ main_chronicles_description: String
+ library_items: String
+ library_items_description: String
+ library_content: String
+ library_content_description: String
+ wiki_description: String
+ news_description: String
+ chronicles_description: String
+ gallery_description: String
+ archives_description: String
+ about_us_description: String
+ merch_description: String
createdAt: DateTime
updatedAt: DateTime
}
@@ -2574,6 +2709,91 @@ type WebsiteInterfaceEntityResponseCollection {
meta: ResponseCollectionMeta!
}
+input WikiPageFiltersInput {
+ id: IDFilterInput
+ slug: StringFilterInput
+ type: WikiPageTypeFiltersInput
+ createdAt: DateTimeFilterInput
+ updatedAt: DateTimeFilterInput
+ and: [WikiPageFiltersInput]
+ or: [WikiPageFiltersInput]
+ not: WikiPageFiltersInput
+}
+
+input WikiPageInput {
+ slug: String
+ thumbnail: ID
+ wiki_set: [ComponentSetsWikiSetInput]
+ type: ID
+}
+
+type WikiPage {
+ slug: String!
+ thumbnail: UploadFileEntityResponse
+ wiki_set(
+ filters: ComponentSetsWikiSetFiltersInput
+ pagination: PaginationArg = {}
+ sort: [String] = []
+ ): [ComponentSetsWikiSet]
+ type: WikiPageTypeEntityResponse
+ createdAt: DateTime
+ updatedAt: DateTime
+}
+
+type WikiPageEntity {
+ id: ID
+ attributes: WikiPage
+}
+
+type WikiPageEntityResponse {
+ data: WikiPageEntity
+}
+
+type WikiPageEntityResponseCollection {
+ data: [WikiPageEntity!]!
+ meta: ResponseCollectionMeta!
+}
+
+input WikiPageTypeFiltersInput {
+ id: IDFilterInput
+ slug: StringFilterInput
+ createdAt: DateTimeFilterInput
+ updatedAt: DateTimeFilterInput
+ and: [WikiPageTypeFiltersInput]
+ or: [WikiPageTypeFiltersInput]
+ not: WikiPageTypeFiltersInput
+}
+
+input WikiPageTypeInput {
+ slug: String
+ titles: [ComponentTranslationsSimpleTitleInput]
+}
+
+type WikiPageType {
+ slug: String!
+ titles(
+ filters: ComponentTranslationsSimpleTitleFiltersInput
+ pagination: PaginationArg = {}
+ sort: [String] = []
+ ): [ComponentTranslationsSimpleTitle]
+ createdAt: DateTime
+ updatedAt: DateTime
+}
+
+type WikiPageTypeEntity {
+ id: ID
+ attributes: WikiPageType
+}
+
+type WikiPageTypeEntityResponse {
+ data: WikiPageTypeEntity
+}
+
+type WikiPageTypeEntityResponseCollection {
+ data: [WikiPageTypeEntity!]!
+ meta: ResponseCollectionMeta!
+}
+
union GenericMorph =
ComponentBasicsCredits
| ComponentBasicsDatepicker
@@ -2585,7 +2805,9 @@ union GenericMorph =
| ComponentCollectionsComponentLibraryDustJacket
| ComponentCollectionsComponentLibraryImages
| ComponentCollectionsComponentLibraryObiBelt
+ | ComponentCollectionsComponentTitles
| ComponentCollectionsComponentWeaponStory
+ | ComponentCollectionsComponentWikiDefinition
| ComponentMetadataAudio
| ComponentMetadataBooks
| ComponentMetadataGame
@@ -2606,8 +2828,10 @@ union GenericMorph =
| ComponentSetsScanSet
| ComponentSetsTextSet
| ComponentSetsVideoSet
+ | ComponentSetsWikiSet
| ComponentSourceUrlSource
| ComponentTranslationsAudioSets
+ | ComponentTranslationsBio
| ComponentTranslationsChronologyEra
| ComponentTranslationsChronologyItem
| ComponentTranslationsGlossaryDefinition
@@ -2648,6 +2872,8 @@ union GenericMorph =
| WeaponStoryGroup
| WeaponStoryType
| WebsiteInterface
+ | WikiPage
+ | WikiPageType
input FileInfoInput {
name: String
@@ -2814,6 +3040,18 @@ type Query {
pagination: PaginationArg = {}
sort: [String] = []
): WebsiteInterfaceEntityResponseCollection
+ wikiPage(id: ID): WikiPageEntityResponse
+ wikiPages(
+ filters: WikiPageFiltersInput
+ pagination: PaginationArg = {}
+ sort: [String] = []
+ ): WikiPageEntityResponseCollection
+ wikiPageType(id: ID): WikiPageTypeEntityResponse
+ wikiPageTypes(
+ filters: WikiPageTypeFiltersInput
+ pagination: PaginationArg = {}
+ sort: [String] = []
+ ): WikiPageTypeEntityResponseCollection
}
type Mutation {
@@ -2939,6 +3177,15 @@ type Mutation {
data: WebsiteInterfaceInput!
): WebsiteInterfaceEntityResponse
deleteWebsiteInterface(id: ID!): WebsiteInterfaceEntityResponse
+ createWikiPage(data: WikiPageInput!): WikiPageEntityResponse
+ updateWikiPage(id: ID!, data: WikiPageInput!): WikiPageEntityResponse
+ deleteWikiPage(id: ID!): WikiPageEntityResponse
+ createWikiPageType(data: WikiPageTypeInput!): WikiPageTypeEntityResponse
+ updateWikiPageType(
+ id: ID!
+ data: WikiPageTypeInput!
+ ): WikiPageTypeEntityResponse
+ deleteWikiPageType(id: ID!): WikiPageTypeEntityResponse
upload(
refId: ID
ref: String
diff --git a/src/pages/_document.tsx b/src/pages/_document.tsx
index 5cbfe18..506d91b 100644
--- a/src/pages/_document.tsx
+++ b/src/pages/_document.tsx
@@ -39,7 +39,16 @@ class MyDocument extends Document {
-
+
+
0 ? content.titles[0].description : undefined
+ }
/>
);
}
diff --git a/src/pages/contents/[slug]/read.tsx b/src/pages/contents/[slug]/read.tsx
index fa1d757..e7200ca 100644
--- a/src/pages/contents/[slug]/read.tsx
+++ b/src/pages/contents/[slug]/read.tsx
@@ -5,6 +5,7 @@ import {
getWebsiteInterface,
} from "graphql/operations";
import {
+ Enum_Componentsetstextset_Status,
GetContentTextQuery,
GetWebsiteInterfaceQuery,
} from "graphql/operations-types";
@@ -15,7 +16,18 @@ import ReturnButton from "components/PanelComponents/ReturnButton";
import ThumbnailHeader from "components/Content/ThumbnailHeader";
import AppLayout from "components/AppLayout";
import Markdawn from "components/Markdown/Markdawn";
-import { prettyinlineTitle, prettySlug } from "queries/helpers";
+import {
+ prettyinlineTitle,
+ prettyLanguage,
+ prettySlug,
+ prettyTestError,
+ prettyTestWarning,
+} from "queries/helpers";
+import Button from "components/Button";
+import { useRouter } from "next/router";
+import Chip from "components/Chip";
+import ReactTooltip from "react-tooltip";
+import RecorderChip from "components/RecorderChip";
type ContentReadProps = {
content: GetContentTextQuery;
@@ -25,6 +37,10 @@ type ContentReadProps = {
export default function ContentRead(props: ContentReadProps): JSX.Element {
const content = props.content.contents.data[0].attributes;
const langui = props.langui.websiteInterfaces.data[0].attributes;
+ const router = useRouter();
+
+ useTesting(props.content);
+
const subPanel = (
+
+
+
+ {content.text_set.length > 0 ? (
+
+
+ {content.text_set[0].source_language.data.attributes.code ===
+ router.locale
+ ? "This content is a transcript"
+ : "This content is a fan-translation"}
+
+
+ {content.text_set[0].source_language.data.attributes.code !==
+ router.locale && (
+
+
Source language:
+
+ {prettyLanguage(
+ content.text_set[0].source_language.data.attributes.code
+ )}
+
+
+ )}
+
+
+
Status:
+
+
+ {content.text_set[0].status}
+
+
+
+ {content.text_set[0].transcribers.data.length > 0 && (
+
+
Transcribers:
+
+ {content.text_set[0].transcribers.data.map((recorder) => (
+
+ ))}
+
+
+ )}
+
+ {content.text_set[0].translators.data.length > 0 && (
+
+
Translators:
+
+ {content.text_set[0].translators.data.map((recorder) => (
+
+ ))}
+
+
+ )}
+
+ {content.text_set[0].proofreaders.data.length > 0 && (
+
+
Proofreaders:
+
+ {content.text_set[0].proofreaders.data.map((recorder) => (
+
+ ))}
+
+
+ )}
+
+ ) : (
+ ""
+ )}
);
const contentPanel = (
@@ -50,18 +153,49 @@ export default function ContentRead(props: ContentReadProps): JSX.Element {
);
+ const extra = (
+ <>
+
+
+
+ >
+ );
+
return (
0
- ? prettyinlineTitle(content.titles[0].pre_title, content.titles[0].title, content.titles[0].subtitle)
+ ? prettyinlineTitle(
+ content.titles[0].pre_title,
+ content.titles[0].title,
+ content.titles[0].subtitle
+ )
: prettySlug(content.slug)
}
thumbnail={content.thumbnail.data.attributes}
langui={langui}
contentPanel={contentPanel}
subPanel={subPanel}
+ extra={extra}
/>
);
}
@@ -109,3 +243,72 @@ export const getStaticPaths: GetStaticPaths = async (context) => {
fallback: false,
};
};
+
+export function useTesting(content: GetContentTextQuery) {
+ const router = useRouter();
+ const contentAtr = content.contents.data[0].attributes;
+ if (contentAtr.categories.data.length === 0) {
+ prettyTestError(router, "Missing categories", ["content"]);
+ }
+
+ if (contentAtr.ranged_contents.data.length === 0) {
+ prettyTestWarning(router, "Unconnected to any source", ["content"]);
+ }
+
+ if (contentAtr.text_set.length === 0) {
+ prettyTestWarning(router, "Has no textset, nor audioset, nor videoset", [
+ "content",
+ ]);
+ }
+
+ if (contentAtr.text_set.length > 1) {
+ console.warn(
+ prettyTestError(router, "More than one textset for this language", [
+ "content",
+ "text_set",
+ ])
+ );
+ }
+
+ if (contentAtr.text_set.length === 1) {
+ const textset = contentAtr.text_set[0];
+ if (!textset.text) {
+ prettyTestError(router, "Missing text", ["content", "text_set"]);
+ }
+ if (!textset.source_language.data) {
+ prettyTestError(router, "Missing source language", [
+ "content",
+ "text_set",
+ ]);
+ }
+ if (textset.source_language.data.attributes.code === router.locale) {
+ // This is a transcript
+ if (textset.transcribers.data.length === 0) {
+ prettyTestError(router, "Missing transcribers attribution", [
+ "content",
+ "text_set",
+ ]);
+ }
+ if (textset.translators.data.length > 0) {
+ prettyTestError(router, "Transcripts shouldn't have translators", [
+ "content",
+ "text_set",
+ ]);
+ }
+ } else {
+ // This is a translation
+ if (textset.translators.data.length === 0) {
+ prettyTestError(router, "Missing translators attribution", [
+ "content",
+ "text_set",
+ ]);
+ }
+ if (textset.transcribers.data.length > 0) {
+ prettyTestError(router, "Translations shouldn't have transcribers", [
+ "content",
+ "text_set",
+ ]);
+ }
+ }
+ }
+}
diff --git a/src/pages/wiki/chronology.tsx b/src/pages/wiki/chronology.tsx
index ef9d14d..25a51ba 100644
--- a/src/pages/wiki/chronology.tsx
+++ b/src/pages/wiki/chronology.tsx
@@ -16,7 +16,11 @@ import NavOption from "components/PanelComponents/NavOption";
import ReturnButton from "components/PanelComponents/ReturnButton";
import HorizontalLine from "components/HorizontalLine";
import AppLayout from "components/AppLayout";
-import { prettySlug } from "queries/helpers";
+import {
+ prettySlug,
+ prettyTestError,
+ prettyTestWarning,
+} from "queries/helpers";
import InsetBox from "components/InsetBox";
import { useRouter } from "next/router";
import ReactTooltip from "react-tooltip";
@@ -165,41 +169,52 @@ export function useTesting(
const router = useRouter();
chronologyEras.chronologyEras.data.map((era) => {
if (era.attributes.title.length === 0) {
- console.warn(
- `${router.pathname} | ${router.locale} | chronologyEras | ${era.attributes.slug} | Missing translation for title and description, using slug instead`
+ prettyTestError(
+ router,
+ "Missing translation for title and description, using slug instead",
+ ["chronologyEras", era.attributes.slug]
);
} else if (era.attributes.title.length > 1) {
- console.warn(
- `${router.pathname} | ${router.locale} | chronologyEras | ${era.attributes.slug} | More than one title and description`
- );
+ prettyTestError(router, "More than one title and description", [
+ "chronologyEras",
+ era.attributes.slug,
+ ]);
} else {
if (!era.attributes.title[0].title)
- console.warn(
- `${router.pathname} | ${router.locale} | chronologyEras | ${era.attributes.slug} | Missing title, using slug instead`
- );
+ prettyTestError(router, "Missing title, using slug instead", [
+ "chronologyEras",
+ era.attributes.slug,
+ ]);
if (!era.attributes.title[0].description)
- console.warn(
- `${router.pathname} | ${router.locale} | chronologyEras | ${era.attributes.slug} | Missing description`
- );
+ prettyTestError(router, "Missing description", [
+ "chronologyEras",
+ era.attributes.slug,
+ ]);
}
});
chronologyItems.chronologyItems.data.map((item) => {
+ const date = `${item.attributes.year}/${item.attributes.month}/${item.attributes.day}`;
if (!(item.attributes.events.length > 0)) {
- console.warn(
- `${router.pathname} | ${router.locale} | chronologyItems | ${item.attributes.year}/${item.attributes.month}/${item.attributes.day} | No events for this date`
- );
+ prettyTestError(router, "No events for this date", [
+ "chronologyItems",
+ date,
+ ]);
} else {
item.attributes.events.map((event) => {
if (!event.source.data) {
- console.warn(
- `${router.pathname} | ${router.locale} | chronologyItems | ${item.attributes.year}/${item.attributes.month}/${item.attributes.day} | ${event.id} | No source for this event`
- );
+ prettyTestError(router, "No source for this event", [
+ "chronologyItems",
+ date,
+ event.id,
+ ]);
}
if (!(event.translations.length > 0)) {
- console.warn(
- `${router.pathname} | ${router.locale} | chronologyItems | ${item.attributes.year}/${item.attributes.month}/${item.attributes.day} | ${event.id} | No translation for this event`
- );
+ prettyTestWarning(router, "No translation for this event", [
+ "chronologyItems",
+ date,
+ event.id,
+ ]);
}
});
}
diff --git a/src/queries/helpers.ts b/src/queries/helpers.ts
index e9f07ff..4b75647 100644
--- a/src/queries/helpers.ts
+++ b/src/queries/helpers.ts
@@ -8,6 +8,7 @@ import {
GetWebsiteInterfaceQuery,
StrapiImage,
} from "graphql/operations-types";
+import { NextRouter } from "next/router";
export function prettyDate(
datePicker: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["release_date"]
@@ -117,6 +118,39 @@ export function prettyLanguage(code: string): string {
}
}
+export function prettyTestWarning(
+ router: NextRouter,
+ message: string,
+ subCategory?: string[]
+): void {
+ prettyTestWritter(TestingLevel.Warning, router, message, subCategory);
+}
+
+export function prettyTestError(
+ router: NextRouter,
+ message: string,
+ subCategory?: string[]
+): void {
+ prettyTestWritter(TestingLevel.Error, router, message, subCategory);
+}
+
+enum TestingLevel {
+ Warning = "warn",
+ Error = "error",
+}
+
+function prettyTestWritter(
+ level: TestingLevel,
+ { asPath, locale }: NextRouter,
+ message: string,
+ subCategory?: string[]
+): void {
+ subCategory?.push("");
+ console.warn(
+ `${level} - ${asPath} | ${locale} | ${subCategory?.join(" | ")}${message}`
+ );
+}
+
export function capitalizeString(string: string): string {
function capitalizeWord(word: string): string {
return word.charAt(0).toUpperCase() + word.substring(1);
@@ -131,28 +165,23 @@ export function convertMmToInch(mm: number): string {
return (mm * 0.03937008).toPrecision(3);
}
-type OgImage = {
+export type OgImage = {
image: string;
width: number;
height: number;
alt: string;
};
-export function getOgImage(
- quality: ImageQuality,
- image?: StrapiImage
-): OgImage | undefined {
- if (image) {
- const imgSize = getImgSizesByQuality(
- image.width,
- image.height,
- quality ? quality : ImageQuality.Small
- );
- return {
- image: getAssetURL(image.url, quality),
- width: imgSize.width,
- height: imgSize.height,
- alt: image.alternativeText,
- };
- }
+export function getOgImage(quality: ImageQuality, image: StrapiImage): OgImage {
+ const imgSize = getImgSizesByQuality(
+ image.width,
+ image.height,
+ quality ? quality : ImageQuality.Small
+ );
+ return {
+ image: getAssetURL(image.url, quality),
+ width: imgSize.width,
+ height: imgSize.height,
+ alt: image.alternativeText,
+ };
}
diff --git a/src/tailwind.css b/src/tailwind.css
index 852c41f..6eea261 100644
--- a/src/tailwind.css
+++ b/src/tailwind.css
@@ -77,6 +77,10 @@
@apply text-dark;
}
+ .prose blockquote {
+ @apply border-l-dark
+ }
+
}
@layer components {
diff --git a/testing_logs/.gitkeep b/testing_logs/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/tsconfig.json b/tsconfig.json
index a67193d..003a01d 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -2,6 +2,7 @@
"compilerOptions": {
"target": "ESNext",
"lib": ["dom", "dom.iterable", "esnext"],
+ "importHelpers": true,
"allowJs": true,
"skipLibCheck": true,
"strict": true,