diff --git a/src/controls.ts b/src/controls.ts index 9430f9c1..db6a6fc6 100644 --- a/src/controls.ts +++ b/src/controls.ts @@ -818,6 +818,11 @@ export const f3Keybinds: Array<{ } ] +export const reloadChunksAction = () => { + const action = f3Keybinds.find(f3Keybind => f3Keybind.key === 'KeyA') + void action!.action() +} + document.addEventListener('keydown', (e) => { if (!isGameActive(false)) return if (contro.pressedKeys.has('F3')) { @@ -987,14 +992,17 @@ export function updateBinds (commands: any) { } export const onF3LongPress = async () => { - const select = await showOptionsModal('', f3Keybinds.filter(f3Keybind => { + const actions = f3Keybinds.filter(f3Keybind => { return f3Keybind.mobileTitle && (f3Keybind.enabled?.() ?? true) - }).map(f3Keybind => { + }) + const actionNames = actions.map(f3Keybind => { return `${f3Keybind.mobileTitle}${f3Keybind.key ? ` (F3+${f3Keybind.key})` : ''}` - })) + }) + const select = await showOptionsModal('', actionNames) if (!select) return - const f3Keybind = f3Keybinds.find(f3Keybind => f3Keybind.mobileTitle === select) - if (f3Keybind) void f3Keybind.action() + const actionIndex = actionNames.indexOf(select) + const f3Keybind = actions[actionIndex]! + void f3Keybind.action() } export const handleMobileButtonCustomAction = (action: CustomAction) => { diff --git a/src/react/OptionsItems.tsx b/src/react/OptionsItems.tsx index 32f99b9e..ccc04bcb 100644 --- a/src/react/OptionsItems.tsx +++ b/src/react/OptionsItems.tsx @@ -4,11 +4,13 @@ import { titleCase } from 'title-case' import { useMemo } from 'react' import { disabledSettings, options, qsOptions } from '../optionsStorage' import { hideAllModals, miscUiState } from '../globalState' +import { reloadChunksAction } from '../controls' import Button from './Button' import Slider from './Slider' import Screen from './Screen' import { showOptionsModal } from './SelectOption' import PixelartIcon, { pixelartIcons } from './PixelartIcon' +import { reconnectReload } from './AppStatusProvider' type GeneralItem = { id?: string @@ -18,7 +20,8 @@ type GeneralItem = { tooltip?: string // description?: string enableWarning?: string - willHaveNoEffect?: boolean + requiresRestart?: boolean + requiresChunksReload?: boolean values?: Array disableIf?: [option: keyof typeof options, value: any] } @@ -56,7 +59,14 @@ const useCommonComponentsProps = (item: OptionMeta) => { } } -export const OptionButton = ({ item }: { item: Extract }) => { +const ignoreReloadWarningsCache = new Set() + +export const OptionButton = ({ item, onClick, valueText, cacheKey }: { + item: Extract, + onClick?: () => void, + valueText?: string, + cacheKey?: string, +}) => { const { disabledBecauseOfSetting } = useCommonComponentsProps(item) const optionValue = useSnapshot(options)[item.id!] @@ -84,40 +94,63 @@ export const OptionButton = ({ item }: { item: Extract { if (disabledReason) { - await showOptionsModal(`The option is unavailable. ${disabledReason}`, []) + await showOptionsModal(`${translate('The option is not available')}: ${disabledReason}`, []) return } if (item.enableWarning && !options[item.id!]) { const result = await showOptionsModal(item.enableWarning, ['Enable']) if (!result) return } - const { values } = item - if (values) { - const getOptionValue = (arrItem) => { - if (typeof arrItem === 'string') { - return arrItem + onClick?.() + if (item.id) { + const { values } = item + if (values) { + const getOptionValue = (arrItem) => { + if (typeof arrItem === 'string') { + return arrItem + } else { + return arrItem[0] + } + } + const currentIndex = values.findIndex((value) => { + return getOptionValue(value) === optionValue + }) + if (currentIndex === -1) { + options[item.id] = getOptionValue(values[0]) } else { - return arrItem[0] + const nextIndex = event.shiftKey + ? (currentIndex - 1 + values.length) % values.length + : (currentIndex + 1) % values.length + options[item.id] = getOptionValue(values[nextIndex]) + } + } else { + options[item.id] = !options[item.id] + } + } + + const toCacheKey = cacheKey ?? item.id ?? '' + if (toCacheKey && !ignoreReloadWarningsCache.has(toCacheKey)) { + ignoreReloadWarningsCache.add(toCacheKey) + + if (item.requiresRestart) { + const result = await showOptionsModal(translate('The option requires a restart to take effect'), ['Restart', 'I will do it later'], { + cancel: false, + }) + if (result) { + reconnectReload() } } - const currentIndex = values.findIndex((value) => { - return getOptionValue(value) === optionValue - }) - if (currentIndex === -1) { - options[item.id!] = getOptionValue(values[0]) - } else { - const nextIndex = event.shiftKey - ? (currentIndex - 1 + values.length) % values.length - : (currentIndex + 1) % values.length - options[item.id!] = getOptionValue(values[nextIndex]) + if (item.requiresChunksReload) { + const result = await showOptionsModal(translate('The option requires a chunks reload to take effect'), ['Reload', 'I will do it later'], { + cancel: false, + }) + if (result) { + reloadChunksAction() + } } - } else { - options[item.id!] = !options[item.id!] } }} title={disabledReason ? `${disabledReason} | ${item.tooltip}` : item.tooltip}