diff --git a/src/components/AppLayout.tsx b/src/components/AppLayout.tsx index 8a9efd0..a7f21aa 100644 --- a/src/components/AppLayout.tsx +++ b/src/components/AppLayout.tsx @@ -14,6 +14,7 @@ import { import { useEffect, useState } from "react"; import { useSwipeable } from "react-swipeable"; import { ImageQuality } from "./Img"; +import OrderableList from "./OrderableList"; import MainPanel from "./Panels/MainPanel"; import Popup from "./Popup"; import Select from "./Select"; @@ -250,154 +251,177 @@ export default function AppLayout(props: Props): JSX.Element { - -

{langui.select_language}

-
- {router.locales?.map((locale) => ( - - ))} -
-
-

{langui.settings}

-
-
-

{langui.theme}

-
- - - -
-
- -
-

{langui.currency}

+
+ {router.locales && (
- +
+
+ +
+

{langui.font_size}

+
+ + + +
+
+ +
+

{langui.font}

+
+ + +
+
+ +
+

{langui.player_name}

+ + appLayout.setPlayerName( + (event.target as HTMLInputElement).value + ) + } />
- -
-

{langui.font_size}

-
- - - -
-
- -
-

{langui.font}

-
- - -
-
- -
-

{langui.player_name}

- - appLayout.setPlayerName( - (event.target as HTMLInputElement).value - ) - } - /> -
diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 876b97e..c5aa7d6 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -10,7 +10,7 @@ interface Props { locale?: string; target?: "_blank"; onClick?: MouseEventHandler; - draggable?: boolean + draggable?: boolean; } export default function Button(props: Props): JSX.Element { diff --git a/src/components/OrderableList.tsx b/src/components/OrderableList.tsx new file mode 100644 index 0000000..c539909 --- /dev/null +++ b/src/components/OrderableList.tsx @@ -0,0 +1,69 @@ +import { arrayMove } from "queries/helpers"; +import { useEffect, useState } from "react"; + +interface Props { + className?: string; + items: Map; + onChange?: (items: Map) => void; +} + +export default function LanguageSwitcher(props: Props): JSX.Element { + const [items, setItems] = useState>(props.items); + + useEffect(() => { + props.onChange?.(items); + }, [items]); + + return ( +
+ {[...items].map(([key, value], index) => ( + <> + {index === 0 ? ( +

Primary language

+ ) : index === 1 ? ( +

Secondary languages

+ ) : ( + "" + )} +
{ + const source = event.target as HTMLElement; + const sourceIndex = source.parentElement + ? Array.from(source.parentElement.children) + .filter((element) => element.tagName === "DIV") + .indexOf(source) + : -1; + event.dataTransfer.setData("text", sourceIndex.toString()); + }} + onDragOver={(event) => { + event.preventDefault(); + }} + onDrop={(event) => { + event.preventDefault(); + const target = event.target as HTMLElement; + const targetIndex = target.parentElement + ? Array.from(target.parentElement.children) + .filter((element) => element.tagName === "DIV") + .indexOf(target) + : -1; + const sourceIndex = parseInt( + event.dataTransfer.getData("text"), + 10 + ); + const newItems = arrayMove([...items], sourceIndex, targetIndex); + setItems(new Map(newItems)); + }} + className="grid place-content-center place-items-center + border-[1px] transition-all hover:text-light hover:bg-dark + hover:drop-shadow-shade-lg border-dark bg-light text-dark + rounded-full px-4 pt-[0.4rem] pb-[0.5rem] cursor-grab select-none" + key={key} + draggable + > + {value} +
+ + ))} +
+ ); +} diff --git a/src/components/Panels/MainPanel.tsx b/src/components/Panels/MainPanel.tsx index ee8f636..64f8c04 100644 --- a/src/components/Panels/MainPanel.tsx +++ b/src/components/Panels/MainPanel.tsx @@ -89,26 +89,6 @@ export default function MainPanel(props: Props): JSX.Element { - {router.locale && ( - {langui.change_language}} - placement="right" - className="text-left" - disabled={!appLayout.mainPanelReduced} - > - - - )} - {/* {langui.open_search}} placement="right" diff --git a/src/contexts/AppLayoutContext.tsx b/src/contexts/AppLayoutContext.tsx index de506b2..79a750b 100644 --- a/src/contexts/AppLayoutContext.tsx +++ b/src/contexts/AppLayoutContext.tsx @@ -4,7 +4,6 @@ import React, { ReactNode, useContext } from "react"; interface AppLayoutState { subPanelOpen: boolean | undefined; - languagePanelOpen: boolean | undefined; configPanelOpen: boolean | undefined; mainPanelReduced: boolean | undefined; mainPanelOpen: boolean | undefined; @@ -14,10 +13,8 @@ interface AppLayoutState { dyslexic: boolean | undefined; currency: string | undefined; playerName: string | undefined; + preferredLanguages: string[] | undefined; setSubPanelOpen: React.Dispatch>; - setLanguagePanelOpen: React.Dispatch< - React.SetStateAction - >; setConfigPanelOpen: React.Dispatch>; setMainPanelReduced: React.Dispatch< React.SetStateAction @@ -31,12 +28,14 @@ interface AppLayoutState { setDyslexic: React.Dispatch>; setCurrency: React.Dispatch>; setPlayerName: React.Dispatch>; + setPreferredLanguages: React.Dispatch< + React.SetStateAction + >; } /* eslint-disable @typescript-eslint/no-empty-function */ const initialState: AppLayoutState = { subPanelOpen: false, - languagePanelOpen: false, configPanelOpen: false, mainPanelReduced: false, mainPanelOpen: false, @@ -46,8 +45,8 @@ const initialState: AppLayoutState = { dyslexic: false, currency: "USD", playerName: "", + preferredLanguages: [], setSubPanelOpen: () => {}, - setLanguagePanelOpen: () => {}, setMainPanelReduced: () => {}, setMainPanelOpen: () => {}, setDarkMode: () => {}, @@ -57,6 +56,7 @@ const initialState: AppLayoutState = { setDyslexic: () => {}, setCurrency: () => {}, setPlayerName: () => {}, + setPreferredLanguages: () => {}, }; /* eslint-enable @typescript-eslint/no-empty-function */ @@ -77,10 +77,6 @@ export function AppContextProvider(props: Props): JSX.Element { boolean | undefined >("subPanelOpen", initialState.subPanelOpen); - const [languagePanelOpen, setLanguagePanelOpen] = useStateWithLocalStorage< - boolean | undefined - >("languagePanelOpen", initialState.languagePanelOpen); - const [configPanelOpen, setConfigPanelOpen] = useStateWithLocalStorage< boolean | undefined >("configPanelOpen", initialState.configPanelOpen); @@ -115,11 +111,14 @@ export function AppContextProvider(props: Props): JSX.Element { string | undefined >("playerName", initialState.playerName); + const [preferredLanguages, setPreferredLanguages] = useStateWithLocalStorage< + string[] | undefined + >("preferredLanguages", initialState.preferredLanguages); + return ( {props.children} diff --git a/src/queries/helpers.ts b/src/queries/helpers.ts index 66cb2be..880a119 100644 --- a/src/queries/helpers.ts +++ b/src/queries/helpers.ts @@ -274,6 +274,18 @@ export function prettyLanguage( return result; } +export function prettyLanguageToCode( + prettyLanguage: string, + languages: AppStaticProps["languages"] +): string { + let result = prettyLanguage; + languages.forEach((language) => { + if (language?.attributes?.localized_name === prettyLanguage) + result = language.attributes.code; + }); + return result; +} + export function prettyTestWarning( router: NextRouter, message: string, @@ -463,3 +475,8 @@ export function getVideoThumbnailURL(uid: string): string { export function getVideoFile(uid: string): string { return `${process.env.NEXT_PUBLIC_URL_WATCH}/videos/${uid}.mp4`; } + +export function arrayMove(arr: T[], old_index: number, new_index: number) { + arr.splice(new_index, 0, arr.splice(old_index, 1)[0]); + return arr; +}