From 3ce7c00d5bbe2f089a69db6c6a866ac2d0d161eb Mon Sep 17 00:00:00 2001 From: Remmy Cat Stock <3317423+remmycat@users.noreply.github.com> Date: Fri, 21 Oct 2022 18:29:23 +0200 Subject: [PATCH 1/8] Detect active nav item via route handle instead of path matching --- app/components/layout/index.tsx | 34 ++++++++++++++++++++++++--------- app/routes/admin.tsx | 10 +++++++++- app/routes/analyzer.tsx | 1 + app/routes/badges.tsx | 1 + app/routes/builds.tsx | 1 + app/routes/calendar/index.tsx | 1 + app/routes/maps.tsx | 1 + app/routes/plus.tsx | 5 +++++ app/utils/remix.ts | 4 ++++ 9 files changed, 48 insertions(+), 10 deletions(-) diff --git a/app/components/layout/index.tsx b/app/components/layout/index.tsx index b05710e8d..b04831c4d 100644 --- a/app/components/layout/index.tsx +++ b/app/components/layout/index.tsx @@ -1,7 +1,8 @@ -import { Link, useLocation } from "@remix-run/react"; +import { Link, useMatches } from "@remix-run/react"; import * as React from "react"; import { useTranslation } from "react-i18next"; import type { RootLoaderData } from "~/root"; +import { type SendouRouteHandle } from "~/utils/remix"; import { LOGO_PATH, navIconUrl } from "~/utils/urls"; import { Image } from "../Image"; import { ColorModeToggle } from "./ColorModeToggle"; @@ -12,6 +13,25 @@ import { Menu } from "./Menu"; import navItems from "./nav-items.json"; import { UserItem } from "./UserItem"; +function useActiveNavItem() { + const matches = useMatches(); + + return React.useMemo(() => { + let activeItem: { name: string; url: string } | undefined = undefined; + + for (const match of matches.reverse()) { + const handle = match.handle as SendouRouteHandle | undefined; + + if (handle?.navItemName) { + activeItem = navItems.find(({ name }) => name === handle.navItemName); + break; + } + } + + return activeItem; + }, [matches]); +} + export const Layout = React.memo(function Layout({ children, patrons, @@ -22,12 +42,8 @@ export const Layout = React.memo(function Layout({ isCatchBoundary?: boolean; }) { const { t } = useTranslation(); - const location = useLocation(); const [menuOpen, setMenuOpen] = React.useState(false); - - const currentPagesNavItem = navItems.find((navItem) => - location.pathname.includes(navItem.name) - ); + const activeNavItem = useActiveNavItem(); return (
@@ -51,15 +67,15 @@ export const Layout = React.memo(function Layout({
setMenuOpen(false)} /> - {currentPagesNavItem && ( + {activeNavItem && (
- {t(`pages.${currentPagesNavItem.name}` as any)} + {t(`pages.${activeNavItem.name}` as any)}
)} {children} diff --git a/app/routes/admin.tsx b/app/routes/admin.tsx index 768532035..8490107ac 100644 --- a/app/routes/admin.tsx +++ b/app/routes/admin.tsx @@ -18,7 +18,11 @@ import { Main } from "~/components/Main"; import { requireUser } from "~/modules/auth"; import { getUser, isImpersonating } from "~/modules/auth/user.server"; import { canPerformAdminActions } from "~/permissions"; -import { parseRequestFormData, validate } from "~/utils/remix"; +import { + parseRequestFormData, + type SendouRouteHandle, + validate, +} from "~/utils/remix"; import { makeTitle } from "~/utils/strings"; import { impersonateUrl, SEED_URL, STOP_IMPERSONATING_URL } from "~/utils/urls"; import { db } from "~/db"; @@ -69,6 +73,10 @@ export const loader: LoaderFunction = async ({ request }) => { }); }; +export const handle: SendouRouteHandle = { + navItemName: "admin", +}; + export default function AdminPage() { return (
diff --git a/app/routes/analyzer.tsx b/app/routes/analyzer.tsx index 8253e30c1..c1bb42f10 100644 --- a/app/routes/analyzer.tsx +++ b/app/routes/analyzer.tsx @@ -52,6 +52,7 @@ export const links: LinksFunction = () => { export const handle: SendouRouteHandle = { i18n: ["weapons", "analyzer"], + navItemName: "analyzer", }; export default function BuildAnalyzerPage() { diff --git a/app/routes/badges.tsx b/app/routes/badges.tsx index 0106ce443..8b64d95ed 100644 --- a/app/routes/badges.tsx +++ b/app/routes/badges.tsx @@ -21,6 +21,7 @@ export interface BadgesLoaderData { export const handle: SendouRouteHandle = { i18n: "badges", + navItemName: "badges", }; export const loader: LoaderFunction = () => { diff --git a/app/routes/builds.tsx b/app/routes/builds.tsx index 6eddd29c6..87c234620 100644 --- a/app/routes/builds.tsx +++ b/app/routes/builds.tsx @@ -16,6 +16,7 @@ export const links: LinksFunction = () => { export const handle: SendouRouteHandle = { i18n: ["weapons", "builds"], breadcrumb: ({ t }) => t("pages.builds"), + navItemName: "builds", }; export default function BuildsLayoutPage() { diff --git a/app/routes/calendar/index.tsx b/app/routes/calendar/index.tsx index ec8983c2f..841e684f6 100644 --- a/app/routes/calendar/index.tsx +++ b/app/routes/calendar/index.tsx @@ -48,6 +48,7 @@ export const meta: MetaFunction = (args) => { export const handle: SendouRouteHandle = { i18n: "calendar", + navItemName: "calendar", }; const loaderSearchParamsSchema = z.object({ diff --git a/app/routes/maps.tsx b/app/routes/maps.tsx index 3b7d8b661..ff152df1a 100644 --- a/app/routes/maps.tsx +++ b/app/routes/maps.tsx @@ -66,6 +66,7 @@ export const meta: MetaFunction = (args) => { export const handle: SendouRouteHandle = { i18n: "game-misc", + navItemName: "maps", }; export const loader = async ({ request }: LoaderArgs) => { diff --git a/app/routes/plus.tsx b/app/routes/plus.tsx index 1425f0f9e..66b061bf8 100644 --- a/app/routes/plus.tsx +++ b/app/routes/plus.tsx @@ -3,11 +3,16 @@ import { Outlet } from "@remix-run/react"; import { Main } from "~/components/Main"; import { SubNav, SubNavLink } from "~/components/SubNav"; import styles from "~/styles/plus.css"; +import { type SendouRouteHandle } from "~/utils/remix"; export const links: LinksFunction = () => { return [{ rel: "stylesheet", href: styles }]; }; +export const handle: SendouRouteHandle = { + navItemName: "plus", +}; + export default function PlusPageLayout() { return ( <> diff --git a/app/utils/remix.ts b/app/utils/remix.ts index be1be09f9..3bf68b402 100644 --- a/app/utils/remix.ts +++ b/app/utils/remix.ts @@ -102,6 +102,7 @@ export function validate(condition: any, status = 400): asserts condition { export type SendouRouteHandle = { /** The i18n translation files used for this route, via remix-i18next */ i18n?: Namespace; + /** * A function that returns the breadcrumb text that should be displayed in * the component @@ -110,4 +111,7 @@ export type SendouRouteHandle = { match: RouteMatch; t: TFunction<"common", undefined>; }) => string | undefined; + + /** The name of a navItem that is active on this route. See nav-items.json */ + navItemName?: string; }; From 17b34f6fe2f63ac0b10644c7dec81badf7e66713 Mon Sep 17 00:00:00 2001 From: lolametro <13728127+lolametro@users.noreply.github.com> Date: Fri, 21 Oct 2022 21:08:53 +0200 Subject: [PATCH 2/8] Update calendar.json for DE --- public/locales/de/calendar.json | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/public/locales/de/calendar.json b/public/locales/de/calendar.json index 7c495c47c..d0294be1d 100644 --- a/public/locales/de/calendar.json +++ b/public/locales/de/calendar.json @@ -1,6 +1,6 @@ { - "inYourTimeZone": " Alle Zeiten sind konvertiert zur lokalen Zeitzone:", - "addNew": "Turnier hinzufügen", + "inYourTimeZone": "Alle Zeiten sind konvertiert zur lokalen Zeitzone:", + "addNew": "Event hinzufügen", "noEvents": "Keine Events in dieser Woche", "reportResults": "Ergebnisse können eingetragen werden für:", "day": "Tag {{number}}", @@ -8,19 +8,21 @@ "participatedCount": "{{count}} teilnehmende Teams", "members": "Mitglieder", "results": "Resultate", + "createMapList": "Arenen-Liste erstellen", "forms.dates": "Datum", - "forms.bracketUrl": "Turnierbaum URL", - "forms.discordInvite": "Discord server Einladung URL", + "forms.bracketUrl": "Turnierbaum-URL", + "forms.discordInvite": "Discord-Server Einladungs-URL", "forms.tags": "Tags", "forms.tags.placeholder": "Wähle einen Tag", - "forms.tags.info": "\"Abzeichen-Preis\" tag wird automatisch hinzugefügt (falls anwendbar)", + "forms.tags.info": "\"Abzeichen-Preis\"-Tag wird automatisch hinzugefügt (falls anwendbar)", "forms.badges": "Abzeichen-Preis", "forms.badges.placeholder": "Wähle ein Abzeichen für das Event", + "forms.mapPool": "Arenen-Pool", "forms.participantCount": "Anzahl Teilnehmer", "forms.reportResultsHeader": "Berichten der Ergebnisse von {{eventName}}", - "forms.reportResultsInfo": "Die Anzahl der eintragbaren Resultate ist frei wählbar. Es kann nur das erste Team sein, die Top 3 oder mehr.", + "forms.reportResultsInfo": "Die Anzahl der eintragbaren Ergebnisse ist frei wählbar. Es kann nur das erste Team sein, die Top 3 oder mehr.", "forms.team.add": "Team hinzufügen", "forms.team.remove": "Team löschen", "forms.team.name": "Name des Teams", From 1efd49f15edcc0dcf5a6e0b821ecea4b4d176380 Mon Sep 17 00:00:00 2001 From: lolametro <13728127+lolametro@users.noreply.github.com> Date: Fri, 21 Oct 2022 21:14:30 +0200 Subject: [PATCH 3/8] Update common.json for DE --- public/locales/de/common.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/public/locales/de/common.json b/public/locales/de/common.json index c846839b6..99e54e858 100644 --- a/public/locales/de/common.json +++ b/public/locales/de/common.json @@ -8,10 +8,16 @@ "pages.faq": "FAQ", "pages.builds": "Ausrüstungen", "pages.analyzer": "Ausrüstungs-Analyse", + "pages.maps": "Arenen-Listen", "header.profile": "Profil", "header.logout": "Ausloggen", "header.login": "Einloggen", + + "auth.errors.aborted": "Einloggen abgebrochen", + "auth.errors.failed": "Einloggen fehlgeschlagen", + "auth.errors.discordPermissions": "Für dein sendou.ink-Profil wird Zugriff auf den Namen, Avatar und Social-Media-Verlinkungen in deinem Discord-Profil benötigt.", + "auth.errors.unknown": "Das Einloggen über Discord ist aus einem unbekannten Grund fehlgeschlagen. Falls das weiterhin passiert, kontaktiere bitte für mehr Hilfe.", "footer.github.subtitle": "Sourcecode", "footer.twitter.subtitle": "Updates", @@ -28,6 +34,11 @@ "actions.delete": "Löschen", "actions.loadMore": "Mehr laden", "actions.close": "Schließen", + + "maps.createMapList": "Arenen-Liste erstellen", + "maps.halfSz": "50% Herrschaft", + "maps.mapPool": "Arenen-Pool", + "maps.tournamentMaplist": "Arenen-Liste für Turnier erstellen (maps.iplabs.ink)", "results": "Ergebnisse", From afe24d150a887271875ec03f445302ce37b43231 Mon Sep 17 00:00:00 2001 From: lolametro <13728127+lolametro@users.noreply.github.com> Date: Fri, 21 Oct 2022 21:16:05 +0200 Subject: [PATCH 4/8] Update front.json for DE --- public/locales/de/front.json | 1 + 1 file changed, 1 insertion(+) diff --git a/public/locales/de/front.json b/public/locales/de/front.json index 3b6ff1cb4..8405878f5 100644 --- a/public/locales/de/front.json +++ b/public/locales/de/front.json @@ -6,6 +6,7 @@ "plus.description": "Sieh vergangene Plus Server Abstimmungen und mehr", "badges.description": "Liste aller Abzeichen, die du für dein Profil verdienen kannst", "analyzer.description": "Analysiere, was deine Ausrüstungen wirklich bewirken", + "maps.description": "Erstelle aus einem Arenen-Pool die Liste für dein Spiel", "recentWinners": "Aktuelle Gewinner", "upcomingEvents": "Bevorstehende Events", "articleBy": "von {{author}}" From c25d4fbd977c727f379ba99e61db8d64c693e650 Mon Sep 17 00:00:00 2001 From: lolametro <13728127+lolametro@users.noreply.github.com> Date: Fri, 21 Oct 2022 21:18:19 +0200 Subject: [PATCH 5/8] Update game-misc.json for DE --- public/locales/de/game-misc.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/public/locales/de/game-misc.json b/public/locales/de/game-misc.json index 446fe7423..4e3c81ce7 100644 --- a/public/locales/de/game-misc.json +++ b/public/locales/de/game-misc.json @@ -10,5 +10,10 @@ "STAGE_8": "Perlmutt-Akademie", "STAGE_9": "Störwerft", "STAGE_10": "Cetacea-Markt", - "STAGE_11": "Flunder-Funpark" + "STAGE_11": "Flunder-Funpark", + "MODE_SHORT_TW": "RK", + "MODE_SHORT_SZ": "HS", + "MODE_SHORT_TC": "TK", + "MODE_SHORT_RM": "OG", + "MODE_SHORT_CB": "MC" } From 71998bf4852020fd57f56e11ee38c275eb08d639 Mon Sep 17 00:00:00 2001 From: lolametro <13728127+lolametro@users.noreply.github.com> Date: Sat, 22 Oct 2022 11:17:18 +0200 Subject: [PATCH 6/8] Merge existing and new locs in common.json DE --- public/locales/de/common.json | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/public/locales/de/common.json b/public/locales/de/common.json index 99e54e858..6b8866bda 100644 --- a/public/locales/de/common.json +++ b/public/locales/de/common.json @@ -16,8 +16,8 @@ "auth.errors.aborted": "Einloggen abgebrochen", "auth.errors.failed": "Einloggen fehlgeschlagen", - "auth.errors.discordPermissions": "Für dein sendou.ink-Profil wird Zugriff auf den Namen, Avatar und Social-Media-Verlinkungen in deinem Discord-Profil benötigt.", - "auth.errors.unknown": "Das Einloggen über Discord ist aus einem unbekannten Grund fehlgeschlagen. Falls das weiterhin passiert, kontaktiere bitte für mehr Hilfe.", + "auth.errors.discordPermissions": "Für dein sendou.ink-Profil benötigt die Seite Zugriff auf den Namen, Avatar und verbundene Social-Media-Accounts in deinem Discord-Profil.", + "auth.errors.unknown": "Das Einloggen via Discord ist aus unbekannten Gründen fehlgeschlagen. Falls dies wiederholt auftritt, kontaktiere uns bitte.", "footer.github.subtitle": "Sourcecode", "footer.twitter.subtitle": "Updates", @@ -67,9 +67,4 @@ "weapon.category.BRELLAS": "Pluviatoren", "weapon.category.STRINGERS": "Stringer", "weapon.category.SPLATANAS": "Splatanas", - - "auth.errors.aborted": "Login Abgebrochen", - "auth.errors.failed": "Login Fehlgeschlagen", - "auth.errors.discordPermissions": "Für dein sendou.ink Profil braucht die Seite die Erlaubnis deinen Discord-Namen, Avatar, und verbundene Social Accounts auszulesen.", - "auth.errors.unknown": "Der Login via Discord ist aus unbekannten Gründen fehlgeschlagen. Falls dies wiederholt auftritt, kontaktiere uns bitte." } From e705c58ebb3caa580e80430bccbf6ea727957c6a Mon Sep 17 00:00:00 2001 From: Kalle <38327916+Sendouc@users.noreply.github.com> Date: Sat, 22 Oct 2022 12:40:36 +0300 Subject: [PATCH 7/8] More type safety to SendouRouteHandle.navItemName --- app/utils/remix.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/utils/remix.ts b/app/utils/remix.ts index 3bf68b402..f54507633 100644 --- a/app/utils/remix.ts +++ b/app/utils/remix.ts @@ -1,6 +1,7 @@ import { z } from "zod"; import { type TFunction, type Namespace } from "react-i18next"; import { type RouteMatch } from "@remix-run/react"; +import type navItems from "~/components/layout/nav-items.json"; export function notFoundIfFalsy(value: T | null | undefined): T { if (!value) throw new Response(null, { status: 404 }); @@ -113,5 +114,5 @@ export type SendouRouteHandle = { }) => string | undefined; /** The name of a navItem that is active on this route. See nav-items.json */ - navItemName?: string; + navItemName?: typeof navItems[number]["name"]; }; From ce50e62172b0e39e4a73f8b556662424b384a8c5 Mon Sep 17 00:00:00 2001 From: Kalle <38327916+Sendouc@users.noreply.github.com> Date: Sat, 22 Oct 2022 12:43:13 +0300 Subject: [PATCH 8/8] Run check-translation-jsons --- public/locales/de/common.json | 6 ++--- translation-progress.md | 45 ++++++----------------------------- 2 files changed, 10 insertions(+), 41 deletions(-) diff --git a/public/locales/de/common.json b/public/locales/de/common.json index 6b8866bda..af292c7b5 100644 --- a/public/locales/de/common.json +++ b/public/locales/de/common.json @@ -13,7 +13,7 @@ "header.profile": "Profil", "header.logout": "Ausloggen", "header.login": "Einloggen", - + "auth.errors.aborted": "Einloggen abgebrochen", "auth.errors.failed": "Einloggen fehlgeschlagen", "auth.errors.discordPermissions": "Für dein sendou.ink-Profil benötigt die Seite Zugriff auf den Namen, Avatar und verbundene Social-Media-Accounts in deinem Discord-Profil.", @@ -34,7 +34,7 @@ "actions.delete": "Löschen", "actions.loadMore": "Mehr laden", "actions.close": "Schließen", - + "maps.createMapList": "Arenen-Liste erstellen", "maps.halfSz": "50% Herrschaft", "maps.mapPool": "Arenen-Pool", @@ -66,5 +66,5 @@ "weapon.category.DUALIES": "Doppler", "weapon.category.BRELLAS": "Pluviatoren", "weapon.category.STRINGERS": "Stringer", - "weapon.category.SPLATANAS": "Splatanas", + "weapon.category.SPLATANAS": "Splatanas" } diff --git a/translation-progress.md b/translation-progress.md index 5a12774e0..e8a162076 100644 --- a/translation-progress.md +++ b/translation-progress.md @@ -80,31 +80,18 @@ **11/11** -### 🟡 calendar.json +### 🟢 calendar.json -**44/46** - -
-Missing - -- createMapList -- forms.mapPool - -
+**46/46** ### 🟡 common.json -**54/60** +**59/60**
Missing -- pages.maps - actions.copyToClipboard -- maps.createMapList -- maps.halfSz -- maps.mapPool -- maps.tournamentMaplist
@@ -116,31 +103,13 @@ **6/6** -### 🟡 front.json +### 🟢 front.json -**10/11** +**11/11** -
-Missing +### 🟢 game-misc.json -- maps.description - -
- -### 🟡 game-misc.json - -**12/17** - -
-Missing - -- MODE_SHORT_TW -- MODE_SHORT_SZ -- MODE_SHORT_TC -- MODE_SHORT_RM -- MODE_SHORT_CB - -
+**17/17** ### 🟢 user.json