- {prettyDate(video.published_date, router.locale)}
+ {formatDate(video.published_date)}
diff --git a/src/pages/contents/all.tsx b/src/pages/contents/all.tsx
index f3eeee6..bcb6ce8 100644
--- a/src/pages/contents/all.tsx
+++ b/src/pages/contents/all.tsx
@@ -42,12 +42,14 @@ const DEFAULT_FILTERS_STATE = {
keepInfoVisible: true,
query: "",
page: 1,
+ lang: 0,
};
const queryParamSchema = z.object({
query: z.coerce.string().optional(),
page: z.coerce.number().positive().optional(),
sort: z.coerce.number().min(0).max(5).optional(),
+ lang: z.coerce.number().min(0).optional(),
});
/*
@@ -59,7 +61,7 @@ interface Props extends AppLayoutRequired {}
const Contents = (props: Props): JSX.Element => {
const hoverable = useDeviceSupportsHover();
- const { format, formatCategory, formatContentType } = useFormat();
+ const { format, formatCategory, formatContentType, formatLanguage } = useFormat();
const router = useTypedRouter(queryParamSchema);
const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened);
@@ -72,6 +74,17 @@ const Contents = (props: Props): JSX.Element => {
[format]
);
+ const languageOptions = useMemo(() => {
+ const memo =
+ router.locales?.map((language) => ({
+ meiliAttribute: language,
+ displayedName: formatLanguage(language),
+ })) ?? [];
+
+ memo.unshift({ meiliAttribute: "", displayedName: format("all") });
+ return memo;
+ }, [router.locales, formatLanguage, format]);
+
const [sortingMethod, setSortingMethod] = useState(
router.query.sort ?? DEFAULT_FILTERS_STATE.sortingMethod
);
@@ -82,25 +95,41 @@ const Contents = (props: Props): JSX.Element => {
setValue: setKeepInfoVisible,
} = useBoolean(DEFAULT_FILTERS_STATE.keepInfoVisible);
- const [page, setPage] = useState(router.query.page ?? DEFAULT_FILTERS_STATE.page);
const [contents, setContents] = useState>();
+ const [page, setPage] = useState(router.query.page ?? DEFAULT_FILTERS_STATE.page);
const [query, setQuery] = useState(router.query.query ?? DEFAULT_FILTERS_STATE.query);
+ const [languageOption, setLanguageOption] = useState(
+ router.query.lang ?? DEFAULT_FILTERS_STATE.lang
+ );
useEffect(() => {
const fetchPosts = async () => {
- const currentSortingMethod = sortingMethods[sortingMethod];
+ const currentSortingMethod = sortingMethods[sortingMethod]?.meiliAttribute;
+ const currentLanguageOption = languageOptions[languageOption]?.meiliAttribute;
+
+ const filter: string[] = [];
+ if (languageOption !== 0) {
+ filter.push(`filterable_languages = ${currentLanguageOption}`);
+ }
+
const searchResult = await meiliSearch(MeiliIndices.CONTENT, query, {
attributesToRetrieve: ["translations", "id", "slug", "categories", "type", "thumbnail"],
attributesToHighlight: ["translations"],
attributesToCrop: ["translations.displayable_description"],
+ filter,
hitsPerPage: 25,
page,
- sort: isDefined(currentSortingMethod) ? [currentSortingMethod.meiliAttribute] : undefined,
+ sort: isDefined(currentSortingMethod) ? [currentSortingMethod] : undefined,
});
- setContents(filterHitsWithHighlight(searchResult, "translations"));
+
+ setContents(
+ languageOption === 0
+ ? filterHitsWithHighlight(searchResult, "translations")
+ : searchResult
+ );
};
fetchPosts();
- }, [query, page, sortingMethod, sortingMethods]);
+ }, [query, page, sortingMethod, sortingMethods, languageOption, languageOptions]);
useEffect(() => {
if (router.isReady)
@@ -108,15 +137,17 @@ const Contents = (props: Props): JSX.Element => {
page,
query,
sort: sortingMethod,
+ lang: languageOption,
});
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [page, query, sortingMethod, router.isReady]);
+ }, [page, query, languageOption, sortingMethod, router.isReady]);
useEffect(() => {
if (router.isReady) {
if (isDefined(router.query.page)) setPage(router.query.page);
if (isDefined(router.query.query)) setQuery(router.query.query);
if (isDefined(router.query.sort)) setSortingMethod(router.query.sort);
+ if (isDefined(router.query.lang)) setLanguageOption(router.query.lang);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [router.isReady]);
@@ -173,6 +204,24 @@ const Contents = (props: Props): JSX.Element => {
/>
+
+
+
{hoverable && (
{
text={format("reset_all_filters")}
icon="settings_backup_restore"
onClick={() => {
- setPage(1);
+ setPage(DEFAULT_FILTERS_STATE.page);
setQuery(DEFAULT_FILTERS_STATE.query);
setSortingMethod(DEFAULT_FILTERS_STATE.sortingMethod);
setKeepInfoVisible(DEFAULT_FILTERS_STATE.keepInfoVisible);
+ setLanguageOption(DEFAULT_FILTERS_STATE.lang);
sendAnalytics("Contents/All", "Reset all filters");
}}
/>
@@ -212,13 +262,19 @@ const Contents = (props: Props): JSX.Element => {
href={`/contents/${item.slug}`}
translations={filterHasAttributes(item._formatted.translations, [
"language.data.attributes.code",
- ]).map(({ displayable_description, language, ...otherAttributes }) => ({
- ...otherAttributes,
- description: containsHighlight(displayable_description)
- ? displayable_description
- : undefined,
- language: language.data.attributes.code,
- }))}
+ ])
+ .map(({ displayable_description, language, ...otherAttributes }) => ({
+ ...otherAttributes,
+ description: containsHighlight(displayable_description)
+ ? displayable_description
+ : undefined,
+ language: language.data.attributes.code,
+ }))
+ .filter(
+ ({ language }) =>
+ languageOption === 0 ||
+ language === languageOptions[languageOption]?.meiliAttribute
+ )}
fallback={{ title: prettySlug(item.slug) }}
thumbnail={item.thumbnail?.data?.attributes}
thumbnailAspectRatio="3/2"
diff --git a/src/pages/library/[slug]/index.tsx b/src/pages/library/[slug]/index.tsx
index 2c16ee2..717f082 100644
--- a/src/pages/library/[slug]/index.tsx
+++ b/src/pages/library/[slug]/index.tsx
@@ -1,6 +1,5 @@
import { Fragment, useCallback, useMemo } from "react";
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
-import { useRouter } from "next/router";
import { useBoolean } from "usehooks-ts";
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { Chip } from "components/Chip";
@@ -20,13 +19,7 @@ import {
GetLibraryItemQuery,
} from "graphql/generated";
import { getReadySdk } from "graphql/sdk";
-import {
- prettyDate,
- prettyInlineTitle,
- prettyPrice,
- prettySlug,
- prettyURL,
-} from "helpers/formatters";
+import { prettyInlineTitle, prettySlug, prettyURL } from "helpers/formatters";
import { ImageQuality } from "helpers/img";
import { convertMmToInch } from "helpers/numbers";
import { sortRangedContent } from "helpers/others";
@@ -96,15 +89,15 @@ const LibrarySlug = ({
formatCategory,
formatContentType,
formatLibraryItemSubType,
+ formatPrice,
+ formatDate,
} = useFormat();
- const currencies = useAtomGetter(atoms.localData.currencies);
const isContentPanelAtLeast3xl = useAtomGetter(atoms.containerQueries.isContentPanelAtLeast3xl);
const isContentPanelAtLeastSm = useAtomGetter(atoms.containerQueries.isContentPanelAtLeastSm);
const is3ColumnsLayout = useAtomGetter(atoms.containerQueries.is3ColumnsLayout);
const hoverable = useDeviceSupportsHover();
- const router = useRouter();
const { value: keepInfoVisible, toggle: toggleKeepInfoVisible } = useBoolean(false);
const { showLightBox } = useAtomGetter(atoms.lightBox);
@@ -320,24 +313,17 @@ const LibrarySlug = ({
{item.release_date && (
{format("release_date")}
-
{prettyDate(item.release_date, router.locale)}
+
{formatDate(item.release_date)}
)}
{item.price && (
{format("price")}
-
- {prettyPrice(
- item.price,
- currencies,
- item.price.currency?.data?.attributes?.code,
- router.locale
- )}
-
+
{formatPrice(item.price)}
{item.price.currency?.data?.attributes?.code !== currency && (
- {prettyPrice(item.price, currencies, currency, router.locale)}
+ {formatPrice(item.price, currency)}
({format("calculated").toLowerCase()})
)}
@@ -627,7 +613,9 @@ export default LibrarySlug;
export const getStaticProps: GetStaticProps = async (context) => {
const sdk = getReadySdk();
- const { format, formatCategory, formatLibraryItemSubType } = getFormat(context.locale);
+ const { format, formatCategory, formatLibraryItemSubType, formatDate } = getFormat(
+ context.locale
+ );
const item = await sdk.getLibraryItem({
slug: context.params && isDefined(context.params.slug) ? context.params.slug.toString() : "",
});
@@ -648,7 +636,7 @@ export const getStaticProps: GetStaticProps = async (context) => {
: [],
[format("release_date")]: [
item.libraryItems.data[0].attributes.release_date
- ? prettyDate(item.libraryItems.data[0].attributes.release_date, context.locale)
+ ? formatDate(item.libraryItems.data[0].attributes.release_date)
: undefined,
],
}
diff --git a/src/pages/news/index.tsx b/src/pages/news/index.tsx
index 20188c3..56980ea 100644
--- a/src/pages/news/index.tsx
+++ b/src/pages/news/index.tsx
@@ -1,5 +1,5 @@
import { GetStaticProps } from "next";
-import { useEffect, useState } from "react";
+import { useEffect, useMemo, useState } from "react";
import { useBoolean } from "usehooks-ts";
import { z } from "zod";
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
@@ -31,6 +31,7 @@ import { prettySlug } from "helpers/formatters";
import { Paginator } from "components/Containers/Paginator";
import { useFormat } from "hooks/useFormat";
import { getFormat } from "helpers/i18n";
+import { Select } from "components/Inputs/Select";
/*
* ╭─────────────╮
@@ -41,11 +42,13 @@ const DEFAULT_FILTERS_STATE = {
query: "",
keepInfoVisible: true,
page: 1,
+ lang: 0,
};
const queryParamSchema = z.object({
query: z.coerce.string().optional(),
page: z.coerce.number().positive().optional(),
+ lang: z.coerce.number().min(0).optional(),
});
/*
@@ -56,9 +59,10 @@ const queryParamSchema = z.object({
interface Props extends AppLayoutRequired {}
const News = ({ ...otherProps }: Props): JSX.Element => {
- const { format, formatCategory } = useFormat();
+ const { format, formatCategory, formatLanguage } = useFormat();
const hoverable = useDeviceSupportsHover();
const router = useTypedRouter(queryParamSchema);
+ const isTerminalMode = useAtomGetter(atoms.layout.terminalMode);
const [query, setQuery] = useState(router.query.query ?? DEFAULT_FILTERS_STATE.query);
@@ -68,13 +72,32 @@ const News = ({ ...otherProps }: Props): JSX.Element => {
setValue: setKeepInfoVisible,
} = useBoolean(DEFAULT_FILTERS_STATE.keepInfoVisible);
- const isTerminalMode = useAtomGetter(atoms.layout.terminalMode);
+ const languageOptions = useMemo(() => {
+ const memo =
+ router.locales?.map((language) => ({
+ meiliAttribute: language,
+ displayedName: formatLanguage(language),
+ })) ?? [];
+
+ memo.unshift({ meiliAttribute: "", displayedName: format("all") });
+ return memo;
+ }, [router.locales, formatLanguage, format]);
const [page, setPage] = useState
(router.query.page ?? DEFAULT_FILTERS_STATE.page);
const [posts, setPosts] = useState>();
+ const [languageOption, setLanguageOption] = useState(
+ router.query.lang ?? DEFAULT_FILTERS_STATE.lang
+ );
useEffect(() => {
const fetchPosts = async () => {
+ const currentLanguageOption = languageOptions[languageOption]?.meiliAttribute;
+ const filter = ["hidden = false"];
+
+ if (languageOption !== 0) {
+ filter.push(`filterable_languages = ${currentLanguageOption}`);
+ }
+
const searchResult = await meiliSearch(MeiliIndices.POST, query, {
hitsPerPage: 25,
page,
@@ -82,26 +105,33 @@ const News = ({ ...otherProps }: Props): JSX.Element => {
attributesToHighlight: ["translations.title", "translations.displayable_description"],
attributesToCrop: ["translations.displayable_description"],
sort: ["sortable_date:desc"],
- filter: ["hidden = false"],
+ filter,
});
- setPosts(filterHitsWithHighlight(searchResult, "translations"));
+
+ setPosts(
+ languageOption === 0
+ ? filterHitsWithHighlight(searchResult, "translations")
+ : searchResult
+ );
};
fetchPosts();
- }, [query, page]);
+ }, [query, page, languageOption, languageOptions]);
useEffect(() => {
if (router.isReady)
router.updateQuery({
page,
query,
+ lang: languageOption,
});
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [page, query, router.isReady]);
+ }, [page, query, languageOption, router.isReady]);
useEffect(() => {
if (router.isReady) {
if (isDefined(router.query.page)) setPage(router.query.page);
if (isDefined(router.query.query)) setQuery(router.query.query);
+ if (isDefined(router.query.lang)) setLanguageOption(router.query.lang);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [router.isReady]);
@@ -131,6 +161,24 @@ const News = ({ ...otherProps }: Props): JSX.Element => {
}}
/>
+
+
+
{hoverable && (
{
text={format("reset_all_filters")}
icon="settings_backup_restore"
onClick={() => {
+ setPage(DEFAULT_FILTERS_STATE.page);
setQuery(DEFAULT_FILTERS_STATE.query);
setKeepInfoVisible(DEFAULT_FILTERS_STATE.keepInfoVisible);
+ setLanguageOption(DEFAULT_FILTERS_STATE.lang);
sendAnalytics("News", "Reset all filters");
}}
/>
@@ -168,13 +218,19 @@ const News = ({ ...otherProps }: Props): JSX.Element => {
href={`/news/${item.slug}`}
translations={filterHasAttributes(item._formatted.translations, [
"language.data.attributes.code",
- ]).map(({ excerpt, displayable_description, language, ...otherAttributes }) => ({
- ...otherAttributes,
- description: containsHighlight(displayable_description)
- ? displayable_description
- : excerpt,
- language: language.data.attributes.code,
- }))}
+ ])
+ .map(({ excerpt, displayable_description, language, ...otherAttributes }) => ({
+ ...otherAttributes,
+ description: containsHighlight(displayable_description)
+ ? displayable_description
+ : excerpt,
+ language: language.data.attributes.code,
+ }))
+ .filter(
+ ({ language }) =>
+ languageOption === 0 ||
+ language === languageOptions[languageOption]?.meiliAttribute
+ )}
fallback={{ title: prettySlug(item.slug) }}
thumbnail={item.thumbnail?.data?.attributes}
thumbnailAspectRatio="3/2"
diff --git a/src/pages/wiki/index.tsx b/src/pages/wiki/index.tsx
index fc2493d..c1c6abb 100644
--- a/src/pages/wiki/index.tsx
+++ b/src/pages/wiki/index.tsx
@@ -1,5 +1,5 @@
import { GetStaticProps } from "next";
-import { useCallback, useEffect, useState } from "react";
+import { useCallback, useEffect, useMemo, useState } from "react";
import { useBoolean } from "usehooks-ts";
import { z } from "zod";
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
@@ -20,12 +20,18 @@ import { TranslatedPreviewCard } from "components/PreviewCard";
import { sendAnalytics } from "helpers/analytics";
import { useTypedRouter } from "hooks/useTypedRouter";
import { MeiliIndices, MeiliWikiPage } from "shared/meilisearch-graphql-typings/meiliTypes";
-import { containsHighlight, CustomSearchResponse, meiliSearch } from "helpers/search";
+import {
+ containsHighlight,
+ CustomSearchResponse,
+ filterHitsWithHighlight,
+ meiliSearch,
+} from "helpers/search";
import { Paginator } from "components/Containers/Paginator";
import { useFormat } from "hooks/useFormat";
import { getFormat } from "helpers/i18n";
import { useAtomSetter } from "helpers/atoms";
import { atoms } from "contexts/atoms";
+import { Select } from "components/Inputs/Select";
/*
* ╭─────────────╮
@@ -36,11 +42,13 @@ const DEFAULT_FILTERS_STATE = {
query: "",
keepInfoVisible: true,
page: 1,
+ lang: 0,
};
const queryParamSchema = z.object({
query: z.coerce.string().optional(),
page: z.coerce.number().positive().optional(),
+ lang: z.coerce.number().min(0).optional(),
});
/*
@@ -51,24 +59,44 @@ const queryParamSchema = z.object({
interface Props extends AppLayoutRequired {}
const Wiki = (props: Props): JSX.Element => {
- const { format, formatCategory, formatWikiTag } = useFormat();
+ const { format, formatCategory, formatWikiTag, formatLanguage } = useFormat();
const hoverable = useDeviceSupportsHover();
const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened);
const closeSubPanel = useCallback(() => setSubPanelOpened(false), [setSubPanelOpened]);
const router = useTypedRouter(queryParamSchema);
- const [query, setQuery] = useState(router.query.query ?? DEFAULT_FILTERS_STATE.query);
+ const languageOptions = useMemo(() => {
+ const memo =
+ router.locales?.map((language) => ({
+ meiliAttribute: language,
+ displayedName: formatLanguage(language),
+ })) ?? [];
+
+ memo.unshift({ meiliAttribute: "", displayedName: format("all") });
+ return memo;
+ }, [router.locales, formatLanguage, format]);
+
+ const [wikiPages, setWikiPages] = useState>();
+ const [query, setQuery] = useState(router.query.query ?? DEFAULT_FILTERS_STATE.query);
+ const [page, setPage] = useState(router.query.page ?? DEFAULT_FILTERS_STATE.page);
const {
value: keepInfoVisible,
toggle: toggleKeepInfoVisible,
setValue: setKeepInfoVisible,
} = useBoolean(DEFAULT_FILTERS_STATE.keepInfoVisible);
-
- const [page, setPage] = useState(router.query.page ?? DEFAULT_FILTERS_STATE.page);
- const [wikiPages, setWikiPages] = useState>();
+ const [languageOption, setLanguageOption] = useState(
+ router.query.lang ?? DEFAULT_FILTERS_STATE.lang
+ );
useEffect(() => {
const fetchWikiPages = async () => {
+ const currentLanguageOption = languageOptions[languageOption]?.meiliAttribute;
+
+ const filter: string[] = [];
+ if (languageOption !== 0) {
+ filter.push(`filterable_languages = ${currentLanguageOption}`);
+ }
+
const searchResult = await meiliSearch(MeiliIndices.WIKI_PAGE, query, {
hitsPerPage: 25,
page,
@@ -79,25 +107,32 @@ const Wiki = (props: Props): JSX.Element => {
"translations.displayable_description",
],
attributesToCrop: ["translations.displayable_description"],
+ filter,
});
- setWikiPages(searchResult);
+ setWikiPages(
+ languageOption === 0
+ ? filterHitsWithHighlight(searchResult, "translations")
+ : searchResult
+ );
};
fetchWikiPages();
- }, [query, page]);
+ }, [query, page, languageOptions, languageOption]);
useEffect(() => {
if (router.isReady)
router.updateQuery({
page,
query,
+ lang: languageOption,
});
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [page, query, router.isReady]);
+ }, [page, query, router.isReady, languageOption]);
useEffect(() => {
if (router.isReady) {
if (isDefined(router.query.page)) setPage(router.query.page);
if (isDefined(router.query.query)) setQuery(router.query.query);
+ if (isDefined(router.query.lang)) setLanguageOption(router.query.lang);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [router.isReady]);
@@ -127,6 +162,24 @@ const Wiki = (props: Props): JSX.Element => {
}}
/>
+
+
+
{hoverable && (
{
text={format("reset_all_filters")}
icon="settings_backup_restore"
onClick={() => {
- setPage(1);
+ setPage(DEFAULT_FILTERS_STATE.page);
setQuery(DEFAULT_FILTERS_STATE.query);
setKeepInfoVisible(DEFAULT_FILTERS_STATE.keepInfoVisible);
+ setLanguageOption(DEFAULT_FILTERS_STATE.lang);
sendAnalytics("Wiki", "Reset all filters");
}}
/>
@@ -182,19 +236,31 @@ const Wiki = (props: Props): JSX.Element => {
href={`/wiki/${item.slug}`}
translations={filterHasAttributes(item._formatted.translations, [
"language.data.attributes.code",
- ]).map(
- ({ aliases, summary, displayable_description, language, ...otherAttributes }) => ({
- ...otherAttributes,
- subtitle:
- aliases && aliases.length > 0
- ? aliases.map((alias) => alias?.alias).join("・")
- : undefined,
- description: containsHighlight(displayable_description)
- ? displayable_description
- : summary,
- language: language.data.attributes.code,
- })
- )}
+ ])
+ .map(
+ ({
+ aliases,
+ summary,
+ displayable_description,
+ language,
+ ...otherAttributes
+ }) => ({
+ ...otherAttributes,
+ subtitle:
+ aliases && aliases.length > 0
+ ? aliases.map((alias) => alias?.alias).join("・")
+ : undefined,
+ description: containsHighlight(displayable_description)
+ ? displayable_description
+ : summary,
+ language: language.data.attributes.code,
+ })
+ )
+ .filter(
+ ({ language }) =>
+ languageOption === 0 ||
+ language === languageOptions[languageOption]?.meiliAttribute
+ )}
fallback={{ title: prettySlug(item.slug) }}
thumbnail={item.thumbnail?.data?.attributes}
thumbnailAspectRatio={"4/3"}
diff --git a/src/pages/wiki/weapons/index.tsx b/src/pages/wiki/weapons/index.tsx
index 909a4b6..38863c3 100644
--- a/src/pages/wiki/weapons/index.tsx
+++ b/src/pages/wiki/weapons/index.tsx
@@ -1,6 +1,6 @@
import { GetStaticProps } from "next";
import { z } from "zod";
-import { useEffect, useState } from "react";
+import { useEffect, useMemo, useState } from "react";
import { useBoolean } from "usehooks-ts";
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { getFormat } from "helpers/i18n";
@@ -29,6 +29,7 @@ import { useDeviceSupportsHover } from "hooks/useMediaQuery";
import { WithLabel } from "components/Inputs/WithLabel";
import { Switch } from "components/Inputs/Switch";
import { ReturnButton } from "components/PanelComponents/ReturnButton";
+import { Select } from "components/Inputs/Select";
/*
* ╭─────────────╮
@@ -39,11 +40,13 @@ const DEFAULT_FILTERS_STATE = {
query: "",
keepInfoVisible: true,
page: 1,
+ lang: 0,
};
const queryParamSchema = z.object({
query: z.coerce.string().optional(),
page: z.coerce.number().positive().optional(),
+ lang: z.coerce.number().min(0).optional(),
});
/*
@@ -54,12 +57,26 @@ const queryParamSchema = z.object({
interface Props extends AppLayoutRequired {}
const Weapons = (props: Props): JSX.Element => {
- const { format, formatCategory, formatWeaponType } = useFormat();
+ const { format, formatCategory, formatWeaponType, formatLanguage } = useFormat();
const hoverable = useDeviceSupportsHover();
const router = useTypedRouter(queryParamSchema);
+ const languageOptions = useMemo(() => {
+ const memo =
+ router.locales?.map((language) => ({
+ meiliAttribute: language,
+ displayedName: formatLanguage(language),
+ })) ?? [];
+
+ memo.unshift({ meiliAttribute: "", displayedName: format("all") });
+ return memo;
+ }, [router.locales, formatLanguage, format]);
+
const [query, setQuery] = useState(router.query.query ?? DEFAULT_FILTERS_STATE.query);
const [page, setPage] = useState(router.query.page ?? DEFAULT_FILTERS_STATE.page);
+ const [languageOption, setLanguageOption] = useState(
+ router.query.lang ?? DEFAULT_FILTERS_STATE.lang
+ );
const {
value: keepInfoVisible,
@@ -71,6 +88,13 @@ const Weapons = (props: Props): JSX.Element => {
useEffect(() => {
const fetchPosts = async () => {
+ const currentLanguageOption = languageOptions[languageOption]?.meiliAttribute;
+
+ const filter: string[] = [];
+ if (languageOption !== 0) {
+ filter.push(`filterable_languages = ${currentLanguageOption}`);
+ }
+
const searchResult = await meiliSearch(MeiliIndices.WEAPON, query, {
hitsPerPage: 25,
page,
@@ -78,25 +102,32 @@ const Weapons = (props: Props): JSX.Element => {
attributesToHighlight: ["translations.description", "translations.names"],
attributesToCrop: ["translations.description"],
sort: ["slug:asc"],
+ filter,
});
- setWeapons(filterHitsWithHighlight(searchResult, "translations"));
+ setWeapons(
+ languageOption === 0
+ ? filterHitsWithHighlight(searchResult, "translations")
+ : searchResult
+ );
};
fetchPosts();
- }, [query, page]);
+ }, [query, page, languageOptions, languageOption]);
useEffect(() => {
if (router.isReady)
router.updateQuery({
page,
query,
+ lang: languageOption,
});
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [page, query, router.isReady]);
+ }, [page, query, languageOption, router.isReady]);
useEffect(() => {
if (router.isReady) {
if (isDefined(router.query.page)) setPage(router.query.page);
if (isDefined(router.query.query)) setQuery(router.query.query);
+ if (isDefined(router.query.lang)) setLanguageOption(router.query.lang);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [router.isReady]);
@@ -132,6 +163,24 @@ const Weapons = (props: Props): JSX.Element => {
}}
/>
+
+
+
{hoverable && (
{
text={format("reset_all_filters")}
icon="settings_backup_restore"
onClick={() => {
+ setPage(DEFAULT_FILTERS_STATE.page);
setQuery(DEFAULT_FILTERS_STATE.query);
setKeepInfoVisible(DEFAULT_FILTERS_STATE.keepInfoVisible);
+ setLanguageOption(DEFAULT_FILTERS_STATE.lang);
sendAnalytics("Weapons", "Reset all filters");
}}
/>
@@ -176,12 +227,18 @@ const Weapons = (props: Props): JSX.Element => {
href={`/wiki/weapons/${item.slug}`}
translations={filterHasAttributes(item._formatted.translations, [
"language.data.attributes.code",
- ]).map(({ description, language, names: [primaryName, ...aliases] }) => ({
- language: language.data.attributes.code,
- title: primaryName,
- subtitle: aliases.join("・"),
- description: containsHighlight(description) ? description : undefined,
- }))}
+ ])
+ .map(({ description, language, names: [primaryName, ...aliases] }) => ({
+ language: language.data.attributes.code,
+ title: primaryName,
+ subtitle: aliases.join("・"),
+ description: containsHighlight(description) ? description : undefined,
+ }))
+ .filter(
+ ({ language }) =>
+ languageOption === 0 ||
+ language === languageOptions[languageOption]?.meiliAttribute
+ )}
fallback={{ title: prettySlug(item.slug) }}
thumbnail={item.thumbnail?.data?.attributes}
thumbnailAspectRatio="1/1"
diff --git a/src/shared/meilisearch-graphql-typings/meiliTypes.ts b/src/shared/meilisearch-graphql-typings/meiliTypes.ts
index b72e0af..7a70bfa 100644
--- a/src/shared/meilisearch-graphql-typings/meiliTypes.ts
+++ b/src/shared/meilisearch-graphql-typings/meiliTypes.ts
@@ -33,6 +33,7 @@ export interface MeiliContent
displayable_description?: string | null;
})[];
sortable_updated_date: number;
+ filterable_languages: string[];
}
export interface MeiliVideo extends VideoAttributesFragment {
@@ -50,6 +51,7 @@ export interface MeiliPost extends Omit
> & {
displayable_description?: string | null;
})[];
+ filterable_languages: string[];
}
export interface MeiliWikiPage extends Omit {
@@ -60,6 +62,7 @@ export interface MeiliWikiPage extends Omit & {
displayable_description?: string | null;
})[];
+ filterable_languages: string[];
}
type WeaponAttributesTranslation = NonNullable<
@@ -79,6 +82,7 @@ export interface MeiliWeapon extends Omit