diff --git a/public/images/dialog/background.webp b/public/images/dialog/background.webp new file mode 100644 index 00000000..10d6ce6c Binary files /dev/null and b/public/images/dialog/background.webp differ diff --git a/public/images/dialog/button.png b/public/images/dialog/button.png new file mode 100644 index 00000000..28a3269f Binary files /dev/null and b/public/images/dialog/button.png differ diff --git a/public/images/dialog/button_highlighted.png b/public/images/dialog/button_highlighted.png new file mode 100644 index 00000000..47fa0074 Binary files /dev/null and b/public/images/dialog/button_highlighted.png differ diff --git a/public/images/dialog/checkbox.png b/public/images/dialog/checkbox.png new file mode 100644 index 00000000..80a9e0c8 Binary files /dev/null and b/public/images/dialog/checkbox.png differ diff --git a/public/images/dialog/checkbox_selected.png b/public/images/dialog/checkbox_selected.png new file mode 100644 index 00000000..09aa39eb Binary files /dev/null and b/public/images/dialog/checkbox_selected.png differ diff --git a/public/images/dialog/slider.png b/public/images/dialog/slider.png new file mode 100644 index 00000000..5bc4404c Binary files /dev/null and b/public/images/dialog/slider.png differ diff --git a/public/images/dialog/slider_handle.png b/public/images/dialog/slider_handle.png new file mode 100644 index 00000000..67bb864e Binary files /dev/null and b/public/images/dialog/slider_handle.png differ diff --git a/public/images/dialog/text_field.png b/public/images/dialog/text_field.png new file mode 100644 index 00000000..655d0935 Binary files /dev/null and b/public/images/dialog/text_field.png differ diff --git a/public/images/dialog/warning_button.png b/public/images/dialog/warning_button.png new file mode 100644 index 00000000..5f4cd841 Binary files /dev/null and b/public/images/dialog/warning_button.png differ diff --git a/public/images/dialog/warning_button_highlighted.png b/public/images/dialog/warning_button_highlighted.png new file mode 100644 index 00000000..95743f9c Binary files /dev/null and b/public/images/dialog/warning_button_highlighted.png differ diff --git a/src/app/components/generator/PreviewPanel.tsx b/src/app/components/generator/PreviewPanel.tsx index fe30da09..a2a11334 100644 --- a/src/app/components/generator/PreviewPanel.tsx +++ b/src/app/components/generator/PreviewPanel.tsx @@ -5,9 +5,9 @@ import { useVersion } from '../../contexts/Version.jsx' import { checkVersion } from '../../services/index.js' import { safeJsonParse } from '../../Utils.js' import { ErrorPanel } from '../ErrorPanel.jsx' -import { BiomeSourcePreview, BlockStatePreview, DecoratorPreview, DensityFunctionPreview, ItemModelPreview, LootTablePreview, ModelPreview, NoisePreview, NoiseSettingsPreview, RecipePreview, StructureSetPreview } from '../previews/index.js' +import { BiomeSourcePreview, BlockStatePreview, DecoratorPreview, DensityFunctionPreview, DialogPreview, ItemModelPreview, LootTablePreview, ModelPreview, NoisePreview, NoiseSettingsPreview, RecipePreview, StructureSetPreview } from '../previews/index.js' -export const HasPreview = ['loot_table', 'recipe', 'dimension', 'worldgen/density_function', 'worldgen/noise', 'worldgen/noise_settings', 'worldgen/configured_feature', 'worldgen/placed_feature', 'worldgen/structure_set', 'block_definition', 'item_definition', 'model'] +export const HasPreview = ['loot_table', 'recipe', 'dialog', 'dimension', 'worldgen/density_function', 'worldgen/noise', 'worldgen/noise_settings', 'worldgen/configured_feature', 'worldgen/placed_feature', 'worldgen/structure_set', 'block_definition', 'item_definition', 'model'] type PreviewPanelProps = { id: string, @@ -50,6 +50,10 @@ export function PreviewContent({ id, docAndNode, shown }: PreviewContentProps) { return } + if (id === 'dialog') { + return + } + if (id === 'dimension' && safeJsonParse(docAndNode.doc.getText())?.generator?.type?.endsWith('noise')) { return } diff --git a/src/app/components/previews/DialogPreview.tsx b/src/app/components/previews/DialogPreview.tsx new file mode 100644 index 00000000..4bff9e21 --- /dev/null +++ b/src/app/components/previews/DialogPreview.tsx @@ -0,0 +1,240 @@ +import { Identifier, ItemStack } from 'deepslate' +import type { ComponentChild } from 'preact' +import { useEffect, useRef } from 'preact/hooks' +import { safeJsonParse } from '../../Utils.js' +import { ItemDisplay } from '../ItemDisplay.jsx' +import { TextComponent } from '../TextComponent.jsx' +import type { PreviewProps } from './index.js' + +export const DialogPreview = ({ docAndNode }: PreviewProps) => { + const overlay = useRef(null) + + const text = docAndNode.doc.getText() + const dialog = safeJsonParse(text) ?? {} + const type = dialog.type?.replace(/^minecraft:/, '') + const footerHeight = type === 'multi_action_input_form' ? 5 : 33 + + useEffect(() => { + function resizeHandler() { + if (!overlay.current) return + const width = Math.floor(overlay.current.clientWidth) + overlay.current.style.setProperty('--dialog-px', `${width/400}px`) + } + resizeHandler() + window.addEventListener('resize', resizeHandler) + return () => window.removeEventListener('resize', resizeHandler) + }, [overlay]) + + return <> +
+ +
+ +
+ + +
+
+ +
+
+
+ +} + +function DialogTitle({ title }: { title: any }) { + // TODO: add warning button tooltip + return
+ +
+
+} + +function DialogBody({ body }: { body: any }) { + if (!body) { + body = [] + } else if (!Array.isArray(body)) { + body = [body] + } + return <> + {body?.map((b: any) => { + const type = b.type?.replace(/^minecraft:/, '') + if (type === 'plain_message') { + // TODO: make this text wrap + return
+ +
+ } + if (type == 'item') { + // TODO: add item components + const item = new ItemStack(Identifier.parse(b.item?.id ?? 'air'), b.show_decorations ? (b.item?.count ?? 1) : 1) + console.log(item) + return
+
+ +
+ {b.description &&
+ +
} +
+ } + return <> + })} + +} + +function DialogContent({ dialog }: { dialog: any }) { + const type = dialog.type?.replace(/^minecraft:/, '') + + if (type === 'dialog_list') { + let dialogs = [] + if (Array.isArray(dialog.dialogs)) { + dialogs = dialog.dialogs + } else if (typeof dialog.dialogs === 'string') { + dialogs = [dialog.dialogs] + } + return + {dialogs.map((d: any) => { + let text = Identifier.parse(d).path.replaceAll('/', ' ').replaceAll('_', ' ') + text = text.charAt(0).toUpperCase() + text.substring(1) + return