diff --git a/src/app/(infoscreen)/@sponsors/page.tsx b/src/app/(infoscreen)/@sponsors/page.tsx index 41ddb34..6f85da1 100644 --- a/src/app/(infoscreen)/@sponsors/page.tsx +++ b/src/app/(infoscreen)/@sponsors/page.tsx @@ -1,6 +1,7 @@ 'use client'; import { Slide } from '@/components/Carousel'; +import I18n from '@/components/I18n/I18n'; import { getSponsorData, type SponsorData } from '@/server/sponsors'; import { useEffect, useState } from 'react'; @@ -18,7 +19,7 @@ const Sponsors = () => { return (

- Yhteistyökumppanit + Yhteistyökumppanit // Sponsors

{sponsors?.filter((sponsor) => sponsor.logoUrl).map((sponsor) => ( diff --git a/src/app/LanguageInterval.tsx b/src/app/LanguageInterval.tsx index 0ca10ef..fb350d2 100644 --- a/src/app/LanguageInterval.tsx +++ b/src/app/LanguageInterval.tsx @@ -1,23 +1,24 @@ 'use client'; -import { langAtom } from '@/lib/lang'; +import { doLangCycleAtom, langAtom } from '@/lib/lang'; import { useAtom } from 'jotai'; import { useEffect } from 'react'; export const LanguageInterval = () => { const [lang, setlang] = useAtom(langAtom); + const [doLangCycle] = useAtom(doLangCycleAtom); useEffect(() => { // Interval for switching language in event titles etc. const langInterval = setInterval( - () => setlang(((lang + 1) % 2) as 0 | 1), + () => { if (doLangCycle) setlang(lang === 0 ? 1 : 0) }, 10 * 1000 ); return () => { clearInterval(langInterval); }; - }, [lang, setlang]); + }, [doLangCycle, lang, setlang]); return null; }; diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 063b294..948b112 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,3 +1,4 @@ +import { LanguageCycle } from '@/components/LanguageCycle'; import { getServerVersion } from '@/server/version'; import { Provider } from 'jotai'; import type { Metadata } from 'next'; @@ -32,6 +33,7 @@ export default async function RootLayout({ {children} + diff --git a/src/components/Carousel.tsx b/src/components/Carousel.tsx index e42ff3c..c1d0345 100644 --- a/src/components/Carousel.tsx +++ b/src/components/Carousel.tsx @@ -59,13 +59,20 @@ export const Carousel = ({ // Register keyboard event listener to document on mount useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { - if (e.key === 'ArrowRight') { - emblaApi?.scrollNext(); - e.preventDefault(); - } - if (e.key === 'ArrowLeft') { - emblaApi?.scrollPrev(); - e.preventDefault(); + const slideNumber = parseInt(e.key); + const slideCount = emblaApi?.slideNodes().length || 0; + if (!isNaN(slideNumber) && slideNumber >= 0 && slideNumber < slideCount) + emblaApi?.scrollTo(slideNumber, true) + + switch (e.key) { + case 'ArrowRight': + emblaApi?.scrollNext(); + e.preventDefault(); + break; + case 'ArrowLeft': + emblaApi?.scrollPrev(); + e.preventDefault(); + break; } }; @@ -87,7 +94,7 @@ export const Carousel = ({ className={`${autoplay ? 'invisible' : 'visible'} absolute bottom-8 right-8 z-50 rounded bg-white/0 p-2 hover:bg-white/30`} onClick={resumeAutoplay} > - +
); diff --git a/src/components/LanguageCycle.tsx b/src/components/LanguageCycle.tsx new file mode 100644 index 0000000..d2aa29e --- /dev/null +++ b/src/components/LanguageCycle.tsx @@ -0,0 +1,41 @@ +'use client'; + +import { doLangCycleAtom, langAtom } from '@/lib/lang'; +import { useAtom } from 'jotai'; +import { useEffect, useRef } from 'react'; + +export const LanguageCycle = () => { + // For toggling language with 'l' + const [lang, setLang] = useAtom(langAtom); + // For disabling language cycling briefly after language has been manually toggled + const [, setDoLangCycle] = useAtom(doLangCycleAtom); + + const timeoutRef = useRef(null); + + // Register keyboard event listener to document on mount + useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + if (e.key === 'l') { + setLang(lang === 0 ? 1 : 0); + setDoLangCycle(false); + e.preventDefault(); + + if (timeoutRef.current) + clearTimeout(timeoutRef.current); + + timeoutRef.current = setTimeout( + () => setDoLangCycle(true), + 30 * 1000 + ); + } + }; + + document.addEventListener('keydown', handleKeyDown); + return () => { + document.removeEventListener('keydown', handleKeyDown); + if (timeoutRef.current) clearTimeout(timeoutRef.current); + } + }, [lang, setLang, setDoLangCycle]); + + return null; +}; \ No newline at end of file diff --git a/src/lib/lang.ts b/src/lib/lang.ts index 35f22ba..7583e5d 100644 --- a/src/lib/lang.ts +++ b/src/lib/lang.ts @@ -5,3 +5,8 @@ import { atom, useAtomValue } from 'jotai'; export const langAtom = atom<0 | 1>(0); export const useLang = () => useAtomValue(langAtom); + +//When true language isn't cycled automatically +export const doLangCycleAtom = atom(true); + +export const useLangCycle = () => useAtomValue(doLangCycleAtom); \ No newline at end of file