import React, { useState, useEffect, useCallback, useMemo } from 'react' import PropTypes from 'prop-types'; import { NavLink, Link, } from "react-router-dom"; import classes from '@/scss/home/Home.module.scss' import { useConfig } from '@/state/config'; import { useI18n } from '@/state/language'; import { useLanguage } from '@/state/language' import { useHeader } from '@/state/header'; import { useAppbar } from '@/state/appbar'; import VoiceElement from '@/component/voice'; import { useAtom } from 'jotai' import { atomWithStorage } from 'jotai/utils'; import CharIcon from '@/component/char_icon'; import Border from '@/component/border'; import useUmami from '@/state/insights'; import Switch from '@/component/switch'; import SearchBox from '@/component/search_box'; const voiceOnAtom = atomWithStorage('voiceOn', false) let lastVoiceState = 'ended' export default function Home() { // eslint-disable-next-line no-unused-vars const _trackEvt = useUmami('/', "Dynamic Compile") const { setTitle, setTabs, currentTab, setHeaderIcon, setFastNavigation } = useHeader() const { config, operators, officalUpdate } = useConfig() const { i18n } = useI18n() const [content, setContent] = useState([]) const [voiceOn] = useAtom(voiceOnAtom) const [voiceSrc, setVoiceSrc] = useState(null) const [voiceReplay, setVoiceReplay] = useState(false) const { language } = useLanguage() const [navigationList, setNavigationList] = useState([]) const [searchField, setSearchField] = useState(''); const [updatedList, setUpdatedList] = useState([]) useEffect(() => { setTitle('dynamic_compile') setTabs([{ key: 'all' }, { key: 'operator' }, { key: 'skin' }]) setHeaderIcon(null) }, [setHeaderIcon, setTabs, setTitle]) useEffect(() => { setContent(config?.operators || []) document.documentElement.style.setProperty('--cursor-color', 'var(--text-color)'); }, [config]) const handleAduioStateChange = useCallback((e, state) => { lastVoiceState = state if (state === 'ended') { setVoiceReplay(false) } }, []) const isShown = useCallback((type) => currentTab === 'all' || currentTab === type, [currentTab]) const fastNavigateDict = useMemo(() => { const dict = {} operators.forEach((item) => { if (!(item.date in dict)) { dict[item.date] = [] } dict[item.date].push({ codename: item.codename, link: item.link, type: item.type, color: item.color }) }) return dict }, [operators]) useEffect(() => { const list = [] for (const [key, value] of Object.entries(fastNavigateDict)) { const newValue = value.filter((item) => isShown(item.type)) if (newValue.length > 0) { list.push({ name: key, value: null, type: "date", }) newValue.forEach((item) => { list.push({ name: item.codename[language], value: item.link, type: "item", color: item.color, icon: }) }) } } setNavigationList(list) setUpdatedList(list) }, [fastNavigateDict, isShown, language]) useEffect(() => { const list = navigationList.filter((item) => { return (item.name.toLowerCase().indexOf(searchField.toLowerCase()) !== -1) || (item.type === 'date'); }) const newList = [] for (let i = 0; i < list.length - 1; i++) { const firstType = list[i].type const secondType = list[i + 1].type if (firstType === 'date' && secondType === 'date') { continue } newList.push(list[i]) } if (list.length > 0 && list[list.length - 1].type !== 'date') { newList.push(list[list.length - 1]) } setUpdatedList(newList) }, [navigationList, searchField]) useEffect(() => { setFastNavigation([ { type: "custom", component: { setSearchField(e) }} searchField={searchField} /> }, ...updatedList ]) }, [searchField, setFastNavigation, updatedList]) const handleVoicePlay = useCallback((src) => { if (!voiceOn) { setVoiceSrc(null) } else { if (src === voiceSrc && lastVoiceState === 'ended') { setVoiceReplay(true) } else { setVoiceSrc(src) } } }, [voiceOn, voiceSrc]) return (
{ officalUpdate.length > operators.length && (
{officalUpdate.length - operators.length} {i18n("new_op_wait_to_update")}
{officalUpdate[officalUpdate.latest].map((entry, index) => { return (
{entry.codename[language]}
) })}
{officalUpdate.latest}
) } { content.map((v) => { const length = v.filter((v) => isShown(v.type)).length return ( ) }) }
) } function OperatorElement({ item, hidden, handleVoicePlay }) { const { textDefaultLang, language, alternateLang } = useLanguage() const onMouseEnter = useCallback(() => { handleVoicePlay(`/${item.link}/assets/${JSON.parse(import.meta.env.VITE_VOICE_FOLDERS).main}/${import.meta.env.VITE_APP_VOICE_URL}`) document.documentElement.style.setProperty('--cursor-color', item.color); }, [handleVoicePlay, item.color, item.link]) const onMouseLeave = useCallback(() => { document.documentElement.style.setProperty('--cursor-color', 'var(--text-color)'); }, []) return useMemo(() => { return (