Add quick output inline toggle
Some checks failed
Deploy to GitHub Pages / build (push) Has been cancelled
Deploy to GitHub Pages / deploy (push) Has been cancelled

This commit is contained in:
Misode
2025-05-25 16:14:28 +02:00
parent 2c5d2434d6
commit 4f2c855d1e
2 changed files with 28 additions and 18 deletions

View File

@@ -1,6 +1,6 @@
import type { DocAndNode } from '@spyglassmc/core' import type { DocAndNode } from '@spyglassmc/core'
import { fileUtil } from '@spyglassmc/core' import { fileUtil } from '@spyglassmc/core'
import { useCallback, useEffect, useRef, useState } from 'preact/hooks' import { useCallback, useEffect, useMemo, useRef, useState } from 'preact/hooks'
import { useLocale } from '../../contexts/index.js' import { useLocale } from '../../contexts/index.js'
import { useDocAndNode, useSpyglass } from '../../contexts/Spyglass.jsx' import { useDocAndNode, useSpyglass } from '../../contexts/Spyglass.jsx'
import { useLocalStorage } from '../../hooks/index.js' import { useLocalStorage } from '../../hooks/index.js'
@@ -12,7 +12,7 @@ import { Btn, BtnMenu } from '../index.js'
interface Editor { interface Editor {
getValue(): string getValue(): string
setValue(value: string): void setValue(value: string): void
configure(indent: string, format: string): void configure(indent: string, format: string, wrap: boolean): void
select(): void select(): void
} }
@@ -27,9 +27,10 @@ type SourcePanelProps = {
export function SourcePanel({ docAndNode, doCopy, doDownload, doImport, copySuccess, onError }: SourcePanelProps) { export function SourcePanel({ docAndNode, doCopy, doDownload, doImport, copySuccess, onError }: SourcePanelProps) {
const { locale } = useLocale() const { locale } = useLocale()
const { service } = useSpyglass() const { service } = useSpyglass()
const [indent, setIndent] = useState(Store.getIndent()) const [cIndent, setIndent] = useState(Store.getIndent())
const [format, setFormat] = useState(Store.getFormat()) const [cFormat, setFormat] = useState(Store.getFormat())
const [sort, setSort] = useLocalStorage('misode_output_sort', 'schema') const [inline, setInline] = useLocalStorage('misode_output_inline', false, (s) => s === 'true', (b) => b ? 'true' : 'false')
// const [sort, setSort] = useLocalStorage('misode_output_sort', 'schema')
const [highlighting, setHighlighting] = useState(Store.getHighlighting()) const [highlighting, setHighlighting] = useState(Store.getHighlighting())
const [braceLoaded, setBraceLoaded] = useState(false) const [braceLoaded, setBraceLoaded] = useState(false)
const download = useRef<HTMLAnchorElement>(null) const download = useRef<HTMLAnchorElement>(null)
@@ -40,13 +41,14 @@ export function SourcePanel({ docAndNode, doCopy, doDownload, doImport, copySucc
const textarea = useRef<HTMLTextAreaElement>(null) const textarea = useRef<HTMLTextAreaElement>(null)
const editor = useRef<Editor>() const editor = useRef<Editor>()
const { indent, format } = useMemo(() => {
return inline ? { indent: 'minified', format: 'snbt' } : { indent: cIndent, format: cFormat }
}, [cIndent, cFormat, inline])
const getSerializedOutput = useCallback((text: string) => { const getSerializedOutput = useCallback((text: string) => {
// TODO: implement sort // TODO: implement sort
// if (sort === 'alphabetically') {
// data = sortData(data)
// }
return stringifySource(text, format, indent) return stringifySource(text, format, indent)
}, [indent, format, sort]) }, [indent, format])
const text = useDocAndNode(docAndNode)?.doc.getText() const text = useDocAndNode(docAndNode)?.doc.getText()
@@ -89,7 +91,7 @@ export function SourcePanel({ docAndNode, doCopy, doDownload, doImport, copySucc
console.error(e) console.error(e)
} }
} }
}, [service, docAndNode, text, indent, format, sort, highlighting]) }, [service, docAndNode, text, indent, format, highlighting])
useEffect(() => { useEffect(() => {
if (highlighting) { if (highlighting) {
@@ -111,6 +113,7 @@ export function SourcePanel({ docAndNode, doCopy, doDownload, doImport, copySucc
showFoldWidgets: false, showFoldWidgets: false,
highlightSelectedWord: false, highlightSelectedWord: false,
scrollPastEnd: 0.5, scrollPastEnd: 0.5,
indentedSoftWrap: false,
}) })
braceEditor.$blockScrolling = Infinity braceEditor.$blockScrolling = Infinity
braceEditor.on('blur', () => onImport.current()) braceEditor.on('blur', () => onImport.current())
@@ -123,7 +126,8 @@ export function SourcePanel({ docAndNode, doCopy, doDownload, doImport, copySucc
setValue(value) { setValue(value) {
braceEditor.getSession().setValue(value) braceEditor.getSession().setValue(value)
}, },
configure(indent, format) { configure(indent, format, wrap) {
braceEditor.setOption('wrap', wrap)
braceEditor.setOption('useSoftTabs', indent !== 'tabs') braceEditor.setOption('useSoftTabs', indent !== 'tabs')
braceEditor.setOption('tabSize', indent === 'tabs' ? 4 : getSourceIndent(indent)) braceEditor.setOption('tabSize', indent === 'tabs' ? 4 : getSourceIndent(indent))
braceEditor.getSession().setMode(`ace/mode/${format}`) braceEditor.getSession().setMode(`ace/mode/${format}`)
@@ -144,7 +148,11 @@ export function SourcePanel({ docAndNode, doCopy, doDownload, doImport, copySucc
if (!textarea.current) return if (!textarea.current) return
textarea.current.value = value textarea.current.value = value
}, },
configure() {}, configure(_indent, _format, wrap) {
if (!textarea.current) return
textarea.current.style.wordBreak = wrap ? 'break-all' : 'unset'
textarea.current.style.whiteSpace = wrap ? 'wrap' : 'pre'
},
select() {}, select() {},
} }
} }
@@ -159,10 +167,10 @@ export function SourcePanel({ docAndNode, doCopy, doDownload, doImport, copySucc
useEffect(() => { useEffect(() => {
if (!editor.current || !retransform.current) return if (!editor.current || !retransform.current) return
if (!highlighting || braceLoaded) { if (!highlighting || braceLoaded) {
editor.current.configure(indent, format === 'snbt' ? 'yaml' : format) editor.current.configure(indent, format === 'snbt' ? 'yaml' : format, inline)
retransform.current() retransform.current()
} }
}, [indent, format, sort, highlighting, braceLoaded]) }, [indent, format, inline, highlighting, braceLoaded])
useEffect(() => { useEffect(() => {
if (doCopy && outputRef.current) { if (doCopy && outputRef.current) {
@@ -217,18 +225,19 @@ export function SourcePanel({ docAndNode, doCopy, doDownload, doImport, copySucc
{window.matchMedia('(pointer: coarse)').matches && <> {window.matchMedia('(pointer: coarse)').matches && <>
<Btn icon="paste" onClick={importFromClipboard} /> <Btn icon="paste" onClick={importFromClipboard} />
</>} </>}
<Btn label={locale('inline')} active={inline} onClick={() => setInline(!inline)} />
<BtnMenu icon="gear" tooltip={locale('output_settings')}> <BtnMenu icon="gear" tooltip={locale('output_settings')}>
{getSourceIndents().map(key => {getSourceIndents().map(key =>
<Btn label={locale(`indentation.${key}`)} active={indent === key} <Btn label={locale(`indentation.${key}`)} active={cIndent === key}
onClick={() => changeIndent(key)}/> onClick={() => changeIndent(key)}/>
)} )}
<hr /> <hr />
{getSourceFormats().map(key => {getSourceFormats().map(key =>
<Btn label={locale(`format.${key}`)} active={format === key} <Btn label={locale(`format.${key}`)} active={cFormat === key}
onClick={() => changeFormat(key)} />)} onClick={() => changeFormat(key)} />)}
<hr /> <hr />
<Btn icon={sort === 'alphabetically' ? 'square_fill' : 'square'} label={locale('sort_alphabetically')} {/* <Btn icon={sort === 'alphabetically' ? 'square_fill' : 'square'} label={locale('sort_alphabetically')}
onClick={() => setSort(sort === 'alphabetically' ? 'schema' : 'alphabetically')} /> onClick={() => setSort(sort === 'alphabetically' ? 'schema' : 'alphabetically')} /> */}
<Btn icon={highlighting ? 'square_fill' : 'square'} label={locale('highlighting')} <Btn icon={highlighting ? 'square_fill' : 'square'} label={locale('highlighting')}
onClick={() => changeHighlighting(!highlighting)} /> onClick={() => changeHighlighting(!highlighting)} />
</BtnMenu> </BtnMenu>

View File

@@ -170,6 +170,7 @@
"indentation.4_spaces": "4 spaces", "indentation.4_spaces": "4 spaces",
"indentation.minified": "Minified", "indentation.minified": "Minified",
"indentation.tabs": "Tabs", "indentation.tabs": "Tabs",
"inline": "Inline",
"language": "Language", "language": "Language",
"layer": "Layer", "layer": "Layer",
"layer.biomes": "Biomes", "layer.biomes": "Biomes",