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":"中文"}}]}}
|
File diff suppressed because one or more lines are too long
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…
Reference in New Issue