import { proxy, useSnapshot } from 'valtio' import { useEffect, useRef } from 'react' import { noCase } from 'change-case' import { titleCase } from 'title-case' import { hideCurrentModal, showModal } from '../globalState' import { parseFormattedMessagePacket } from '../botUtils' import Screen from './Screen' import { useIsModalActive } from './utilsApp' import Button from './Button' import MessageFormattedString from './MessageFormattedString' import Input, { InputWithLabel } from './Input' const state = proxy({ title: '', options: [] as string[], showCancel: true, minecraftJsonMessage: null as null | Record, behavior: 'resolve-close' as 'resolve-close' | 'close-resolve', inputs: {} as Record, inputsConfirmButton: '' }) let resolve export const showOptionsModal = async ( title: string, options: T[], { cancel = true, minecraftJsonMessage }: { cancel?: boolean, minecraftJsonMessage? } = {} ): Promise => { showModal({ reactType: 'general-select' }) let minecraftJsonMessageParsed if (minecraftJsonMessage) { const parseResult = parseFormattedMessagePacket(minecraftJsonMessage) minecraftJsonMessageParsed = parseResult.formatted if (parseResult.plain) { title += ` (${parseResult.plain})` } } return new Promise((_resolve) => { resolve = _resolve Object.assign(state, { title, options, showCancel: cancel, minecraftJsonMessage: minecraftJsonMessageParsed, inputs: {}, inputsConfirmButton: '' }) }) } type InputOption = { type: 'text' | 'checkbox' defaultValue?: string | boolean label?: string } export const showInputsModal = async >( title: string, inputs: T, { cancel = true, minecraftJsonMessage }: { cancel?: boolean, minecraftJsonMessage? } = {} ): Promise<{ [K in keyof T]: T[K] extends { type: 'text' } ? string : T[K] extends { type: 'checkbox' } ? boolean : never }> => { showModal({ reactType: 'general-select' }) let minecraftJsonMessageParsed if (minecraftJsonMessage) { const parseResult = parseFormattedMessagePacket(minecraftJsonMessage) minecraftJsonMessageParsed = parseResult.formatted if (parseResult.plain) { title += ` (${parseResult.plain})` } } return new Promise((_resolve) => { resolve = _resolve Object.assign(state, { title, inputs, showCancel: cancel, minecraftJsonMessage: minecraftJsonMessageParsed, options: [], inputsConfirmButton: 'Confirm' }) }) } export default () => { const { title, options, showCancel, minecraftJsonMessage, inputs, inputsConfirmButton } = useSnapshot(state) const isModalActive = useIsModalActive('general-select') const inputValues = useRef({}) useEffect(() => { inputValues.current = Object.fromEntries(Object.entries(inputs).map(([key, input]) => [key, input.defaultValue ?? (input.type === 'checkbox' ? false : '')])) }, [inputs]) if (!isModalActive) return const resolveClose = (value: any) => { if (state.behavior === 'resolve-close') { resolve(value) hideCurrentModal() } else { hideCurrentModal() resolve(value) } } return {minecraftJsonMessage &&
}
{options.length > 0 &&
{options.map(option => )}
}
{Object.entries(inputs).map(([key, input]) => { const label = input.label ?? titleCase(noCase(key)) return
{input.type === 'text' && ( { inputValues.current[key] = e.target.value }} /> )} {input.type === 'checkbox' && ( )}
})}
{inputs && inputsConfirmButton && ( )} {showCancel && ( )}
}