Categories and recorders are now localdata
This commit is contained in:
parent
c3796b4fe8
commit
284bbd6272
@ -1 +1,2 @@
|
||||
.next
|
||||
public/local-data/*
|
@ -1,100 +1 @@
|
||||
{
|
||||
"currencies": {
|
||||
"data": [
|
||||
{
|
||||
"id": "1",
|
||||
"attributes": {
|
||||
"code": "EUR",
|
||||
"symbol": "€",
|
||||
"rate_to_usd": 1.036166,
|
||||
"display_decimals": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "2",
|
||||
"attributes": {
|
||||
"code": "CAD",
|
||||
"symbol": "$",
|
||||
"rate_to_usd": 0.79319156,
|
||||
"display_decimals": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "3",
|
||||
"attributes": { "code": "USD", "symbol": "$", "rate_to_usd": 1, "display_decimals": true }
|
||||
},
|
||||
{
|
||||
"id": "4",
|
||||
"attributes": {
|
||||
"code": "JPY",
|
||||
"symbol": "¥",
|
||||
"rate_to_usd": 0.0083864261,
|
||||
"display_decimals": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "5",
|
||||
"attributes": {
|
||||
"code": "BRL",
|
||||
"symbol": "R$",
|
||||
"rate_to_usd": 0.19904328,
|
||||
"display_decimals": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "6",
|
||||
"attributes": {
|
||||
"code": "GBP",
|
||||
"symbol": "£",
|
||||
"rate_to_usd": 1.3181323,
|
||||
"display_decimals": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "7",
|
||||
"attributes": {
|
||||
"code": "AUD",
|
||||
"symbol": "$",
|
||||
"rate_to_usd": 0.7422,
|
||||
"display_decimals": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "8",
|
||||
"attributes": {
|
||||
"code": "INR",
|
||||
"symbol": "₹",
|
||||
"rate_to_usd": 0.013162881,
|
||||
"display_decimals": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "9",
|
||||
"attributes": {
|
||||
"code": "NZD",
|
||||
"symbol": "$",
|
||||
"rate_to_usd": 0.69089984,
|
||||
"display_decimals": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "10",
|
||||
"attributes": {
|
||||
"code": "CHF",
|
||||
"symbol": "CHF",
|
||||
"rate_to_usd": 1.0728706,
|
||||
"display_decimals": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "11",
|
||||
"attributes": {
|
||||
"code": "CNY",
|
||||
"symbol": "¥",
|
||||
"rate_to_usd": 0.141546,
|
||||
"display_decimals": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
{"currencies":{"data":[{"id":"1","attributes":{"code":"EUR","symbol":"€","rate_to_usd":1.036166,"display_decimals":true}},{"id":"2","attributes":{"code":"CAD","symbol":"$","rate_to_usd":0.79319156,"display_decimals":true}},{"id":"3","attributes":{"code":"USD","symbol":"$","rate_to_usd":1,"display_decimals":true}},{"id":"4","attributes":{"code":"JPY","symbol":"¥","rate_to_usd":0.0083864261,"display_decimals":false}},{"id":"5","attributes":{"code":"BRL","symbol":"R$","rate_to_usd":0.19904328,"display_decimals":true}},{"id":"6","attributes":{"code":"GBP","symbol":"£","rate_to_usd":1.3181323,"display_decimals":true}},{"id":"7","attributes":{"code":"AUD","symbol":"$","rate_to_usd":0.7422,"display_decimals":true}},{"id":"8","attributes":{"code":"INR","symbol":"₹","rate_to_usd":0.013162881,"display_decimals":false}},{"id":"9","attributes":{"code":"NZD","symbol":"$","rate_to_usd":0.69089984,"display_decimals":true}},{"id":"10","attributes":{"code":"CHF","symbol":"CHF","rate_to_usd":1.0728706,"display_decimals":true}},{"id":"11","attributes":{"code":"CNY","symbol":"¥","rate_to_usd":0.141546,"display_decimals":true}}]}}
|
@ -1,29 +1 @@
|
||||
{
|
||||
"languages": {
|
||||
"data": [
|
||||
{ "id": "1", "attributes": { "name": "French", "code": "fr", "localized_name": "Français" } },
|
||||
{ "id": "2", "attributes": { "name": "English", "code": "en", "localized_name": "English" } },
|
||||
{ "id": "3", "attributes": { "name": "Japanese", "code": "ja", "localized_name": "日本語" } },
|
||||
{ "id": "4", "attributes": { "name": "Spanish", "code": "es", "localized_name": "Español" } },
|
||||
{
|
||||
"id": "6",
|
||||
"attributes": {
|
||||
"name": "Portuguese (Brazil)",
|
||||
"code": "pt-br",
|
||||
"localized_name": "Português (Brasil)"
|
||||
}
|
||||
},
|
||||
{ "id": "8", "attributes": { "name": "German", "code": "de", "localized_name": "Deutsch" } },
|
||||
{
|
||||
"id": "9",
|
||||
"attributes": { "name": "Italian", "code": "it", "localized_name": "Italiano" }
|
||||
},
|
||||
{
|
||||
"id": "10",
|
||||
"attributes": { "name": "Russian", "code": "ru", "localized_name": "русский" }
|
||||
},
|
||||
{ "id": "11", "attributes": { "name": "Korean", "code": "ko", "localized_name": "한국어" } },
|
||||
{ "id": "12", "attributes": { "name": "Chinese", "code": "zh", "localized_name": "中文" } }
|
||||
]
|
||||
}
|
||||
}
|
||||
{"languages":{"data":[{"id":"1","attributes":{"name":"French","code":"fr","localized_name":"Français"}},{"id":"2","attributes":{"name":"English","code":"en","localized_name":"English"}},{"id":"3","attributes":{"name":"Japanese","code":"ja","localized_name":"日本語"}},{"id":"4","attributes":{"name":"Spanish","code":"es","localized_name":"Español"}},{"id":"6","attributes":{"name":"Portuguese (Brazil)","code":"pt-br","localized_name":"Português (Brasil)"}},{"id":"8","attributes":{"name":"German","code":"de","localized_name":"Deutsch"}},{"id":"9","attributes":{"name":"Italian","code":"it","localized_name":"Italiano"}},{"id":"10","attributes":{"name":"Russian","code":"ru","localized_name":"русский"}},{"id":"11","attributes":{"name":"Korean","code":"ko","localized_name":"한국어"}},{"id":"12","attributes":{"name":"Chinese","code":"zh","localized_name":"中文"}}]}}
|
1
public/local-data/recorders.json
Normal file
1
public/local-data/recorders.json
Normal file
File diff suppressed because one or more lines are too long
1
public/local-data/typesTranslations.json
Normal file
1
public/local-data/typesTranslations.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -3,7 +3,6 @@ import { Markdawn } from "components/Markdown/Markdawn";
|
||||
import { RecorderChip } from "components/RecorderChip";
|
||||
import { ToolTip } from "components/ToolTip";
|
||||
import { atoms } from "contexts/atoms";
|
||||
import { RecorderChipFragment } from "graphql/generated";
|
||||
import { filterHasAttributes, isDefined, isDefinedAndNotEmpty } from "helpers/asserts";
|
||||
import { useAtomGetter } from "helpers/atoms";
|
||||
import { prettyLanguage } from "helpers/formatters";
|
||||
@ -18,12 +17,12 @@ interface Props {
|
||||
languageCode?: string;
|
||||
sourceLanguageCode?: string;
|
||||
status?: ContentStatus | null;
|
||||
transcribers?: { attributes?: RecorderChipFragment | null }[];
|
||||
translators?: { attributes?: RecorderChipFragment | null }[];
|
||||
proofreaders?: { attributes?: RecorderChipFragment | null }[];
|
||||
dubbers?: { attributes?: RecorderChipFragment | null }[];
|
||||
subbers?: { attributes?: RecorderChipFragment | null }[];
|
||||
authors?: { attributes?: RecorderChipFragment | null }[];
|
||||
transcribers?: RecorderChipsProps["recorders"];
|
||||
translators?: RecorderChipsProps["recorders"];
|
||||
proofreaders?: RecorderChipsProps["recorders"];
|
||||
dubbers?: RecorderChipsProps["recorders"];
|
||||
subbers?: RecorderChipsProps["recorders"];
|
||||
authors?: RecorderChipsProps["recorders"];
|
||||
notes?: string | null;
|
||||
}
|
||||
|
||||
@ -118,14 +117,14 @@ export const Credits = ({
|
||||
|
||||
interface RecorderChipsProps {
|
||||
title: string;
|
||||
recorders: { attributes?: RecorderChipFragment | null }[];
|
||||
recorders: { attributes?: { username: string } | null }[];
|
||||
}
|
||||
|
||||
const RecorderChips = ({ title, recorders }: RecorderChipsProps) => (
|
||||
<div className="flex flex-wrap place-content-center place-items-center gap-1">
|
||||
<p className="pr-1 font-headers font-bold">{title}:</p>
|
||||
{filterHasAttributes(recorders, ["attributes"]).map((recorder) => (
|
||||
<RecorderChip key={recorder.attributes.anonymous_code} recorder={recorder.attributes} />
|
||||
<RecorderChip key={recorder.attributes.username} username={recorder.attributes.username} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
@ -24,7 +24,7 @@ import {
|
||||
} from "shared/meilisearch-graphql-typings/meiliTypes";
|
||||
import { getVideoThumbnailURL } from "helpers/videos";
|
||||
import { UpPressable } from "components/Containers/UpPressable";
|
||||
import { prettyItemSubType, prettySlug } from "helpers/formatters";
|
||||
import { prettySlug } from "helpers/formatters";
|
||||
import { Ico } from "components/Ico";
|
||||
import { useFormat } from "hooks/useFormat";
|
||||
|
||||
@ -52,7 +52,14 @@ interface MultiResult {
|
||||
export const SearchPopup = (): JSX.Element => {
|
||||
const [isSearchOpened, setSearchOpened] = useAtomPair(atoms.layout.searchOpened);
|
||||
const [query, setQuery] = useState("");
|
||||
const { format } = useFormat();
|
||||
const {
|
||||
format,
|
||||
formatCategory,
|
||||
formatContentType,
|
||||
formatWikiTag,
|
||||
formatLibraryItemSubType,
|
||||
formatWeaponType,
|
||||
} = useFormat();
|
||||
const [multiResult, setMultiResult] = useState<MultiResult>({});
|
||||
|
||||
const fetchSearchResults = useCallback((q: string) => {
|
||||
@ -243,11 +250,11 @@ export const SearchPopup = (): JSX.Element => {
|
||||
keepInfoVisible
|
||||
topChips={
|
||||
item.metadata && item.metadata.length > 0 && item.metadata[0]
|
||||
? [prettyItemSubType(item.metadata[0])]
|
||||
? [formatLibraryItemSubType(item.metadata[0])]
|
||||
: []
|
||||
}
|
||||
bottomChips={item.categories?.data.map(
|
||||
(category) => category.attributes?.short ?? ""
|
||||
bottomChips={filterHasAttributes(item.categories?.data, ["attributes"]).map(
|
||||
(category) => formatCategory(category.attributes.slug)
|
||||
)}
|
||||
metadata={{
|
||||
releaseDate: item.release_date,
|
||||
@ -288,15 +295,11 @@ export const SearchPopup = (): JSX.Element => {
|
||||
thumbnailForceAspectRatio
|
||||
topChips={
|
||||
item.type?.data?.attributes
|
||||
? [
|
||||
item.type.data.attributes.titles?.[0]
|
||||
? item.type.data.attributes.titles[0]?.title
|
||||
: prettySlug(item.type.data.attributes.slug),
|
||||
]
|
||||
? [formatContentType(item.type.data.attributes.slug)]
|
||||
: undefined
|
||||
}
|
||||
bottomChips={item.categories?.data.map(
|
||||
(category) => category.attributes?.short ?? ""
|
||||
bottomChips={filterHasAttributes(item.categories?.data, ["attributes"]).map(
|
||||
(category) => formatCategory(category.attributes.slug)
|
||||
)}
|
||||
keepInfoVisible
|
||||
/>
|
||||
@ -345,11 +348,11 @@ export const SearchPopup = (): JSX.Element => {
|
||||
thumbnailRounded
|
||||
thumbnailForceAspectRatio
|
||||
keepInfoVisible
|
||||
topChips={filterHasAttributes(item.tags?.data, ["attributes"]).map(
|
||||
(tag) => tag.attributes.titles?.[0]?.title ?? prettySlug(tag.attributes.slug)
|
||||
topChips={filterHasAttributes(item.tags?.data, ["attributes"]).map((tag) =>
|
||||
formatWikiTag(tag.attributes.slug)
|
||||
)}
|
||||
bottomChips={filterHasAttributes(item.categories?.data, ["attributes"]).map(
|
||||
(category) => category.attributes.short
|
||||
(category) => formatCategory(category.attributes.slug)
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
@ -384,8 +387,8 @@ export const SearchPopup = (): JSX.Element => {
|
||||
thumbnailAspectRatio="3/2"
|
||||
thumbnailForceAspectRatio
|
||||
keepInfoVisible
|
||||
bottomChips={item.categories?.data.map(
|
||||
(category) => category.attributes?.short ?? ""
|
||||
bottomChips={filterHasAttributes(item.categories?.data, ["attributes"]).map(
|
||||
(category) => formatCategory(category.attributes.slug)
|
||||
)}
|
||||
metadata={{
|
||||
releaseDate: item.date,
|
||||
@ -466,11 +469,11 @@ export const SearchPopup = (): JSX.Element => {
|
||||
keepInfoVisible
|
||||
topChips={
|
||||
item.type?.data?.attributes?.slug
|
||||
? [prettySlug(item.type.data.attributes.slug)]
|
||||
? [formatWeaponType(item.type.data.attributes.slug)]
|
||||
: undefined
|
||||
}
|
||||
bottomChips={filterHasAttributes(item.categories, ["attributes.short"]).map(
|
||||
(category) => category.attributes.short
|
||||
bottomChips={filterHasAttributes(item.categories, ["attributes"]).map(
|
||||
(category) => formatCategory(category.attributes.slug)
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
|
@ -7,13 +7,14 @@ import { SubPanel } from "./Containers/SubPanel";
|
||||
import { ThumbnailHeader } from "./ThumbnailHeader";
|
||||
import { useSmartLanguage } from "hooks/useSmartLanguage";
|
||||
import { PostWithTranslations } from "types/types";
|
||||
import { isDefined } from "helpers/asserts";
|
||||
import { filterHasAttributes, isDefined } from "helpers/asserts";
|
||||
import { prettySlug } from "helpers/formatters";
|
||||
import { useAtomGetter, useAtomSetter } from "helpers/atoms";
|
||||
import { atoms } from "contexts/atoms";
|
||||
import { ElementsSeparator } from "helpers/component";
|
||||
import { HorizontalLine } from "components/HorizontalLine";
|
||||
import { Credits } from "components/Credits";
|
||||
import { useFormat } from "hooks/useFormat";
|
||||
|
||||
/*
|
||||
* ╭─────────────╮
|
||||
@ -48,6 +49,7 @@ export const PostPage = ({
|
||||
displayTitle = true,
|
||||
...otherProps
|
||||
}: Props): JSX.Element => {
|
||||
const { formatCategory } = useFormat();
|
||||
const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened);
|
||||
const is1ColumnLayout = useAtomGetter(atoms.containerQueries.is1ColumnLayout);
|
||||
|
||||
@ -104,7 +106,9 @@ export const PostPage = ({
|
||||
thumbnail={thumbnail}
|
||||
title={title}
|
||||
description={excerpt}
|
||||
categories={post.categories}
|
||||
categories={filterHasAttributes(post.categories?.data, ["attributes"]).map((category) =>
|
||||
formatCategory(category.attributes.slug)
|
||||
)}
|
||||
languageSwitcher={
|
||||
languageSwitcherProps.locales.size > 1 ? (
|
||||
<LanguageSwitcher {...languageSwitcherProps} />
|
||||
|
@ -3,10 +3,12 @@ import { Img } from "./Img";
|
||||
import { Markdawn } from "./Markdown/Markdawn";
|
||||
import { ToolTip } from "./ToolTip";
|
||||
import { Chip } from "components/Chip";
|
||||
import { RecorderChipFragment } from "graphql/generated";
|
||||
import { ImageQuality } from "helpers/img";
|
||||
import { filterHasAttributes } from "helpers/asserts";
|
||||
import { filterHasAttributes, isUndefined } from "helpers/asserts";
|
||||
import { useFormat } from "hooks/useFormat";
|
||||
import { useAtomGetter } from "helpers/atoms";
|
||||
import { atoms } from "contexts/atoms";
|
||||
import { useSmartLanguage } from "hooks/useSmartLanguage";
|
||||
|
||||
/*
|
||||
* ╭─────────────╮
|
||||
@ -14,14 +16,22 @@ import { useFormat } from "hooks/useFormat";
|
||||
*/
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
recorder: RecorderChipFragment;
|
||||
username: string;
|
||||
}
|
||||
|
||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
|
||||
export const RecorderChip = ({ recorder }: Props): JSX.Element => {
|
||||
export const RecorderChip = ({ username }: Props): JSX.Element => {
|
||||
const { format } = useFormat();
|
||||
const recorders = useAtomGetter(atoms.localData.recorders);
|
||||
const recorder = recorders.find((elem) => elem.attributes?.username === username)?.attributes;
|
||||
|
||||
const [selectedBioTranslation] = useSmartLanguage({
|
||||
items: recorder?.bio ?? [],
|
||||
languageExtractor: (bio) => bio.language?.data?.attributes?.code,
|
||||
});
|
||||
|
||||
if (isUndefined(recorder)) return <></>;
|
||||
|
||||
return (
|
||||
<ToolTip
|
||||
@ -55,7 +65,7 @@ export const RecorderChip = ({ recorder }: Props): JSX.Element => {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{recorder.bio?.[0] && <Markdawn text={recorder.bio[0].bio ?? ""} />}
|
||||
{selectedBioTranslation?.bio && <Markdawn text={selectedBioTranslation.bio} />}
|
||||
</div>
|
||||
}
|
||||
placement="top">
|
||||
|
@ -2,10 +2,9 @@ import { Chip } from "components/Chip";
|
||||
import { Img } from "components/Img";
|
||||
import { InsetBox } from "components/Containers/InsetBox";
|
||||
import { Markdawn } from "components/Markdown/Markdawn";
|
||||
import { GetContentTextQuery, UploadImageFragment } from "graphql/generated";
|
||||
import { prettyInlineTitle, prettySlug, slugify } from "helpers/formatters";
|
||||
import { UploadImageFragment } from "graphql/generated";
|
||||
import { prettyInlineTitle, slugify } from "helpers/formatters";
|
||||
import { ImageQuality } from "helpers/img";
|
||||
import { filterHasAttributes } from "helpers/asserts";
|
||||
import { useAtomGetter } from "helpers/atoms";
|
||||
import { atoms } from "contexts/atoms";
|
||||
import { useFormat } from "hooks/useFormat";
|
||||
@ -20,12 +19,8 @@ interface Props {
|
||||
title: string | null | undefined;
|
||||
subtitle?: string | null | undefined;
|
||||
description?: string | null | undefined;
|
||||
type?: NonNullable<
|
||||
NonNullable<GetContentTextQuery["contents"]>["data"][number]["attributes"]
|
||||
>["type"];
|
||||
categories?: NonNullable<
|
||||
NonNullable<GetContentTextQuery["contents"]>["data"][number]["attributes"]
|
||||
>["categories"];
|
||||
type?: string;
|
||||
categories?: string[];
|
||||
thumbnail?: UploadImageFragment | null | undefined;
|
||||
className?: string;
|
||||
languageSwitcher?: JSX.Element;
|
||||
@ -72,25 +67,21 @@ export const ThumbnailHeader = ({
|
||||
</div>
|
||||
|
||||
<div className="flew-wrap flex flex-row place-content-center gap-8">
|
||||
{type?.data?.attributes && (
|
||||
{type && (
|
||||
<div className="flex flex-col place-items-center gap-2">
|
||||
<h3 className="text-xl">{format("type", { count: 1 })}</h3>
|
||||
<div className="flex flex-row flex-wrap">
|
||||
<Chip
|
||||
text={
|
||||
type.data.attributes.titles?.[0]?.title ?? prettySlug(type.data.attributes.slug)
|
||||
}
|
||||
/>
|
||||
<Chip text={type} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{categories && categories.data.length > 0 && (
|
||||
{categories && categories.length > 0 && (
|
||||
<div className="flex flex-col place-items-center gap-2">
|
||||
<h3 className="text-xl">{format("category", { count: categories.data.length })}</h3>
|
||||
<h3 className="text-xl">{format("category", { count: categories.length })}</h3>
|
||||
<div className="flex flex-row flex-wrap place-content-center gap-2">
|
||||
{filterHasAttributes(categories.data, ["attributes", "id"]).map((category) => (
|
||||
<Chip key={category.id} text={category.attributes.name} />
|
||||
{categories.map((category) => (
|
||||
<Chip key={category} text={category} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -5,7 +5,7 @@ import { userAgent } from "contexts/userAgent";
|
||||
import { atomPairing } from "helpers/atoms";
|
||||
import { settings } from "contexts/settings";
|
||||
import { UploadImageFragment } from "graphql/generated";
|
||||
import { Languages, Currencies, Langui } from "helpers/localData";
|
||||
import { Languages, Currencies, Langui, Recorders, TypesTranslations } from "helpers/localData";
|
||||
|
||||
/* [ LOCAL DATA ATOMS ] */
|
||||
|
||||
@ -13,12 +13,29 @@ const languages = atomPairing(atom<Languages>([]));
|
||||
const currencies = atomPairing(atom<Currencies>([]));
|
||||
const langui = atomPairing(atom<Langui>({}));
|
||||
const fallbackLangui = atomPairing(atom<Langui>({}));
|
||||
const recorders = atomPairing(atom<Recorders>([]));
|
||||
const typesTranslations = atomPairing(
|
||||
atom<TypesTranslations>({
|
||||
audioSubtypes: [],
|
||||
categories: [],
|
||||
contentTypes: [],
|
||||
gamePlatforms: [],
|
||||
groupSubtypes: [],
|
||||
metadataTypes: [],
|
||||
textualSubtypes: [],
|
||||
videoSubtypes: [],
|
||||
wikiPagesTags: [],
|
||||
weaponTypes: [],
|
||||
})
|
||||
);
|
||||
|
||||
const localData = {
|
||||
languages: languages[0],
|
||||
currencies: currencies[0],
|
||||
langui: langui[0],
|
||||
fallbackLangui: fallbackLangui[0],
|
||||
recorders: recorders[0],
|
||||
typesTranslations: typesTranslations[0],
|
||||
};
|
||||
|
||||
/* [ LIGHTBOX ATOMS ] */
|
||||
@ -70,5 +87,5 @@ export const atoms = {
|
||||
// Do not import outside of the "contexts" folder
|
||||
export const internalAtoms = {
|
||||
lightBox: lightBoxAtom,
|
||||
localData: { languages, currencies, langui, fallbackLangui },
|
||||
localData: { languages, currencies, langui, fallbackLangui, recorders, typesTranslations },
|
||||
};
|
||||
|
@ -7,10 +7,17 @@ import {
|
||||
LocalDataGetWebsiteInterfacesQuery,
|
||||
LocalDataGetCurrenciesQuery,
|
||||
LocalDataGetLanguagesQuery,
|
||||
LocalDataGetRecordersQuery,
|
||||
} from "graphql/generated";
|
||||
import { LocalDataFile } from "graphql/fetchLocalData";
|
||||
import { internalAtoms } from "contexts/atoms";
|
||||
import { processLanguages, processCurrencies, processLangui } from "helpers/localData";
|
||||
import {
|
||||
processLanguages,
|
||||
processCurrencies,
|
||||
processLangui,
|
||||
processRecorders,
|
||||
processTypesTranslations,
|
||||
} from "helpers/localData";
|
||||
import { getLogger } from "helpers/logger";
|
||||
|
||||
const getFileName = (name: LocalDataFile): string => `/local-data/${name}.json`;
|
||||
@ -21,6 +28,8 @@ export const useLocalData = (): void => {
|
||||
const setCurrencies = useAtomSetter(internalAtoms.localData.currencies);
|
||||
const setLangui = useAtomSetter(internalAtoms.localData.langui);
|
||||
const setFallbackLangui = useAtomSetter(internalAtoms.localData.fallbackLangui);
|
||||
const setRecorders = useAtomSetter(internalAtoms.localData.recorders);
|
||||
const setTypesTranslations = useAtomSetter(internalAtoms.localData.typesTranslations);
|
||||
|
||||
const { locale } = useRouter();
|
||||
const { data: rawLanguages } = useFetch<LocalDataGetLanguagesQuery>(getFileName("languages"));
|
||||
@ -28,6 +37,10 @@ export const useLocalData = (): void => {
|
||||
const { data: rawLangui } = useFetch<LocalDataGetWebsiteInterfacesQuery>(
|
||||
getFileName("websiteInterfaces")
|
||||
);
|
||||
const { data: rawRecorders } = useFetch<LocalDataGetRecordersQuery>(getFileName("recorders"));
|
||||
const { data: rawTypesTranslations } = useFetch<LocalDataGetRecordersQuery>(
|
||||
getFileName("typesTranslations")
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
logger.log("Refresh languages");
|
||||
@ -48,4 +61,14 @@ export const useLocalData = (): void => {
|
||||
logger.log("Refresh fallback langui");
|
||||
setFallbackLangui(processLangui(rawLangui, "en"));
|
||||
}, [rawLangui, setFallbackLangui]);
|
||||
|
||||
useEffect(() => {
|
||||
logger.log("Refresh recorders");
|
||||
setRecorders(processRecorders(rawRecorders));
|
||||
}, [rawRecorders, setRecorders]);
|
||||
|
||||
useEffect(() => {
|
||||
logger.log("Refresh types translations");
|
||||
setTypesTranslations(processTypesTranslations(rawTypesTranslations));
|
||||
}, [rawTypesTranslations, setTypesTranslations]);
|
||||
};
|
||||
|
@ -3,8 +3,16 @@ import { resolve } from "path";
|
||||
import { readFileSync, writeFileSync } from "fs";
|
||||
import { config } from "dotenv";
|
||||
import { getReadySdk } from "./sdk";
|
||||
import { LocalDataGetWebsiteInterfacesQuery } from "./generated";
|
||||
import { processLangui, Langui } from "helpers/localData";
|
||||
import {
|
||||
LocalDataGetTypesTranslationsQuery,
|
||||
LocalDataGetWebsiteInterfacesQuery,
|
||||
} from "./generated";
|
||||
import {
|
||||
processLangui,
|
||||
Langui,
|
||||
TypesTranslations,
|
||||
processTypesTranslations,
|
||||
} from "helpers/localData";
|
||||
import { getLogger } from "helpers/logger";
|
||||
|
||||
config({ path: resolve(process.cwd(), ".env.local") });
|
||||
@ -12,7 +20,7 @@ config({ path: resolve(process.cwd(), ".env.local") });
|
||||
const LOCAL_DATA_FOLDER = `${process.cwd()}/public/local-data`;
|
||||
const logger = getLogger("💽 [Local Data]", "server");
|
||||
|
||||
const writeLocalData = (name: LocalDataFile, localData: unknown) => {
|
||||
const writeLocalData = (name: LocalDataFile, localData: object) => {
|
||||
const path = `${LOCAL_DATA_FOLDER}/${name}.json`;
|
||||
writeFileSync(path, JSON.stringify(localData), { encoding: "utf-8" });
|
||||
logger.log(`${name}.json has been written`);
|
||||
@ -23,22 +31,58 @@ const readLocalData = <T>(name: LocalDataFile): T => {
|
||||
return JSON.parse(readFileSync(path, { encoding: "utf8" }));
|
||||
};
|
||||
|
||||
export const fetchLocalData = async (): Promise<void> => {
|
||||
export const fetchWebsiteInterfaces = async (): Promise<void> => {
|
||||
const sdk = getReadySdk();
|
||||
writeLocalData("websiteInterfaces", await sdk.localDataGetWebsiteInterfaces());
|
||||
};
|
||||
|
||||
export const fetchCurrencies = async (): Promise<void> => {
|
||||
const sdk = getReadySdk();
|
||||
writeLocalData("currencies", await sdk.localDataGetCurrencies());
|
||||
};
|
||||
|
||||
export const fetchLanguages = async (): Promise<void> => {
|
||||
const sdk = getReadySdk();
|
||||
writeLocalData("languages", await sdk.localDataGetLanguages());
|
||||
};
|
||||
|
||||
export const fetchRecorders = async (): Promise<void> => {
|
||||
const sdk = getReadySdk();
|
||||
writeLocalData("recorders", await sdk.localDataGetRecorders());
|
||||
};
|
||||
|
||||
export const fetchTypesTranslations = async (): Promise<void> => {
|
||||
const sdk = getReadySdk();
|
||||
writeLocalData("typesTranslations", await sdk.localDataGetTypesTranslations());
|
||||
};
|
||||
|
||||
const fetchLocalData = async (): Promise<void> => {
|
||||
await fetchWebsiteInterfaces();
|
||||
await fetchCurrencies();
|
||||
await fetchLanguages();
|
||||
await fetchRecorders();
|
||||
await fetchTypesTranslations();
|
||||
};
|
||||
|
||||
if (process.argv[2] === "--esrun") {
|
||||
fetchLocalData();
|
||||
}
|
||||
|
||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
|
||||
export type LocalDataFile = "currencies" | "languages" | "websiteInterfaces";
|
||||
export type LocalDataFile =
|
||||
| "currencies"
|
||||
| "languages"
|
||||
| "recorders"
|
||||
| "typesTranslations"
|
||||
| "websiteInterfaces";
|
||||
|
||||
export const getLangui = (locale: string | undefined): Langui => {
|
||||
export const getLangui = (locale: string): Langui => {
|
||||
const websiteInterfaces = readLocalData<LocalDataGetWebsiteInterfacesQuery>("websiteInterfaces");
|
||||
return processLangui(websiteInterfaces, locale);
|
||||
};
|
||||
|
||||
export const getTypesTranslations = (): TypesTranslations => {
|
||||
const typesTranslations = readLocalData<LocalDataGetTypesTranslationsQuery>("typesTranslations");
|
||||
return processTypesTranslations(typesTranslations);
|
||||
};
|
||||
|
@ -1,23 +0,0 @@
|
||||
fragment recorderChip on Recorder {
|
||||
username
|
||||
anonymize
|
||||
anonymous_code
|
||||
pronouns
|
||||
bio(filters: { language: { code: { eq: $language_code } } }) {
|
||||
bio
|
||||
}
|
||||
languages(pagination: { limit: -1 }) {
|
||||
data {
|
||||
attributes {
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
avatar {
|
||||
data {
|
||||
attributes {
|
||||
...uploadImage
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -14,9 +14,8 @@ fragment relatedContentPreview on Content {
|
||||
}
|
||||
categories(pagination: { limit: -1 }) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
short
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -24,9 +23,6 @@ fragment relatedContentPreview on Content {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,10 +17,9 @@ export const getPostStaticProps =
|
||||
(slug: string): GetStaticProps =>
|
||||
async (context) => {
|
||||
const sdk = getReadySdk();
|
||||
const { format } = getFormat(context.locale);
|
||||
const { format, formatCategory } = getFormat(context.locale);
|
||||
const post = await sdk.getPost({
|
||||
slug: slug,
|
||||
language_code: context.locale ?? "en",
|
||||
});
|
||||
|
||||
if (!post.posts?.data[0]?.attributes?.translations || !context.locale || !context.locales) {
|
||||
@ -40,7 +39,7 @@ export const getPostStaticProps =
|
||||
[format("category", { count: Infinity })]: filterHasAttributes(
|
||||
post.posts.data[0].attributes.categories?.data,
|
||||
["attributes"]
|
||||
).map((category) => category.attributes.short),
|
||||
).map((category) => formatCategory(category.attributes.slug)),
|
||||
});
|
||||
|
||||
const thumbnail =
|
||||
|
@ -1,4 +1,4 @@
|
||||
query getChronicle($slug: String, $language_code: String) {
|
||||
query getChronicle($slug: String) {
|
||||
chronicles(filters: { slug: { eq: $slug } }) {
|
||||
data {
|
||||
attributes {
|
||||
@ -53,21 +53,21 @@ query getChronicle($slug: String, $language_code: String) {
|
||||
authors {
|
||||
data {
|
||||
attributes {
|
||||
...recorderChip
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
translators {
|
||||
data {
|
||||
attributes {
|
||||
...recorderChip
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
proofreaders {
|
||||
data {
|
||||
attributes {
|
||||
...recorderChip
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -80,10 +80,8 @@ query getChronicle($slug: String, $language_code: String) {
|
||||
slug
|
||||
categories(pagination: { limit: -1 }) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
name
|
||||
short
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -91,9 +89,6 @@ query getChronicle($slug: String, $language_code: String) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -123,7 +118,7 @@ query getChronicle($slug: String, $language_code: String) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
...recorderChip
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -131,7 +126,7 @@ query getChronicle($slug: String, $language_code: String) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
...recorderChip
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -139,7 +134,7 @@ query getChronicle($slug: String, $language_code: String) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
...recorderChip
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
query getContentText($slug: String, $language_code: String) {
|
||||
query getContentText($slug: String) {
|
||||
contents(filters: { slug: { eq: $slug } }) {
|
||||
data {
|
||||
id
|
||||
@ -6,10 +6,8 @@ query getContentText($slug: String, $language_code: String) {
|
||||
slug
|
||||
categories(pagination: { limit: -1 }) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
name
|
||||
short
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -17,9 +15,6 @@ query getContentText($slug: String, $language_code: String) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -53,10 +48,8 @@ query getContentText($slug: String, $language_code: String) {
|
||||
}
|
||||
categories(pagination: { limit: -1 }) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
name
|
||||
short
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -67,19 +60,15 @@ query getContentText($slug: String, $language_code: String) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
... on ComponentMetadataGame {
|
||||
platforms(pagination: { limit: -1 }) {
|
||||
platform {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
short
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -89,9 +78,6 @@ query getContentText($slug: String, $language_code: String) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -101,9 +87,6 @@ query getContentText($slug: String, $language_code: String) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -113,9 +96,6 @@ query getContentText($slug: String, $language_code: String) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -123,9 +103,6 @@ query getContentText($slug: String, $language_code: String) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -163,7 +140,7 @@ query getContentText($slug: String, $language_code: String) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
...recorderChip
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -171,7 +148,7 @@ query getContentText($slug: String, $language_code: String) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
...recorderChip
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -179,7 +156,7 @@ query getContentText($slug: String, $language_code: String) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
...recorderChip
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -198,7 +175,7 @@ query getContentText($slug: String, $language_code: String) {
|
||||
subbers(pagination: { limit: -1 }) {
|
||||
data {
|
||||
attributes {
|
||||
...recorderChip
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -216,7 +193,7 @@ query getContentText($slug: String, $language_code: String) {
|
||||
dubbers(pagination: { limit: -1 }) {
|
||||
data {
|
||||
attributes {
|
||||
...recorderChip
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
query getContentsFolder($slug: String, $language_code: String) {
|
||||
query getContentsFolder($slug: String) {
|
||||
contentsFolders(filters: { slug: { eq: $slug } }) {
|
||||
data {
|
||||
attributes {
|
||||
@ -22,10 +22,8 @@ query getContentsFolder($slug: String, $language_code: String) {
|
||||
}
|
||||
categories(pagination: { limit: -1 }) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
name
|
||||
short
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -33,9 +31,6 @@ query getContentsFolder($slug: String, $language_code: String) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
query getLibraryItem($slug: String, $language_code: String) {
|
||||
query getLibraryItem($slug: String) {
|
||||
libraryItems(filters: { slug: { eq: $slug } }) {
|
||||
data {
|
||||
id
|
||||
@ -33,10 +33,8 @@ query getLibraryItem($slug: String, $language_code: String) {
|
||||
}
|
||||
categories(pagination: { limit: -1 }) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
name
|
||||
short
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -58,9 +56,6 @@ query getLibraryItem($slug: String, $language_code: String) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -81,19 +76,15 @@ query getLibraryItem($slug: String, $language_code: String) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
... on ComponentMetadataGame {
|
||||
platforms(pagination: { limit: -1 }) {
|
||||
platform {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
short
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -127,9 +118,6 @@ query getLibraryItem($slug: String, $language_code: String) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -144,9 +132,6 @@ query getLibraryItem($slug: String, $language_code: String) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -154,9 +139,6 @@ query getLibraryItem($slug: String, $language_code: String) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -194,10 +176,8 @@ query getLibraryItem($slug: String, $language_code: String) {
|
||||
}
|
||||
categories(pagination: { limit: -1 }) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
name
|
||||
short
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -208,19 +188,16 @@ query getLibraryItem($slug: String, $language_code: String) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
... on ComponentMetadataGame {
|
||||
platforms {
|
||||
platform {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
short
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -230,9 +207,6 @@ query getLibraryItem($slug: String, $language_code: String) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -242,9 +216,6 @@ query getLibraryItem($slug: String, $language_code: String) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -254,9 +225,6 @@ query getLibraryItem($slug: String, $language_code: String) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -264,9 +232,6 @@ query getLibraryItem($slug: String, $language_code: String) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -317,10 +282,8 @@ query getLibraryItem($slug: String, $language_code: String) {
|
||||
slug
|
||||
categories(pagination: { limit: -1 }) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
name
|
||||
short
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -328,9 +291,6 @@ query getLibraryItem($slug: String, $language_code: String) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
query getLibraryItemScans($slug: String, $language_code: String) {
|
||||
query getLibraryItemScans($slug: String) {
|
||||
libraryItems(filters: { slug: { eq: $slug } }) {
|
||||
data {
|
||||
id
|
||||
@ -27,7 +27,7 @@ query getLibraryItemScans($slug: String, $language_code: String) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
...recorderChip
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -35,7 +35,7 @@ query getLibraryItemScans($slug: String, $language_code: String) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
...recorderChip
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -43,7 +43,7 @@ query getLibraryItemScans($slug: String, $language_code: String) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
...recorderChip
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -156,10 +156,8 @@ query getLibraryItemScans($slug: String, $language_code: String) {
|
||||
}
|
||||
categories(pagination: { limit: -1 }) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
name
|
||||
short
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -171,19 +169,16 @@ query getLibraryItemScans($slug: String, $language_code: String) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
... on ComponentMetadataGame {
|
||||
platforms {
|
||||
platform {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
short
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -193,9 +188,6 @@ query getLibraryItemScans($slug: String, $language_code: String) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -205,9 +197,6 @@ query getLibraryItemScans($slug: String, $language_code: String) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -217,9 +206,6 @@ query getLibraryItemScans($slug: String, $language_code: String) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -227,9 +213,6 @@ query getLibraryItemScans($slug: String, $language_code: String) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -290,7 +273,7 @@ query getLibraryItemScans($slug: String, $language_code: String) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
...recorderChip
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -298,7 +281,7 @@ query getLibraryItemScans($slug: String, $language_code: String) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
...recorderChip
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -306,7 +289,7 @@ query getLibraryItemScans($slug: String, $language_code: String) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
...recorderChip
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
query getPost($slug: String, $language_code: String) {
|
||||
query getPost($slug: String) {
|
||||
posts(filters: { slug: { eq: $slug } }) {
|
||||
data {
|
||||
id
|
||||
@ -12,16 +12,14 @@ query getPost($slug: String, $language_code: String) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
...recorderChip
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
categories(pagination: { limit: -1 }) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
name
|
||||
short
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,9 +23,8 @@ query getVideo($uid: String) {
|
||||
}
|
||||
categories(pagination: { limit: -1 }) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
short
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
query getWeapon($slug: String, $language_code: String) {
|
||||
query getWeapon($slug: String) {
|
||||
weaponStories(filters: { slug: { eq: $slug } }) {
|
||||
data {
|
||||
attributes {
|
||||
@ -7,10 +7,8 @@ query getWeapon($slug: String, $language_code: String) {
|
||||
id
|
||||
categories(pagination: { limit: -1 }) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
name
|
||||
short
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -57,16 +55,6 @@ fragment sharedWeaponFragment on WeaponStory {
|
||||
id
|
||||
attributes {
|
||||
slug
|
||||
translations(filters: { language: { code: { eq: $language_code } } }) {
|
||||
name
|
||||
language {
|
||||
data {
|
||||
attributes {
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
query getWikiPage($slug: String, $language_code: String) {
|
||||
query getWikiPage($slug: String) {
|
||||
wikiPages(filters: { slug: { eq: $slug } }) {
|
||||
data {
|
||||
id
|
||||
@ -13,21 +13,15 @@ query getWikiPage($slug: String, $language_code: String) {
|
||||
}
|
||||
categories(pagination: { limit: -1 }) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
name
|
||||
short
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
tags {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -58,7 +52,7 @@ query getWikiPage($slug: String, $language_code: String) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
...recorderChip
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -66,7 +60,7 @@ query getWikiPage($slug: String, $language_code: String) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
...recorderChip
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -74,7 +68,7 @@ query getWikiPage($slug: String, $language_code: String) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
...recorderChip
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -90,10 +84,8 @@ query getWikiPage($slug: String, $language_code: String) {
|
||||
}
|
||||
categories(pagination: { limit: -1 }) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
name
|
||||
short
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,36 @@
|
||||
query localDataGetRecorders {
|
||||
recorders(pagination: { limit: -1 }) {
|
||||
data {
|
||||
attributes {
|
||||
username
|
||||
anonymize
|
||||
anonymous_code
|
||||
pronouns
|
||||
bio(pagination: { limit: -1 }) {
|
||||
bio
|
||||
language {
|
||||
data {
|
||||
attributes {
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
languages(pagination: { limit: -1 }) {
|
||||
data {
|
||||
attributes {
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
avatar {
|
||||
data {
|
||||
attributes {
|
||||
...uploadImage
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,183 @@
|
||||
query localDataGetTypesTranslations {
|
||||
metadataTypes(pagination: { limit: -1 }) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles {
|
||||
language {
|
||||
data {
|
||||
attributes {
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
audioSubtypes(pagination: { limit: -1 }) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles {
|
||||
language {
|
||||
data {
|
||||
attributes {
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
videoSubtypes(pagination: { limit: -1 }) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles {
|
||||
language {
|
||||
data {
|
||||
attributes {
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
textualSubtypes(pagination: { limit: -1 }) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles {
|
||||
language {
|
||||
data {
|
||||
attributes {
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
groupSubtypes(pagination: { limit: -1 }) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles {
|
||||
language {
|
||||
data {
|
||||
attributes {
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gamePlatforms(pagination: { limit: -1 }) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles {
|
||||
language {
|
||||
data {
|
||||
attributes {
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
title
|
||||
short
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
contentTypes(pagination: { limit: -1 }) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles {
|
||||
language {
|
||||
data {
|
||||
attributes {
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wikiPagesTags(pagination: { limit: -1 }) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles {
|
||||
language {
|
||||
data {
|
||||
attributes {
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
weaponStoryTypes(pagination: { limit: -1 }) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
translations {
|
||||
language {
|
||||
data {
|
||||
attributes {
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
categories(pagination: { limit: -1 }) {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles {
|
||||
language {
|
||||
data {
|
||||
attributes {
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
title
|
||||
short
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -114,11 +114,11 @@ query localDataGetWebsiteInterfaces {
|
||||
previous_content
|
||||
followup_content
|
||||
videos
|
||||
view_on
|
||||
view_on_x
|
||||
channel
|
||||
subscribers
|
||||
description
|
||||
available_at
|
||||
available_at_x
|
||||
want_it
|
||||
have_it
|
||||
source
|
||||
|
@ -62,135 +62,6 @@ export const prettyInlineTitle = (
|
||||
return result;
|
||||
};
|
||||
|
||||
export const prettyItemSubType = (
|
||||
metadata:
|
||||
| {
|
||||
__typename: "ComponentMetadataAudio";
|
||||
subtype?: {
|
||||
data?: {
|
||||
attributes?: {
|
||||
slug: string;
|
||||
titles?:
|
||||
| ({
|
||||
title: string;
|
||||
} | null)[]
|
||||
| null;
|
||||
} | null;
|
||||
} | null;
|
||||
} | null;
|
||||
}
|
||||
| {
|
||||
__typename: "ComponentMetadataBooks";
|
||||
subtype?: {
|
||||
data?: {
|
||||
attributes?: {
|
||||
slug: string;
|
||||
titles?:
|
||||
| ({
|
||||
title: string;
|
||||
} | null)[]
|
||||
| null;
|
||||
} | null;
|
||||
} | null;
|
||||
} | null;
|
||||
}
|
||||
| {
|
||||
__typename: "ComponentMetadataGame";
|
||||
platforms?: {
|
||||
data: {
|
||||
id?: string | null;
|
||||
attributes?: {
|
||||
short: string;
|
||||
} | null;
|
||||
}[];
|
||||
} | null;
|
||||
}
|
||||
| {
|
||||
__typename: "ComponentMetadataGroup";
|
||||
subtype?: {
|
||||
data?: {
|
||||
attributes?: {
|
||||
slug: string;
|
||||
titles?:
|
||||
| ({
|
||||
title: string;
|
||||
} | null)[]
|
||||
| null;
|
||||
} | null;
|
||||
} | null;
|
||||
} | null;
|
||||
subitems_type?: {
|
||||
data?: {
|
||||
attributes?: {
|
||||
slug: string;
|
||||
titles?:
|
||||
| ({
|
||||
title: string;
|
||||
} | null)[]
|
||||
| null;
|
||||
} | null;
|
||||
} | null;
|
||||
} | null;
|
||||
}
|
||||
| {
|
||||
__typename: "ComponentMetadataVideo";
|
||||
subtype?: {
|
||||
data?: {
|
||||
attributes?: {
|
||||
slug: string;
|
||||
titles?:
|
||||
| ({
|
||||
title: string;
|
||||
} | null)[]
|
||||
| null;
|
||||
} | null;
|
||||
} | null;
|
||||
} | null;
|
||||
}
|
||||
| { __typename: "ComponentMetadataOther" }
|
||||
| { __typename: "Error" }
|
||||
| null
|
||||
): string => {
|
||||
if (metadata) {
|
||||
switch (metadata.__typename) {
|
||||
case "ComponentMetadataAudio":
|
||||
case "ComponentMetadataBooks":
|
||||
case "ComponentMetadataVideo":
|
||||
return metadata.subtype?.data?.attributes?.titles &&
|
||||
metadata.subtype.data.attributes.titles.length > 0 &&
|
||||
metadata.subtype.data.attributes.titles[0]
|
||||
? metadata.subtype.data.attributes.titles[0].title
|
||||
: prettySlug(metadata.subtype?.data?.attributes?.slug);
|
||||
case "ComponentMetadataGame":
|
||||
return metadata.platforms?.data &&
|
||||
metadata.platforms.data.length > 0 &&
|
||||
metadata.platforms.data[0]?.attributes
|
||||
? metadata.platforms.data[0].attributes.short
|
||||
: "";
|
||||
case "ComponentMetadataGroup": {
|
||||
const firstPart =
|
||||
metadata.subtype?.data?.attributes?.titles &&
|
||||
metadata.subtype.data.attributes.titles.length > 0 &&
|
||||
metadata.subtype.data.attributes.titles[0]
|
||||
? metadata.subtype.data.attributes.titles[0].title
|
||||
: prettySlug(metadata.subtype?.data?.attributes?.slug);
|
||||
|
||||
const secondPart =
|
||||
metadata.subitems_type?.data?.attributes?.titles &&
|
||||
metadata.subitems_type.data.attributes.titles.length > 0 &&
|
||||
metadata.subitems_type.data.attributes.titles[0]
|
||||
? metadata.subitems_type.data.attributes.titles[0].title
|
||||
: prettySlug(metadata.subitems_type?.data?.attributes?.slug);
|
||||
return `${secondPart} ${firstPart}`;
|
||||
}
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
return "";
|
||||
};
|
||||
/* eslint-enable id-denylist */
|
||||
|
||||
export const prettyShortenNumber = (number: number): string => {
|
||||
if (number > 1_000_000) {
|
||||
return `${(number / 1_000_000).toLocaleString(undefined, {
|
||||
|
@ -2,7 +2,9 @@ import { IntlMessageFormat } from "intl-messageformat";
|
||||
import { LibraryItemMetadataDynamicZone } from "graphql/generated";
|
||||
import { ICUParams } from "graphql/icuParams";
|
||||
import { isDefined, isDefinedAndNotEmpty } from "helpers/asserts";
|
||||
import { getLangui } from "graphql/fetchLocalData";
|
||||
import { getLangui, getTypesTranslations } from "graphql/fetchLocalData";
|
||||
import { prettySlug } from "helpers/formatters";
|
||||
import { LibraryItemMetadata } from "types/types";
|
||||
|
||||
type WordingKey = keyof ICUParams;
|
||||
type LibraryItemType = Exclude<LibraryItemMetadataDynamicZone["__typename"], undefined>;
|
||||
@ -29,18 +31,24 @@ const componentSetsTextsetStatusToWording: Record<
|
||||
};
|
||||
|
||||
export const getFormat = (
|
||||
locale: string | undefined
|
||||
locale: string | undefined = "en"
|
||||
): {
|
||||
format: <K extends WordingKey>(
|
||||
key: K,
|
||||
...values: ICUParams[K] extends never ? [undefined?] : [ICUParams[K]]
|
||||
) => string;
|
||||
formatLibraryItemType: (metadata: { __typename: LibraryItemType }) => string;
|
||||
formatLibraryItemType: (metadata: LibraryItemMetadata) => string;
|
||||
formatLibraryItemSubType: (metadata: LibraryItemMetadata) => string;
|
||||
formatStatusLabel: (status: ContentStatus) => string;
|
||||
formatStatusDescription: (status: ContentStatus) => string;
|
||||
formatCategory: (slug: string, type?: "default" | "full") => string;
|
||||
formatContentType: (slug: string) => string;
|
||||
formatWikiTag: (slug: string) => string;
|
||||
formatWeaponType: (slug: string) => string;
|
||||
} => {
|
||||
const langui = getLangui(locale);
|
||||
const fallbackLangui = getLangui("en");
|
||||
const typesTranslations = getTypesTranslations();
|
||||
|
||||
const format = (
|
||||
key: WordingKey,
|
||||
@ -65,8 +73,90 @@ export const getFormat = (
|
||||
return key;
|
||||
};
|
||||
|
||||
const formatLibraryItemType = (metadata: { __typename: LibraryItemType }): string =>
|
||||
format(componentMetadataToWording[metadata.__typename]);
|
||||
const formatLibraryItemType = (metadata: LibraryItemMetadata): string =>
|
||||
metadata ? format(componentMetadataToWording[metadata.__typename]) : format("other");
|
||||
|
||||
const formatLibraryItemSubType = (metadata: LibraryItemMetadata): string => {
|
||||
switch (metadata?.__typename) {
|
||||
case "ComponentMetadataAudio": {
|
||||
const slug = metadata.subtype?.data?.attributes?.slug;
|
||||
const subtype = typesTranslations.audioSubtypes.find(
|
||||
(type) => type.attributes?.slug === slug
|
||||
);
|
||||
const findTranslation = (givenLocale: string) =>
|
||||
subtype?.attributes?.titles?.find(
|
||||
(translation) => translation?.language?.data?.attributes?.code === givenLocale
|
||||
)?.title;
|
||||
return findTranslation(locale) ?? findTranslation("en") ?? format("other");
|
||||
}
|
||||
|
||||
case "ComponentMetadataBooks": {
|
||||
const slug = metadata.subtype?.data?.attributes?.slug;
|
||||
const subtype = typesTranslations.textualSubtypes.find(
|
||||
(type) => type.attributes?.slug === slug
|
||||
);
|
||||
const findTranslation = (givenLocale: string) =>
|
||||
subtype?.attributes?.titles?.find(
|
||||
(translation) => translation?.language?.data?.attributes?.code === givenLocale
|
||||
)?.title;
|
||||
return findTranslation(locale) ?? findTranslation("en") ?? format("other");
|
||||
}
|
||||
|
||||
case "ComponentMetadataVideo": {
|
||||
const slug = metadata.subtype?.data?.attributes?.slug;
|
||||
const subtype = typesTranslations.videoSubtypes.find(
|
||||
(type) => type.attributes?.slug === slug
|
||||
);
|
||||
const findTranslation = (givenLocale: string) =>
|
||||
subtype?.attributes?.titles?.find(
|
||||
(translation) => translation?.language?.data?.attributes?.code === givenLocale
|
||||
)?.title;
|
||||
return findTranslation(locale) ?? findTranslation("en") ?? format("other");
|
||||
}
|
||||
|
||||
case "ComponentMetadataGame": {
|
||||
const slug = metadata.platform?.data?.attributes?.slug;
|
||||
const subtype = typesTranslations.gamePlatforms.find(
|
||||
(type) => type.attributes?.slug === slug
|
||||
);
|
||||
console.log(slug);
|
||||
const findTranslation = (givenLocale: string) =>
|
||||
subtype?.attributes?.titles?.find(
|
||||
(translation) => translation?.language?.data?.attributes?.code === givenLocale
|
||||
)?.title;
|
||||
return findTranslation(locale) ?? findTranslation("en") ?? format("other");
|
||||
}
|
||||
|
||||
case "ComponentMetadataGroup": {
|
||||
const subItemType = (() => {
|
||||
const subitemTypeSlug = metadata.subitems_type?.data?.attributes?.slug;
|
||||
const subItemTypeTranslations = typesTranslations.metadataTypes.find(
|
||||
(type) => type.attributes?.slug === subitemTypeSlug
|
||||
);
|
||||
const findTranslation = (givenLocale: string) =>
|
||||
subItemTypeTranslations?.attributes?.titles?.find(
|
||||
(translation) => translation?.language?.data?.attributes?.code === givenLocale
|
||||
)?.title;
|
||||
return findTranslation(locale) ?? findTranslation("en") ?? format("other");
|
||||
})();
|
||||
const groupType = (() => {
|
||||
const groupTypeSlug = metadata.subtype?.data?.attributes?.slug;
|
||||
const groupTypeTranslations = typesTranslations.groupSubtypes.find(
|
||||
(type) => type.attributes?.slug === groupTypeSlug
|
||||
);
|
||||
const findTranslation = (givenLocale: string) =>
|
||||
groupTypeTranslations?.attributes?.titles?.find(
|
||||
(translation) => translation?.language?.data?.attributes?.code === givenLocale
|
||||
)?.title;
|
||||
return findTranslation(locale) ?? findTranslation("en") ?? format("other");
|
||||
})();
|
||||
return `${groupType} - ${subItemType}`;
|
||||
}
|
||||
|
||||
default:
|
||||
return format("other");
|
||||
}
|
||||
};
|
||||
|
||||
const formatStatusLabel = (status: ContentStatus): string =>
|
||||
format(componentSetsTextsetStatusToWording[status].label);
|
||||
@ -74,10 +164,65 @@ export const getFormat = (
|
||||
const formatStatusDescription = (status: ContentStatus): string =>
|
||||
format(componentSetsTextsetStatusToWording[status].description);
|
||||
|
||||
const formatCategory = (slug: string, type: "default" | "full" = "default"): string => {
|
||||
const category = typesTranslations.categories.find((cat) => cat.attributes?.slug === slug);
|
||||
if (!category) return prettySlug(slug);
|
||||
const findTranslation = (givenLocale: string): string | null | undefined => {
|
||||
const localeTranslation = category.attributes?.titles?.find(
|
||||
(translation) => translation?.language?.data?.attributes?.code === givenLocale
|
||||
);
|
||||
return type === "default" ? localeTranslation?.title : localeTranslation?.short;
|
||||
};
|
||||
return findTranslation(locale) ?? findTranslation("en") ?? prettySlug(slug);
|
||||
};
|
||||
|
||||
const formatContentType = (slug: string): string => {
|
||||
const contentType = typesTranslations.contentTypes.find(
|
||||
(type) => type.attributes?.slug === slug
|
||||
);
|
||||
if (!contentType) return prettySlug(slug);
|
||||
const findTranslation = (givenLocale: string): string | null | undefined => {
|
||||
const localeTranslation = contentType.attributes?.titles?.find(
|
||||
(translation) => translation?.language?.data?.attributes?.code === givenLocale
|
||||
);
|
||||
return localeTranslation?.title;
|
||||
};
|
||||
return findTranslation(locale) ?? findTranslation("en") ?? prettySlug(slug);
|
||||
};
|
||||
|
||||
const formatWikiTag = (slug: string): string => {
|
||||
const wikiTag = typesTranslations.wikiPagesTags.find((cat) => cat.attributes?.slug === slug);
|
||||
if (!wikiTag) return prettySlug(slug);
|
||||
const findTranslation = (givenLocale: string): string | null | undefined => {
|
||||
const localeTranslation = wikiTag.attributes?.titles?.find(
|
||||
(translation) => translation?.language?.data?.attributes?.code === givenLocale
|
||||
);
|
||||
return localeTranslation?.title;
|
||||
};
|
||||
return findTranslation(locale) ?? findTranslation("en") ?? prettySlug(slug);
|
||||
};
|
||||
|
||||
const formatWeaponType = (slug: string): string => {
|
||||
const weaponType = typesTranslations.weaponTypes.find((type) => type.attributes?.slug === slug);
|
||||
if (!weaponType) return prettySlug(slug);
|
||||
const findTranslation = (givenLocale: string): string | null | undefined => {
|
||||
const localeTranslation = weaponType.attributes?.translations?.find(
|
||||
(translation) => translation?.language?.data?.attributes?.code === givenLocale
|
||||
);
|
||||
return localeTranslation?.name;
|
||||
};
|
||||
return findTranslation(locale) ?? findTranslation("en") ?? prettySlug(slug);
|
||||
};
|
||||
|
||||
return {
|
||||
format,
|
||||
formatLibraryItemType,
|
||||
formatLibraryItemSubType,
|
||||
formatStatusLabel,
|
||||
formatStatusDescription,
|
||||
formatCategory,
|
||||
formatContentType,
|
||||
formatWikiTag,
|
||||
formatWeaponType,
|
||||
};
|
||||
};
|
||||
|
@ -1,6 +1,8 @@
|
||||
import {
|
||||
LocalDataGetCurrenciesQuery,
|
||||
LocalDataGetLanguagesQuery,
|
||||
LocalDataGetRecordersQuery,
|
||||
LocalDataGetTypesTranslationsQuery,
|
||||
LocalDataGetWebsiteInterfacesQuery,
|
||||
} from "graphql/generated";
|
||||
|
||||
@ -45,3 +47,58 @@ export const processLanguages = (languages: LocalDataGetLanguagesQuery | undefin
|
||||
}
|
||||
return languages?.languages?.data ?? [];
|
||||
};
|
||||
|
||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
|
||||
export type Recorders = NonNullable<LocalDataGetRecordersQuery["recorders"]>["data"];
|
||||
|
||||
export const processRecorders = (recorders: LocalDataGetRecordersQuery | undefined): Recorders =>
|
||||
recorders?.recorders?.data ?? [];
|
||||
|
||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
|
||||
export type TypesTranslations = {
|
||||
audioSubtypes: NonNullable<
|
||||
NonNullable<LocalDataGetTypesTranslationsQuery>["audioSubtypes"]
|
||||
>["data"];
|
||||
gamePlatforms: NonNullable<
|
||||
NonNullable<LocalDataGetTypesTranslationsQuery>["gamePlatforms"]
|
||||
>["data"];
|
||||
groupSubtypes: NonNullable<
|
||||
NonNullable<LocalDataGetTypesTranslationsQuery>["groupSubtypes"]
|
||||
>["data"];
|
||||
metadataTypes: NonNullable<
|
||||
NonNullable<LocalDataGetTypesTranslationsQuery>["metadataTypes"]
|
||||
>["data"];
|
||||
textualSubtypes: NonNullable<
|
||||
NonNullable<LocalDataGetTypesTranslationsQuery>["textualSubtypes"]
|
||||
>["data"];
|
||||
videoSubtypes: NonNullable<
|
||||
NonNullable<LocalDataGetTypesTranslationsQuery>["videoSubtypes"]
|
||||
>["data"];
|
||||
contentTypes: NonNullable<
|
||||
NonNullable<LocalDataGetTypesTranslationsQuery>["contentTypes"]
|
||||
>["data"];
|
||||
wikiPagesTags: NonNullable<
|
||||
NonNullable<LocalDataGetTypesTranslationsQuery>["wikiPagesTags"]
|
||||
>["data"];
|
||||
weaponTypes: NonNullable<
|
||||
NonNullable<LocalDataGetTypesTranslationsQuery>["weaponStoryTypes"]
|
||||
>["data"];
|
||||
categories: NonNullable<NonNullable<LocalDataGetTypesTranslationsQuery>["categories"]>["data"];
|
||||
};
|
||||
|
||||
export const processTypesTranslations = (
|
||||
data: LocalDataGetTypesTranslationsQuery | undefined
|
||||
): TypesTranslations => ({
|
||||
audioSubtypes: data?.audioSubtypes?.data ?? [],
|
||||
categories: data?.categories?.data ?? [],
|
||||
contentTypes: data?.contentTypes?.data ?? [],
|
||||
gamePlatforms: data?.gamePlatforms?.data ?? [],
|
||||
groupSubtypes: data?.groupSubtypes?.data ?? [],
|
||||
metadataTypes: data?.metadataTypes?.data ?? [],
|
||||
textualSubtypes: data?.textualSubtypes?.data ?? [],
|
||||
videoSubtypes: data?.videoSubtypes?.data ?? [],
|
||||
weaponTypes: data?.weaponStoryTypes?.data ?? [],
|
||||
wikiPagesTags: data?.wikiPagesTags?.data ?? [],
|
||||
});
|
||||
|
@ -1,11 +1,14 @@
|
||||
import { IntlMessageFormat } from "intl-messageformat";
|
||||
import { useCallback } from "react";
|
||||
import { useRouter } from "next/router";
|
||||
import { atoms } from "contexts/atoms";
|
||||
import { useAtomGetter } from "helpers/atoms";
|
||||
import { LibraryItemMetadataDynamicZone } from "graphql/generated";
|
||||
import { ICUParams } from "graphql/icuParams";
|
||||
import { isDefined, isDefinedAndNotEmpty } from "helpers/asserts";
|
||||
import { getLogger } from "helpers/logger";
|
||||
import { prettySlug } from "helpers/formatters";
|
||||
import { LibraryItemMetadata } from "types/types";
|
||||
|
||||
const logger = getLogger("🗺️ [I18n]");
|
||||
|
||||
@ -58,12 +61,19 @@ export const useFormat = (): {
|
||||
key: K,
|
||||
...values: ICUParams[K] extends never ? [undefined?] : [ICUParams[K]]
|
||||
) => string;
|
||||
formatLibraryItemType: (metadata: { __typename: LibraryItemType }) => string;
|
||||
formatLibraryItemType: (metadata: LibraryItemMetadata) => string;
|
||||
formatLibraryItemSubType: (metadata: LibraryItemMetadata) => string;
|
||||
formatStatusLabel: (status: ContentStatus) => string;
|
||||
formatStatusDescription: (status: ContentStatus) => string;
|
||||
formatCategory: (slug: string, type?: "default" | "full") => string;
|
||||
formatContentType: (slug: string) => string;
|
||||
formatWikiTag: (slug: string) => string;
|
||||
formatWeaponType: (slug: string) => string;
|
||||
} => {
|
||||
const langui = useAtomGetter(atoms.localData.langui);
|
||||
const fallbackLangui = useAtomGetter(atoms.localData.fallbackLangui);
|
||||
const typesTranslations = useAtomGetter(atoms.localData.typesTranslations);
|
||||
const { locale = "en" } = useRouter();
|
||||
|
||||
const format = useCallback(
|
||||
(
|
||||
@ -96,12 +106,6 @@ Falling back to en translation.`
|
||||
[langui, fallbackLangui]
|
||||
);
|
||||
|
||||
const formatLibraryItemType = useCallback(
|
||||
(metadata: { __typename: LibraryItemType }): string =>
|
||||
format(componentMetadataToWording[metadata.__typename]),
|
||||
[format]
|
||||
);
|
||||
|
||||
const formatStatusLabel = useCallback(
|
||||
(status: ContentStatus): string => format(componentSetsTextsetStatusToWording[status].label),
|
||||
[format]
|
||||
@ -113,10 +117,178 @@ Falling back to en translation.`
|
||||
[format]
|
||||
);
|
||||
|
||||
const formatLibraryItemType = useCallback(
|
||||
(metadata: LibraryItemMetadata): string =>
|
||||
metadata ? format(componentMetadataToWording[metadata.__typename]) : format("other"),
|
||||
[format]
|
||||
);
|
||||
|
||||
const formatLibraryItemSubType = useCallback(
|
||||
(metadata: LibraryItemMetadata): string => {
|
||||
switch (metadata?.__typename) {
|
||||
case "ComponentMetadataAudio": {
|
||||
const slug = metadata.subtype?.data?.attributes?.slug;
|
||||
const subtype = typesTranslations.audioSubtypes.find(
|
||||
(type) => type.attributes?.slug === slug
|
||||
);
|
||||
const findTranslation = (givenLocale: string) =>
|
||||
subtype?.attributes?.titles?.find(
|
||||
(translation) => translation?.language?.data?.attributes?.code === givenLocale
|
||||
)?.title;
|
||||
return findTranslation(locale) ?? findTranslation("en") ?? format("other");
|
||||
}
|
||||
|
||||
case "ComponentMetadataBooks": {
|
||||
const slug = metadata.subtype?.data?.attributes?.slug;
|
||||
const subtype = typesTranslations.textualSubtypes.find(
|
||||
(type) => type.attributes?.slug === slug
|
||||
);
|
||||
const findTranslation = (givenLocale: string) =>
|
||||
subtype?.attributes?.titles?.find(
|
||||
(translation) => translation?.language?.data?.attributes?.code === givenLocale
|
||||
)?.title;
|
||||
return findTranslation(locale) ?? findTranslation("en") ?? format("other");
|
||||
}
|
||||
|
||||
case "ComponentMetadataVideo": {
|
||||
const slug = metadata.subtype?.data?.attributes?.slug;
|
||||
const subtype = typesTranslations.videoSubtypes.find(
|
||||
(type) => type.attributes?.slug === slug
|
||||
);
|
||||
const findTranslation = (givenLocale: string) =>
|
||||
subtype?.attributes?.titles?.find(
|
||||
(translation) => translation?.language?.data?.attributes?.code === givenLocale
|
||||
)?.title;
|
||||
return findTranslation(locale) ?? findTranslation("en") ?? format("other");
|
||||
}
|
||||
|
||||
case "ComponentMetadataGame": {
|
||||
const slug = metadata.platform?.data?.attributes?.slug;
|
||||
const subtype = typesTranslations.gamePlatforms.find(
|
||||
(type) => type.attributes?.slug === slug
|
||||
);
|
||||
const findTranslation = (givenLocale: string) =>
|
||||
subtype?.attributes?.titles?.find(
|
||||
(translation) => translation?.language?.data?.attributes?.code === givenLocale
|
||||
)?.title;
|
||||
return findTranslation(locale) ?? findTranslation("en") ?? format("other");
|
||||
}
|
||||
|
||||
case "ComponentMetadataGroup": {
|
||||
const subItemType = (() => {
|
||||
const subitemTypeSlug = metadata.subitems_type?.data?.attributes?.slug;
|
||||
const subItemTypeTranslations = typesTranslations.metadataTypes.find(
|
||||
(type) => type.attributes?.slug === subitemTypeSlug
|
||||
);
|
||||
const findTranslation = (givenLocale: string) =>
|
||||
subItemTypeTranslations?.attributes?.titles?.find(
|
||||
(translation) => translation?.language?.data?.attributes?.code === givenLocale
|
||||
)?.title;
|
||||
return findTranslation(locale) ?? findTranslation("en") ?? format("other");
|
||||
})();
|
||||
const groupType = (() => {
|
||||
const groupTypeSlug = metadata.subtype?.data?.attributes?.slug;
|
||||
const groupTypeTranslations = typesTranslations.groupSubtypes.find(
|
||||
(type) => type.attributes?.slug === groupTypeSlug
|
||||
);
|
||||
const findTranslation = (givenLocale: string) =>
|
||||
groupTypeTranslations?.attributes?.titles?.find(
|
||||
(translation) => translation?.language?.data?.attributes?.code === givenLocale
|
||||
)?.title;
|
||||
return findTranslation(locale) ?? findTranslation("en") ?? format("other");
|
||||
})();
|
||||
return `${groupType} - ${subItemType}`;
|
||||
}
|
||||
|
||||
default:
|
||||
return format("other");
|
||||
}
|
||||
},
|
||||
[
|
||||
format,
|
||||
locale,
|
||||
typesTranslations.audioSubtypes,
|
||||
typesTranslations.gamePlatforms,
|
||||
typesTranslations.groupSubtypes,
|
||||
typesTranslations.metadataTypes,
|
||||
typesTranslations.textualSubtypes,
|
||||
typesTranslations.videoSubtypes,
|
||||
]
|
||||
);
|
||||
|
||||
const formatCategory = useCallback(
|
||||
(slug: string, type: "default" | "full" = "default"): string => {
|
||||
const category = typesTranslations.categories.find((cat) => cat.attributes?.slug === slug);
|
||||
if (!category) return prettySlug(slug);
|
||||
const findTranslation = (givenLocale: string): string | null | undefined => {
|
||||
const localeTranslation = category.attributes?.titles?.find(
|
||||
(translation) => translation?.language?.data?.attributes?.code === givenLocale
|
||||
);
|
||||
return type === "full" ? localeTranslation?.title : localeTranslation?.short;
|
||||
};
|
||||
return findTranslation(locale) ?? findTranslation("en") ?? prettySlug(slug);
|
||||
},
|
||||
[locale, typesTranslations.categories]
|
||||
);
|
||||
|
||||
const formatContentType = useCallback(
|
||||
(slug: string): string => {
|
||||
const contentType = typesTranslations.contentTypes.find(
|
||||
(type) => type.attributes?.slug === slug
|
||||
);
|
||||
if (!contentType) return prettySlug(slug);
|
||||
const findTranslation = (givenLocale: string): string | null | undefined => {
|
||||
const localeTranslation = contentType.attributes?.titles?.find(
|
||||
(translation) => translation?.language?.data?.attributes?.code === givenLocale
|
||||
);
|
||||
return localeTranslation?.title;
|
||||
};
|
||||
return findTranslation(locale) ?? findTranslation("en") ?? prettySlug(slug);
|
||||
},
|
||||
[locale, typesTranslations.contentTypes]
|
||||
);
|
||||
|
||||
const formatWikiTag = useCallback(
|
||||
(slug: string): string => {
|
||||
const wikiTag = typesTranslations.wikiPagesTags.find((cat) => cat.attributes?.slug === slug);
|
||||
if (!wikiTag) return prettySlug(slug);
|
||||
const findTranslation = (givenLocale: string): string | null | undefined => {
|
||||
const localeTranslation = wikiTag.attributes?.titles?.find(
|
||||
(translation) => translation?.language?.data?.attributes?.code === givenLocale
|
||||
);
|
||||
return localeTranslation?.title;
|
||||
};
|
||||
return findTranslation(locale) ?? findTranslation("en") ?? prettySlug(slug);
|
||||
},
|
||||
[locale, typesTranslations.wikiPagesTags]
|
||||
);
|
||||
|
||||
const formatWeaponType = useCallback(
|
||||
(slug: string): string => {
|
||||
const weaponType = typesTranslations.weaponTypes.find(
|
||||
(type) => type.attributes?.slug === slug
|
||||
);
|
||||
if (!weaponType) return prettySlug(slug);
|
||||
const findTranslation = (givenLocale: string): string | null | undefined => {
|
||||
const localeTranslation = weaponType.attributes?.translations?.find(
|
||||
(translation) => translation?.language?.data?.attributes?.code === givenLocale
|
||||
);
|
||||
return localeTranslation?.name;
|
||||
};
|
||||
return findTranslation(locale) ?? findTranslation("en") ?? prettySlug(slug);
|
||||
},
|
||||
[locale, typesTranslations.weaponTypes]
|
||||
);
|
||||
|
||||
return {
|
||||
format,
|
||||
formatLibraryItemType,
|
||||
formatLibraryItemSubType,
|
||||
formatStatusLabel,
|
||||
formatStatusDescription,
|
||||
formatCategory,
|
||||
formatContentType,
|
||||
formatWikiTag,
|
||||
formatWeaponType,
|
||||
};
|
||||
};
|
||||
|
@ -2,7 +2,13 @@ import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { i18n } from "../../../next.config";
|
||||
import { cartesianProduct } from "helpers/others";
|
||||
import { filterHasAttributes } from "helpers/asserts";
|
||||
import { fetchLocalData } from "graphql/fetchLocalData";
|
||||
import {
|
||||
fetchCurrencies,
|
||||
fetchLanguages,
|
||||
fetchRecorders,
|
||||
fetchTypesTranslations,
|
||||
fetchWebsiteInterfaces,
|
||||
} from "graphql/fetchLocalData";
|
||||
import { getReadySdk } from "graphql/sdk";
|
||||
|
||||
type CRUDEvents = "entry.create" | "entry.delete" | "entry.update";
|
||||
@ -20,21 +26,32 @@ type StrapiRelationalFieldEntry = {
|
||||
|
||||
type RequestProps =
|
||||
| CustomRequest
|
||||
| StrapiAudioSubType
|
||||
| StrapiCategory
|
||||
| StrapiChronicle
|
||||
| StrapiChronicleChapter
|
||||
| StrapiChronology
|
||||
| StrapiContent
|
||||
| StrapiContentFolder
|
||||
| StrapiContentType
|
||||
| StrapiCurrency
|
||||
| StrapiGamePlatform
|
||||
| StrapiGroupSubtypes
|
||||
| StrapiLanguage
|
||||
| StrapiLibraryItem
|
||||
| StrapiMetadataType
|
||||
| StrapiPostContent
|
||||
| StrapiRangedContent
|
||||
| StrapiRecorder
|
||||
| StrapiTextualSubtypes
|
||||
| StrapiVideo
|
||||
| StrapiVideoSubType
|
||||
| StrapiWeaponGroup
|
||||
| StrapiWeaponStory
|
||||
| StrapiWeaponStoryType
|
||||
| StrapiWebsiteInterface
|
||||
| StrapiWiki;
|
||||
| StrapiWiki
|
||||
| StrapiWikiPagesTag;
|
||||
|
||||
interface CustomRequest {
|
||||
model: "custom";
|
||||
@ -57,7 +74,6 @@ interface StrapiWeaponGroup extends StrapiEvent {
|
||||
}
|
||||
|
||||
interface StrapiRangedContent extends StrapiEvent {
|
||||
event: CRUDEvents;
|
||||
model: "ranged-content";
|
||||
entry: {
|
||||
id: string;
|
||||
@ -78,7 +94,6 @@ interface StrapiContent extends StrapiEvent {
|
||||
}
|
||||
|
||||
interface StrapiPostContent extends StrapiEvent {
|
||||
event: CRUDEvents;
|
||||
model: "post";
|
||||
entry: {
|
||||
slug: string;
|
||||
@ -86,31 +101,62 @@ interface StrapiPostContent extends StrapiEvent {
|
||||
}
|
||||
|
||||
interface StrapiWebsiteInterface extends StrapiEvent {
|
||||
event: CRUDEvents;
|
||||
model: "website-interface";
|
||||
entry: {
|
||||
slug: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface StrapiRecorder extends StrapiEvent {
|
||||
model: "recorder";
|
||||
}
|
||||
|
||||
interface StrapiMetadataType extends StrapiEvent {
|
||||
model: "metadata-type";
|
||||
}
|
||||
|
||||
interface StrapiAudioSubType extends StrapiEvent {
|
||||
model: "audio-subtype";
|
||||
}
|
||||
|
||||
interface StrapiVideoSubType extends StrapiEvent {
|
||||
model: "video-subtype";
|
||||
}
|
||||
|
||||
interface StrapiTextualSubtypes extends StrapiEvent {
|
||||
model: "textual-subtype";
|
||||
}
|
||||
|
||||
interface StrapiGroupSubtypes extends StrapiEvent {
|
||||
model: "group-subtype";
|
||||
}
|
||||
|
||||
interface StrapiGamePlatform extends StrapiEvent {
|
||||
model: "game-platform";
|
||||
}
|
||||
|
||||
interface StrapiContentType extends StrapiEvent {
|
||||
model: "content-type";
|
||||
}
|
||||
|
||||
interface StrapiWikiPagesTag extends StrapiEvent {
|
||||
model: "wiki-pages-tag";
|
||||
}
|
||||
|
||||
interface StrapiWeaponStoryType extends StrapiEvent {
|
||||
model: "weapon-story-type";
|
||||
}
|
||||
|
||||
interface StrapiCategory extends StrapiEvent {
|
||||
model: "category";
|
||||
}
|
||||
|
||||
interface StrapiLanguage extends StrapiEvent {
|
||||
event: CRUDEvents;
|
||||
model: "language";
|
||||
entry: {
|
||||
slug: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface StrapiCurrency extends StrapiEvent {
|
||||
event: CRUDEvents;
|
||||
model: "currency";
|
||||
entry: {
|
||||
slug: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface StrapiLibraryItem extends StrapiEvent {
|
||||
event: CRUDEvents;
|
||||
model: "library-item";
|
||||
entry: {
|
||||
slug: string;
|
||||
@ -121,7 +167,6 @@ interface StrapiLibraryItem extends StrapiEvent {
|
||||
}
|
||||
|
||||
interface StrapiContentFolder extends StrapiEvent {
|
||||
event: CRUDEvents;
|
||||
model: "contents-folder";
|
||||
entry: {
|
||||
slug: string;
|
||||
@ -132,12 +177,10 @@ interface StrapiContentFolder extends StrapiEvent {
|
||||
}
|
||||
|
||||
interface StrapiChronology extends StrapiEvent {
|
||||
event: CRUDEvents;
|
||||
model: "chronology-era" | "chronology-item";
|
||||
}
|
||||
|
||||
interface StrapiWiki extends StrapiEvent {
|
||||
event: CRUDEvents;
|
||||
model: "wiki-page";
|
||||
entry: {
|
||||
slug: string;
|
||||
@ -145,7 +188,6 @@ interface StrapiWiki extends StrapiEvent {
|
||||
}
|
||||
|
||||
interface StrapiChronicle extends StrapiEvent {
|
||||
event: CRUDEvents;
|
||||
model: "chronicle";
|
||||
entry: {
|
||||
slug: string;
|
||||
@ -153,7 +195,6 @@ interface StrapiChronicle extends StrapiEvent {
|
||||
}
|
||||
|
||||
interface StrapiChronicleChapter extends StrapiEvent {
|
||||
event: CRUDEvents;
|
||||
model: "chronicles-chapter";
|
||||
entry: {
|
||||
chronicles: StrapiRelationalFieldEntry[];
|
||||
@ -161,7 +202,6 @@ interface StrapiChronicleChapter extends StrapiEvent {
|
||||
}
|
||||
|
||||
interface StrapiVideo extends StrapiEvent {
|
||||
event: CRUDEvents;
|
||||
model: "video";
|
||||
entry: {
|
||||
uid: string;
|
||||
@ -322,13 +362,6 @@ const Revalidate = async (
|
||||
break;
|
||||
}
|
||||
|
||||
case "website-interface":
|
||||
case "language":
|
||||
case "currency": {
|
||||
await fetchLocalData();
|
||||
break;
|
||||
}
|
||||
|
||||
case "video": {
|
||||
if (body.entry.uid) {
|
||||
paths.push(`/archives/videos/v/${body.entry.uid}`);
|
||||
@ -351,6 +384,38 @@ const Revalidate = async (
|
||||
break;
|
||||
}
|
||||
|
||||
case "recorder": {
|
||||
await fetchRecorders();
|
||||
break;
|
||||
}
|
||||
|
||||
case "audio-subtype":
|
||||
case "textual-subtype":
|
||||
case "video-subtype":
|
||||
case "group-subtype":
|
||||
case "game-platform":
|
||||
case "metadata-type":
|
||||
case "content-type":
|
||||
case "weapon-story-type":
|
||||
case "category":
|
||||
case "wiki-pages-tag": {
|
||||
await fetchTypesTranslations();
|
||||
break;
|
||||
}
|
||||
|
||||
case "website-interface": {
|
||||
await fetchWebsiteInterfaces();
|
||||
break;
|
||||
}
|
||||
case "language": {
|
||||
await fetchLanguages();
|
||||
break;
|
||||
}
|
||||
case "currency": {
|
||||
await fetchCurrencies();
|
||||
break;
|
||||
}
|
||||
|
||||
case "custom": {
|
||||
paths.push(`${body.path}`);
|
||||
break;
|
||||
|
@ -34,7 +34,7 @@ interface Props extends AppLayoutRequired {
|
||||
}
|
||||
|
||||
const Chronicle = ({ chronicle, chapters, ...otherProps }: Props): JSX.Element => {
|
||||
const { format } = useFormat();
|
||||
const { format, formatContentType, formatCategory } = useFormat();
|
||||
useScrollTopOnChange(Ids.ContentPanel, [chronicle.slug]);
|
||||
|
||||
const [selectedTranslation, LanguageSwitcher, languageSwitcherProps] = useSmartLanguage({
|
||||
@ -111,8 +111,14 @@ const Chronicle = ({ chronicle, chapters, ...otherProps }: Props): JSX.Element =
|
||||
<ContentLanguageSwitcher {...ContentLanguageSwitcherProps} />
|
||||
) : undefined
|
||||
}
|
||||
categories={primaryContent?.categories}
|
||||
type={primaryContent?.type}
|
||||
categories={filterHasAttributes(primaryContent?.categories?.data, [
|
||||
"attributes",
|
||||
]).map((category) => formatCategory(category.attributes.slug))}
|
||||
type={
|
||||
primaryContent?.type?.data?.attributes
|
||||
? formatContentType(primaryContent.type.data.attributes.slug)
|
||||
: undefined
|
||||
}
|
||||
description={selectedContentTranslation.description}
|
||||
thumbnail={primaryContent?.thumbnail?.data?.attributes}
|
||||
/>,
|
||||
@ -146,13 +152,10 @@ export default Chronicle;
|
||||
|
||||
export const getStaticProps: GetStaticProps = async (context) => {
|
||||
const sdk = getReadySdk();
|
||||
const { format } = getFormat(context.locale);
|
||||
const { format, formatCategory, formatContentType } = getFormat(context.locale);
|
||||
const slug =
|
||||
context.params && isDefined(context.params.slug) ? context.params.slug.toString() : "";
|
||||
const chronicle = await sdk.getChronicle({
|
||||
language_code: context.locale ?? "en",
|
||||
slug: slug,
|
||||
});
|
||||
const chronicle = await sdk.getChronicle({ slug: slug });
|
||||
const chronicles = await sdk.getChroniclesChapters();
|
||||
if (
|
||||
!chronicle.chronicles?.data[0]?.attributes?.translations ||
|
||||
@ -178,13 +181,18 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
||||
description: getDescription(selectedContentTranslation.description, {
|
||||
[format("type", { count: Infinity })]: [
|
||||
chronicle.chronicles.data[0].attributes.contents.data[0].attributes.type?.data
|
||||
?.attributes?.titles?.[0]?.title,
|
||||
?.attributes
|
||||
? formatContentType(
|
||||
chronicle.chronicles.data[0].attributes.contents.data[0].attributes.type.data
|
||||
.attributes.slug
|
||||
)
|
||||
: undefined,
|
||||
],
|
||||
[format("category", { count: Infinity })]: filterHasAttributes(
|
||||
chronicle.chronicles.data[0].attributes.contents.data[0].attributes.categories
|
||||
?.data,
|
||||
["attributes"]
|
||||
).map((category) => category.attributes.short),
|
||||
).map((category) => formatCategory(category.attributes.slug)),
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import { SubPanel } from "components/Containers/SubPanel";
|
||||
import { PreviewCard, TranslatedPreviewCard } from "components/PreviewCard";
|
||||
import { ThumbnailHeader } from "components/ThumbnailHeader";
|
||||
import { getReadySdk } from "graphql/sdk";
|
||||
import { prettyInlineTitle, prettyItemSubType, prettySlug } from "helpers/formatters";
|
||||
import { prettyInlineTitle, prettySlug } from "helpers/formatters";
|
||||
import { isUntangibleGroupItem } from "helpers/libraryItem";
|
||||
import { filterHasAttributes, isDefined, isDefinedAndNotEmpty } from "helpers/asserts";
|
||||
import { ContentWithTranslations } from "types/types";
|
||||
@ -47,7 +47,7 @@ interface Props extends AppLayoutRequired {
|
||||
const Content = ({ content, ...otherProps }: Props): JSX.Element => {
|
||||
const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened);
|
||||
const is1ColumnLayout = useAtomGetter(atoms.containerQueries.is1ColumnLayout);
|
||||
const { format } = useFormat();
|
||||
const { format, formatCategory, formatLibraryItemSubType, formatContentType } = useFormat();
|
||||
|
||||
const [selectedTranslation, LanguageSwitcher, languageSwitcherProps] = useSmartLanguage({
|
||||
items: content.translations,
|
||||
@ -196,12 +196,12 @@ const Content = ({ content, ...otherProps }: Props): JSX.Element => {
|
||||
libraryItem.attributes.metadata &&
|
||||
libraryItem.attributes.metadata.length > 0 &&
|
||||
libraryItem.attributes.metadata[0]
|
||||
? [prettyItemSubType(libraryItem.attributes.metadata[0])]
|
||||
? [formatLibraryItemSubType(libraryItem.attributes.metadata[0])]
|
||||
: []
|
||||
}
|
||||
bottomChips={filterHasAttributes(libraryItem.attributes.categories?.data, [
|
||||
"attributes",
|
||||
]).map((category) => category.attributes.short)}
|
||||
]).map((category) => formatCategory(category.attributes.slug))}
|
||||
metadata={{
|
||||
releaseDate: libraryItem.attributes.release_date,
|
||||
price: libraryItem.attributes.price,
|
||||
@ -250,8 +250,14 @@ const Content = ({ content, ...otherProps }: Props): JSX.Element => {
|
||||
title={selectedTranslation?.title}
|
||||
subtitle={selectedTranslation?.subtitle}
|
||||
description={selectedTranslation?.description}
|
||||
type={content.type}
|
||||
categories={content.categories}
|
||||
categories={filterHasAttributes(content.categories?.data, ["attributes"]).map(
|
||||
(category) => formatCategory(category.attributes.slug)
|
||||
)}
|
||||
type={
|
||||
content.type?.data?.attributes
|
||||
? formatContentType(content.type.data.attributes.slug)
|
||||
: undefined
|
||||
}
|
||||
languageSwitcher={
|
||||
languageSwitcherProps.locales.size > 1 ? (
|
||||
<LanguageSwitcher {...languageSwitcherProps} />
|
||||
@ -330,12 +336,9 @@ export default Content;
|
||||
|
||||
export const getStaticProps: GetStaticProps = async (context) => {
|
||||
const sdk = getReadySdk();
|
||||
const { format } = getFormat(context.locale);
|
||||
const { format, formatCategory, formatContentType } = getFormat(context.locale);
|
||||
const slug = context.params?.slug ? context.params.slug.toString() : "";
|
||||
const content = await sdk.getContentText({
|
||||
slug: slug,
|
||||
language_code: context.locale ?? "en",
|
||||
});
|
||||
const content = await sdk.getContentText({ slug: slug });
|
||||
|
||||
if (!content.contents?.data[0]?.attributes?.translations) {
|
||||
return { notFound: true };
|
||||
@ -361,12 +364,14 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
||||
),
|
||||
description: getDescription(rawDescription, {
|
||||
[format("type", { count: Infinity })]: [
|
||||
content.contents.data[0].attributes.type?.data?.attributes?.titles?.[0]?.title,
|
||||
content.contents.data[0].attributes.type?.data?.attributes
|
||||
? formatContentType(content.contents.data[0].attributes.type.data.attributes.slug)
|
||||
: undefined,
|
||||
],
|
||||
[format("category", { count: Infinity })]: filterHasAttributes(
|
||||
content.contents.data[0].attributes.categories?.data,
|
||||
["attributes"]
|
||||
).map((category) => category.attributes.short),
|
||||
).map((category) => formatCategory(category.attributes.slug)),
|
||||
}),
|
||||
audio:
|
||||
selectedTranslation.language?.data?.attributes?.code && selectedTranslation.audio_set
|
||||
@ -470,6 +475,7 @@ const RelatedContentPreview = ({
|
||||
categories,
|
||||
type,
|
||||
}: RelatedContentPreviewFragment) => {
|
||||
const { formatCategory, formatContentType } = useFormat();
|
||||
const isContentPanelAtLeastXl = useAtomGetter(atoms.containerQueries.isContentPanelAtLeastXl);
|
||||
|
||||
return (
|
||||
@ -486,16 +492,10 @@ const RelatedContentPreview = ({
|
||||
)}
|
||||
fallback={{ title: slug }}
|
||||
thumbnail={thumbnail?.data?.attributes}
|
||||
topChips={
|
||||
type?.data?.attributes
|
||||
? [
|
||||
type.data.attributes.titles?.[0]
|
||||
? type.data.attributes.titles[0]?.title
|
||||
: prettySlug(type.data.attributes.slug),
|
||||
]
|
||||
: undefined
|
||||
}
|
||||
bottomChips={categories?.data.map((category) => category.attributes?.short ?? "")}
|
||||
topChips={type?.data?.attributes ? [formatContentType(type.data.attributes.slug)] : undefined}
|
||||
bottomChips={filterHasAttributes(categories?.data, ["attributes"]).map((category) =>
|
||||
formatCategory(category.attributes.slug)
|
||||
)}
|
||||
keepInfoVisible
|
||||
/>
|
||||
);
|
||||
|
@ -59,7 +59,7 @@ interface Props extends AppLayoutRequired {}
|
||||
|
||||
const Contents = (props: Props): JSX.Element => {
|
||||
const hoverable = useDeviceSupportsHover();
|
||||
const { format } = useFormat();
|
||||
const { format, formatCategory, formatContentType } = useFormat();
|
||||
const router = useTypedRouter(queryParamSchema);
|
||||
const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened);
|
||||
|
||||
@ -225,15 +225,11 @@ const Contents = (props: Props): JSX.Element => {
|
||||
thumbnailForceAspectRatio
|
||||
topChips={
|
||||
item.type?.data?.attributes
|
||||
? [
|
||||
item.type.data.attributes.titles?.[0]
|
||||
? item.type.data.attributes.titles[0]?.title
|
||||
: prettySlug(item.type.data.attributes.slug),
|
||||
]
|
||||
? [formatContentType(item.type.data.attributes.slug)]
|
||||
: undefined
|
||||
}
|
||||
bottomChips={item.categories?.data.map(
|
||||
(category) => category.attributes?.short ?? ""
|
||||
bottomChips={filterHasAttributes(item.categories?.data, ["attributes"]).map(
|
||||
(category) => formatCategory(category.attributes.slug)
|
||||
)}
|
||||
keepInfoVisible={keepInfoVisible}
|
||||
/>
|
||||
|
@ -35,7 +35,7 @@ interface Props extends AppLayoutRequired {
|
||||
}
|
||||
|
||||
const ContentsFolder = ({ openGraph, folder, path, ...otherProps }: Props): JSX.Element => {
|
||||
const { format } = useFormat();
|
||||
const { format, formatCategory, formatContentType } = useFormat();
|
||||
const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened);
|
||||
const isContentPanelAtLeast4xl = useAtomGetter(atoms.containerQueries.isContentPanelAtLeast4xl);
|
||||
|
||||
@ -158,16 +158,12 @@ const ContentsFolder = ({ openGraph, folder, path, ...otherProps }: Props): JSX.
|
||||
thumbnailForceAspectRatio
|
||||
topChips={
|
||||
item.attributes.type?.data?.attributes
|
||||
? [
|
||||
item.attributes.type.data.attributes.titles?.[0]
|
||||
? item.attributes.type.data.attributes.titles[0]?.title
|
||||
: prettySlug(item.attributes.type.data.attributes.slug),
|
||||
]
|
||||
? [formatContentType(item.attributes.type.data.attributes.slug)]
|
||||
: undefined
|
||||
}
|
||||
bottomChips={item.attributes.categories?.data.map(
|
||||
(category) => category.attributes?.short ?? ""
|
||||
)}
|
||||
bottomChips={filterHasAttributes(item.attributes.categories?.data, [
|
||||
"attributes",
|
||||
]).map((category) => formatCategory(category.attributes.slug))}
|
||||
keepInfoVisible
|
||||
/>
|
||||
))}
|
||||
@ -201,10 +197,7 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
||||
const sdk = getReadySdk();
|
||||
const { format } = getFormat(context.locale);
|
||||
const slug = context.params?.slug ? context.params.slug.toString() : "";
|
||||
const contentsFolder = await sdk.getContentsFolder({
|
||||
slug: slug,
|
||||
language_code: context.locale ?? "en",
|
||||
});
|
||||
const contentsFolder = await sdk.getContentsFolder({ slug: slug });
|
||||
if (!contentsFolder.contentsFolders?.data[0]?.attributes) {
|
||||
return { notFound: true };
|
||||
}
|
||||
|
@ -64,10 +64,7 @@ export default Home;
|
||||
export const getStaticProps: GetStaticProps = async (context) => {
|
||||
const sdk = getReadySdk();
|
||||
const { format } = getFormat(context.locale);
|
||||
const post = await sdk.getPost({
|
||||
slug: "home",
|
||||
language_code: context.locale ?? "en",
|
||||
});
|
||||
const post = await sdk.getPost({ slug: "home" });
|
||||
if (post.posts?.data && post.posts.data.length > 0) {
|
||||
const props: PostStaticProps = {
|
||||
post: post.posts.data[0]?.attributes as PostWithTranslations,
|
||||
|
@ -23,7 +23,6 @@ import { getReadySdk } from "graphql/sdk";
|
||||
import {
|
||||
prettyDate,
|
||||
prettyInlineTitle,
|
||||
prettyItemSubType,
|
||||
prettyPrice,
|
||||
prettySlug,
|
||||
prettyURL,
|
||||
@ -91,7 +90,13 @@ const LibrarySlug = ({
|
||||
}: Props): JSX.Element => {
|
||||
const currency = useAtomGetter(atoms.settings.currency);
|
||||
const isPerfModeEnabled = useAtomGetter(atoms.settings.isPerfModeEnabled);
|
||||
const { format, formatLibraryItemType } = useFormat();
|
||||
const {
|
||||
format,
|
||||
formatLibraryItemType,
|
||||
formatCategory,
|
||||
formatContentType,
|
||||
formatLibraryItemSubType,
|
||||
} = useFormat();
|
||||
const currencies = useAtomGetter(atoms.localData.currencies);
|
||||
|
||||
const isContentPanelAtLeast3xl = useAtomGetter(atoms.containerQueries.isContentPanelAtLeast3xl);
|
||||
@ -307,7 +312,7 @@ const LibrarySlug = ({
|
||||
<div className="grid grid-flow-col gap-1">
|
||||
<Chip text={formatLibraryItemType(item.metadata[0])} />
|
||||
{"›"}
|
||||
<Chip text={prettyItemSubType(item.metadata[0])} />
|
||||
<Chip text={formatLibraryItemSubType(item.metadata[0])} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@ -347,7 +352,10 @@ const LibrarySlug = ({
|
||||
</h3>
|
||||
<div className="flex flex-row flex-wrap place-content-center gap-2">
|
||||
{filterHasAttributes(item.categories.data, ["attributes"]).map((category) => (
|
||||
<Chip key={category.id} text={category.attributes.name} />
|
||||
<Chip
|
||||
key={category.attributes.slug}
|
||||
text={formatCategory(category.attributes.slug, "full")}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
@ -506,12 +514,12 @@ const LibrarySlug = ({
|
||||
subitem.attributes.metadata &&
|
||||
subitem.attributes.metadata.length > 0 &&
|
||||
subitem.attributes.metadata[0]
|
||||
? [prettyItemSubType(subitem.attributes.metadata[0])]
|
||||
? [formatLibraryItemSubType(subitem.attributes.metadata[0])]
|
||||
: []
|
||||
}
|
||||
bottomChips={subitem.attributes.categories?.data.map(
|
||||
(category) => category.attributes?.short ?? ""
|
||||
)}
|
||||
bottomChips={filterHasAttributes(subitem.attributes.categories?.data, [
|
||||
"attributes",
|
||||
]).map((category) => formatCategory(category.attributes.slug))}
|
||||
metadata={{
|
||||
releaseDate: subitem.attributes.release_date,
|
||||
price: subitem.attributes.price,
|
||||
@ -573,14 +581,14 @@ const LibrarySlug = ({
|
||||
categories: filterHasAttributes(
|
||||
rangedContent.attributes.content.data.attributes.categories?.data,
|
||||
["attributes"]
|
||||
).map((category) => category.attributes.short),
|
||||
type:
|
||||
rangedContent.attributes.content.data.attributes.type?.data
|
||||
?.attributes?.titles?.[0]?.title ??
|
||||
prettySlug(
|
||||
rangedContent.attributes.content.data.attributes.type?.data
|
||||
?.attributes?.slug
|
||||
),
|
||||
).map((category) => formatCategory(category.attributes.slug)),
|
||||
type: rangedContent.attributes.content.data.attributes.type?.data
|
||||
?.attributes
|
||||
? formatContentType(
|
||||
rangedContent.attributes.content.data.attributes.type.data
|
||||
.attributes.slug
|
||||
)
|
||||
: undefined,
|
||||
slug: rangedContent.attributes.content.data.attributes.slug,
|
||||
}
|
||||
: undefined
|
||||
@ -619,10 +627,9 @@ export default LibrarySlug;
|
||||
|
||||
export const getStaticProps: GetStaticProps = async (context) => {
|
||||
const sdk = getReadySdk();
|
||||
const { format } = getFormat(context.locale);
|
||||
const { format, formatCategory, formatLibraryItemSubType } = getFormat(context.locale);
|
||||
const item = await sdk.getLibraryItem({
|
||||
slug: context.params && isDefined(context.params.slug) ? context.params.slug.toString() : "",
|
||||
language_code: context.locale ?? "en",
|
||||
});
|
||||
if (!item.libraryItems?.data[0]?.attributes) return { notFound: true };
|
||||
sortRangedContent(item.libraryItems.data[0].attributes.contents);
|
||||
@ -634,10 +641,10 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
||||
{
|
||||
[format("category", { count: Infinity })]: filterHasAttributes(
|
||||
item.libraryItems.data[0].attributes.categories?.data,
|
||||
["attributes.short"]
|
||||
).map((category) => category.attributes.short),
|
||||
["attributes"]
|
||||
).map((category) => formatCategory(category.attributes.slug)),
|
||||
[format("type", { count: Infinity })]: item.libraryItems.data[0].attributes.metadata?.[0]
|
||||
? [prettyItemSubType(item.libraryItems.data[0].attributes.metadata[0])]
|
||||
? [formatLibraryItemSubType(item.libraryItems.data[0].attributes.metadata[0])]
|
||||
: [],
|
||||
[format("release_date")]: [
|
||||
item.libraryItems.data[0].attributes.release_date
|
||||
|
@ -593,7 +593,6 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
||||
const { format } = getFormat(context.locale);
|
||||
const item = await sdk.getLibraryItemScans({
|
||||
slug: context.params && isDefined(context.params.slug) ? context.params.slug.toString() : "",
|
||||
language_code: context.locale ?? "en",
|
||||
});
|
||||
if (!item.libraryItems?.data[0]?.attributes || !item.libraryItems.data[0]?.id)
|
||||
return { notFound: true };
|
||||
@ -891,7 +890,7 @@ const ScanSet = ({ onClickOnImage, scanSet, id, title, content }: ScanSetProps):
|
||||
{filterHasAttributes(selectedScan.scanners.data, ["id", "attributes"]).map(
|
||||
(scanner) => (
|
||||
<Fragment key={scanner.id}>
|
||||
<RecorderChip recorder={scanner.attributes} />
|
||||
<RecorderChip username={scanner.attributes.username} />
|
||||
</Fragment>
|
||||
)
|
||||
)}
|
||||
@ -906,7 +905,7 @@ const ScanSet = ({ onClickOnImage, scanSet, id, title, content }: ScanSetProps):
|
||||
{filterHasAttributes(selectedScan.cleaners.data, ["id", "attributes"]).map(
|
||||
(cleaner) => (
|
||||
<Fragment key={cleaner.id}>
|
||||
<RecorderChip recorder={cleaner.attributes} />
|
||||
<RecorderChip username={cleaner.attributes.username} />
|
||||
</Fragment>
|
||||
)
|
||||
)}
|
||||
@ -921,7 +920,7 @@ const ScanSet = ({ onClickOnImage, scanSet, id, title, content }: ScanSetProps):
|
||||
{filterHasAttributes(selectedScan.typesetters.data, ["id", "attributes"]).map(
|
||||
(typesetter) => (
|
||||
<Fragment key={typesetter.id}>
|
||||
<RecorderChip recorder={typesetter.attributes} />
|
||||
<RecorderChip username={typesetter.attributes.username} />
|
||||
</Fragment>
|
||||
)
|
||||
)}
|
||||
|
@ -27,7 +27,6 @@ import {
|
||||
import { MeiliIndices, MeiliLibraryItem } from "shared/meilisearch-graphql-typings/meiliTypes";
|
||||
import { useTypedRouter } from "hooks/useTypedRouter";
|
||||
import { TranslatedPreviewCard } from "components/PreviewCard";
|
||||
import { prettyItemSubType } from "helpers/formatters";
|
||||
import { isUntangibleGroupItem } from "helpers/libraryItem";
|
||||
import { PreviewCardCTAs } from "components/Library/PreviewCardCTAs";
|
||||
import { useLibraryItemUserStatus } from "hooks/useLibraryItemUserStatus";
|
||||
@ -70,7 +69,7 @@ interface Props extends AppLayoutRequired {}
|
||||
|
||||
const Library = (props: Props): JSX.Element => {
|
||||
const hoverable = useDeviceSupportsHover();
|
||||
const { format } = useFormat();
|
||||
const { format, formatCategory, formatLibraryItemSubType } = useFormat();
|
||||
const { libraryItemUserStatus } = useLibraryItemUserStatus();
|
||||
|
||||
const sortingMethods = useMemo(
|
||||
@ -414,11 +413,11 @@ const Library = (props: Props): JSX.Element => {
|
||||
keepInfoVisible={keepInfoVisible}
|
||||
topChips={
|
||||
item.metadata && item.metadata.length > 0 && item.metadata[0]
|
||||
? [prettyItemSubType(item.metadata[0])]
|
||||
: []
|
||||
? [formatLibraryItemSubType(item.metadata[0])]
|
||||
: undefined
|
||||
}
|
||||
bottomChips={item.categories?.data.map(
|
||||
(category) => category.attributes?.short ?? ""
|
||||
bottomChips={filterHasAttributes(item.categories?.data, ["attributes"]).map(
|
||||
(category) => formatCategory(category.attributes.slug)
|
||||
)}
|
||||
metadata={{
|
||||
releaseDate: item.release_date,
|
||||
|
@ -56,7 +56,7 @@ const queryParamSchema = z.object({
|
||||
interface Props extends AppLayoutRequired {}
|
||||
|
||||
const News = ({ ...otherProps }: Props): JSX.Element => {
|
||||
const { format } = useFormat();
|
||||
const { format, formatCategory } = useFormat();
|
||||
const hoverable = useDeviceSupportsHover();
|
||||
const router = useTypedRouter(queryParamSchema);
|
||||
|
||||
@ -180,8 +180,8 @@ const News = ({ ...otherProps }: Props): JSX.Element => {
|
||||
thumbnailAspectRatio="3/2"
|
||||
thumbnailForceAspectRatio
|
||||
keepInfoVisible={keepInfoVisible}
|
||||
bottomChips={item.categories?.data.map(
|
||||
(category) => category.attributes?.short ?? ""
|
||||
bottomChips={filterHasAttributes(item.categories?.data, ["attributes"]).map(
|
||||
(category) => formatCategory(category.attributes.slug)
|
||||
)}
|
||||
metadata={{
|
||||
releaseDate: item.date,
|
||||
|
@ -38,7 +38,7 @@ interface Props extends AppLayoutRequired {
|
||||
}
|
||||
|
||||
const WikiPage = ({ page, ...otherProps }: Props): JSX.Element => {
|
||||
const { format } = useFormat();
|
||||
const { format, formatCategory, formatWikiTag } = useFormat();
|
||||
const router = useRouter();
|
||||
const isTerminalMode = useAtomGetter(atoms.layout.terminalMode);
|
||||
const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened);
|
||||
@ -126,7 +126,10 @@ const WikiPage = ({ page, ...otherProps }: Props): JSX.Element => {
|
||||
|
||||
<div className="flex flex-row flex-wrap place-content-center gap-2">
|
||||
{filterHasAttributes(page.categories.data, ["attributes"]).map((category) => (
|
||||
<Chip key={category.id} text={category.attributes.name} />
|
||||
<Chip
|
||||
key={category.attributes.slug}
|
||||
text={formatCategory(category.attributes.slug, "full")}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
@ -137,12 +140,7 @@ const WikiPage = ({ page, ...otherProps }: Props): JSX.Element => {
|
||||
<p className="font-headers text-xl font-bold">{format("tags")}</p>
|
||||
<div className="flex flex-row flex-wrap place-content-center gap-2">
|
||||
{filterHasAttributes(page.tags.data, ["attributes"]).map((tag) => (
|
||||
<Chip
|
||||
key={tag.id}
|
||||
text={
|
||||
tag.attributes.titles?.[0]?.title ?? prettySlug(tag.attributes.slug)
|
||||
}
|
||||
/>
|
||||
<Chip key={tag.attributes.slug} text={formatWikiTag(tag.attributes.slug)} />
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
@ -180,7 +178,7 @@ const WikiPage = ({ page, ...otherProps }: Props): JSX.Element => {
|
||||
}))}
|
||||
index={index + 1}
|
||||
categories={filterHasAttributes(definition.categories?.data, ["attributes"]).map(
|
||||
(category) => category.attributes.short
|
||||
(category) => formatCategory(category.attributes.slug)
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
@ -250,24 +248,21 @@ export default WikiPage;
|
||||
|
||||
export const getStaticProps: GetStaticProps = async (context) => {
|
||||
const sdk = getReadySdk();
|
||||
const { format } = getFormat(context.locale);
|
||||
const { format, formatCategory, formatWikiTag } = getFormat(context.locale);
|
||||
const slug =
|
||||
context.params && isDefined(context.params.slug) ? context.params.slug.toString() : "";
|
||||
const page = await sdk.getWikiPage({
|
||||
language_code: context.locale ?? "en",
|
||||
slug: slug,
|
||||
});
|
||||
const page = await sdk.getWikiPage({ slug: slug });
|
||||
if (!page.wikiPages?.data[0]?.attributes?.translations) return { notFound: true };
|
||||
|
||||
const { title, description } = (() => {
|
||||
const chipsGroups = {
|
||||
[format("tags")]: filterHasAttributes(page.wikiPages.data[0].attributes.tags?.data, [
|
||||
"attributes",
|
||||
]).map((tag) => tag.attributes.titles?.[0]?.title ?? prettySlug(tag.attributes.slug)),
|
||||
]).map((tag) => formatWikiTag(tag.attributes.slug)),
|
||||
[format("category", { count: Infinity })]: filterHasAttributes(
|
||||
page.wikiPages.data[0].attributes.categories?.data,
|
||||
["attributes"]
|
||||
).map((category) => category.attributes.short),
|
||||
).map((category) => formatCategory(category.attributes.slug)),
|
||||
};
|
||||
|
||||
if (context.locale && context.locales) {
|
||||
|
@ -51,10 +51,10 @@ const queryParamSchema = z.object({
|
||||
interface Props extends AppLayoutRequired {}
|
||||
|
||||
const Wiki = (props: Props): JSX.Element => {
|
||||
const { format, formatCategory, formatWikiTag } = useFormat();
|
||||
const hoverable = useDeviceSupportsHover();
|
||||
const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened);
|
||||
const closeSubPanel = useCallback(() => setSubPanelOpened(false), [setSubPanelOpened]);
|
||||
const { format } = useFormat();
|
||||
const router = useTypedRouter(queryParamSchema);
|
||||
const [query, setQuery] = useState(router.query.query ?? DEFAULT_FILTERS_STATE.query);
|
||||
|
||||
@ -201,11 +201,11 @@ const Wiki = (props: Props): JSX.Element => {
|
||||
thumbnailRounded
|
||||
thumbnailForceAspectRatio
|
||||
keepInfoVisible
|
||||
topChips={filterHasAttributes(item.tags?.data, ["attributes"]).map(
|
||||
(tag) => tag.attributes.titles?.[0]?.title ?? prettySlug(tag.attributes.slug)
|
||||
topChips={filterHasAttributes(item.tags?.data, ["attributes"]).map((tag) =>
|
||||
formatWikiTag(tag.attributes.slug)
|
||||
)}
|
||||
bottomChips={filterHasAttributes(item.categories?.data, ["attributes"]).map(
|
||||
(category) => category.attributes.short
|
||||
(category) => formatCategory(category.attributes.slug)
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
|
@ -64,7 +64,7 @@ const WeaponPreview = ({ weapon }: WeaponPreviewProps): JSX.Element => (
|
||||
);
|
||||
|
||||
const WeaponPage = ({ weapon, primaryName, aliases, ...otherProps }: Props): JSX.Element => {
|
||||
const { format } = useFormat();
|
||||
const { format, formatCategory, formatWeaponType } = useFormat();
|
||||
|
||||
const intersectionIds = useMemo(
|
||||
() => filterDefined(weapon.stories).map(({ id }) => `story-${id}`),
|
||||
@ -91,8 +91,10 @@ const WeaponPage = ({ weapon, primaryName, aliases, ...otherProps }: Props): JSX
|
||||
key={index}
|
||||
url={`#${id}`}
|
||||
title={`Story ${index + 1}`}
|
||||
subtitle={weapon.stories?.[index]?.categories?.data
|
||||
.map((category) => category.attributes?.name)
|
||||
subtitle={filterHasAttributes(weapon.stories?.[index]?.categories?.data, [
|
||||
"attributes",
|
||||
])
|
||||
.map((category) => formatCategory(category.attributes.slug))
|
||||
.join("・")}
|
||||
active={currentIntersection === index}
|
||||
border
|
||||
@ -133,6 +135,11 @@ const WeaponPage = ({ weapon, primaryName, aliases, ...otherProps }: Props): JSX
|
||||
<ThumbnailHeader
|
||||
title={primaryName}
|
||||
subtitle={aliases.join("・")}
|
||||
type={
|
||||
weapon.type?.data?.attributes
|
||||
? formatWeaponType(weapon.type.data.attributes.slug)
|
||||
: undefined
|
||||
}
|
||||
thumbnail={weapon.thumbnail?.data?.attributes}
|
||||
/>
|
||||
|
||||
@ -166,10 +173,7 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
||||
const sdk = getReadySdk();
|
||||
const { format } = getFormat(context.locale);
|
||||
const slug = context.params?.slug ? context.params.slug.toString() : "";
|
||||
const weaponResp = await sdk.getWeapon({
|
||||
slug: slug,
|
||||
language_code: context.locale ?? "en",
|
||||
});
|
||||
const weaponResp = await sdk.getWeapon({ slug: slug });
|
||||
|
||||
const weapon = weaponResp.weaponStories?.data[0]?.attributes;
|
||||
|
||||
@ -227,7 +231,7 @@ interface WeaponStoryProps {
|
||||
}
|
||||
|
||||
const WeaponStory = ({ story, storyNumber, id }: WeaponStoryProps): JSX.Element => {
|
||||
const { format } = useFormat();
|
||||
const { format, formatCategory } = useFormat();
|
||||
const [selectedTranslation, LanguageSwitcher, languageSwitcherProps] = useSmartLanguage({
|
||||
items: story.translations,
|
||||
languageExtractor: useCallback(
|
||||
@ -241,14 +245,18 @@ const WeaponStory = ({ story, storyNumber, id }: WeaponStoryProps): JSX.Element
|
||||
|
||||
return (
|
||||
<InsetBox id={id} className="formatted">
|
||||
<h2 className="!mb-4 !mt-4">{format("story_x", { x: storyNumber })}</h2>
|
||||
|
||||
{languageSwitcherProps.locales.size > 1 && <LanguageSwitcher {...languageSwitcherProps} />}
|
||||
<div className="flex place-content-center place-items-center gap-4">
|
||||
<h2 className="!mb-4 !mt-4">{format("story_x", { x: storyNumber })}</h2>
|
||||
{languageSwitcherProps.locales.size > 1 && <LanguageSwitcher {...languageSwitcherProps} />}
|
||||
</div>
|
||||
|
||||
{story.categories && story.categories.data.length > 0 && (
|
||||
<div className="mb-12 flex flex-row flex-wrap place-content-center gap-2">
|
||||
{filterHasAttributes(story.categories.data, ["attributes.name"]).map((category) => (
|
||||
<Chip key={category.id} text={category.attributes.name} />
|
||||
{filterHasAttributes(story.categories.data, ["attributes"]).map((category) => (
|
||||
<Chip
|
||||
key={category.attributes.slug}
|
||||
text={formatCategory(category.attributes.slug, "full")}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
@ -54,7 +54,7 @@ const queryParamSchema = z.object({
|
||||
interface Props extends AppLayoutRequired {}
|
||||
|
||||
const Weapons = (props: Props): JSX.Element => {
|
||||
const { format } = useFormat();
|
||||
const { format, formatCategory, formatWeaponType } = useFormat();
|
||||
const hoverable = useDeviceSupportsHover();
|
||||
const router = useTypedRouter(queryParamSchema);
|
||||
|
||||
@ -190,11 +190,11 @@ const Weapons = (props: Props): JSX.Element => {
|
||||
keepInfoVisible={keepInfoVisible}
|
||||
topChips={
|
||||
item.type?.data?.attributes?.slug
|
||||
? [prettySlug(item.type.data.attributes.slug)]
|
||||
? [formatWeaponType(item.type.data.attributes.slug)]
|
||||
: undefined
|
||||
}
|
||||
bottomChips={filterHasAttributes(item.categories, ["attributes.short"]).map(
|
||||
(category) => category.attributes.short
|
||||
bottomChips={filterHasAttributes(item.categories, ["attributes"]).map((category) =>
|
||||
formatCategory(category.attributes.slug)
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
@ -203,11 +203,7 @@ const Weapons = (props: Props): JSX.Element => {
|
||||
</ContentPanel>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<AppLayout contentPanel={contentPanel} subPanel={subPanel} {...props} />
|
||||
</>
|
||||
);
|
||||
return <AppLayout contentPanel={contentPanel} subPanel={subPanel} {...props} />;
|
||||
};
|
||||
export default Weapons;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -73,3 +73,39 @@ export enum LibraryItemUserStatus {
|
||||
Want = 1,
|
||||
Have = 2,
|
||||
}
|
||||
|
||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
|
||||
type LibraryItemMetadataSubType = {
|
||||
data?: {
|
||||
attributes?: {
|
||||
slug: string;
|
||||
} | null;
|
||||
} | null;
|
||||
} | null;
|
||||
|
||||
export type LibraryItemMetadata =
|
||||
| {
|
||||
__typename: "ComponentMetadataAudio";
|
||||
subtype?: LibraryItemMetadataSubType;
|
||||
}
|
||||
| {
|
||||
__typename: "ComponentMetadataBooks";
|
||||
subtype?: LibraryItemMetadataSubType;
|
||||
}
|
||||
| {
|
||||
__typename: "ComponentMetadataGame";
|
||||
platform?: LibraryItemMetadataSubType;
|
||||
}
|
||||
| {
|
||||
__typename: "ComponentMetadataGroup";
|
||||
subtype?: LibraryItemMetadataSubType;
|
||||
subitems_type?: LibraryItemMetadataSubType;
|
||||
}
|
||||
| {
|
||||
__typename: "ComponentMetadataVideo";
|
||||
subtype?: LibraryItemMetadataSubType;
|
||||
}
|
||||
| { __typename: "ComponentMetadataOther" }
|
||||
| { __typename: "Error" }
|
||||
| null;
|
||||
|
Loading…
x
Reference in New Issue
Block a user