import { useMemo, useEffect } from 'react';
import { useShallow } from 'zustand/react/shallow';
import { BiSolidHeart } from 'react-icons/bi/index';
import { Howler } from 'howler';
import { I18nextProvider } from 'react-i18next';
import i18n from '@/i18n';
import { useSoundStore } from '@/stores/sound';
import { Container } from '@/components/container';
import { StoreConsumer } from '@/components/store-consumer';
import { Buttons } from '@/components/buttons';
import { Categories } from '@/components/categories';
import { SharedModal } from '@/components/modals/shared';
import { Toolbar } from '@/components/toolbar';
import { SnackbarProvider } from '@/contexts/snackbar';
import { MediaControls } from '@/components/media-controls';
import { sounds } from '@/data/sounds';
import { FADE_OUT } from '@/constants/events';
import type { Sound, Category as CategoryType } from '@/data/types';
import { subscribe } from '@/lib/event';
interface AppProps {
locale: string;
}
export function App({ locale }: AppProps) {
if (locale && i18n.language !== locale) {
i18n.changeLanguage(locale);
}
const categoriesData = useMemo(() => sounds.categories, []);
const favorites = useSoundStore(useShallow(state => state.getFavorites()));
const pause = useSoundStore(state => state.pause);
const lock = useSoundStore(state => state.lock);
const unlock = useSoundStore(state => state.unlock);
const favoriteSounds = useMemo(() => {
const allFlatSounds = categoriesData
.map(category => category.sounds)
.flat();
const favoriteSoundsData = allFlatSounds.filter(sound =>
favorites.includes(sound.id),
);
return favorites
.map(favoriteId =>
favoriteSoundsData.find(sound => sound.id === favoriteId),
)
.filter((s): s is Sound => s !== undefined);
}, [favorites, categoriesData]);
useEffect(() => {
const onChange = () => {
const { ctx } = Howler;
if (ctx && !document.hidden) {
setTimeout(() => {
ctx.resume();
}, 100);
}
};
document.addEventListener('visibilitychange', onChange, false);
return () => document.removeEventListener('visibilitychange', onChange);
}, []);
useEffect(() => {
const unsubscribe = subscribe(FADE_OUT, (e: { duration: number }) => {
lock();
setTimeout(() => {
pause();
unlock();
}, e.duration);
});
return unsubscribe;
}, [pause, lock, unlock]);
const allCategories = useMemo(() => {
const favs: CategoryType[] = [];
if (favoriteSounds.length) {
favs.push({
icon: ,
id: 'favorites',
sounds: favoriteSounds,
titleKey: 'sounds.favorites.title',
});
}
return [...favs, ...categoriesData];
}, [favoriteSounds, categoriesData]);
return (
);
}