Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# .github/workflows/ci.yml
name: Automated Tests

on:
pull_request:
push:

jobs:
build:
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [20.x]

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: "npm"

- name: Install dependencies
run: npm install

- name: Install Playwright dependencies
run: npx playwright install

- name: Run tests
run: npm test
24 changes: 12 additions & 12 deletions bun.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,35 @@
"": {
"name": "tools",
"dependencies": {
"@tiptap/core": "^2.23.0",
"@tiptap/extension-placeholder": "^2.23.0",
"@tiptap/pm": "^2.23.0",
"@tiptap/starter-kit": "^2.23.0",
"@tiptap/core": "^2.23.1",
"@tiptap/extension-placeholder": "^2.23.1",
"@tiptap/pm": "^2.23.1",
"@tiptap/starter-kit": "^2.23.1",
"idb": "^8.0.3",
"svelte-awesome-color-picker": "^4.0.2",
"tippy.js": "^6.3.7",
"typescript-color-gradient": "^4.0.1",
},
"devDependencies": {
"@iconify-json/tabler": "^1.2.19",
"@playwright/test": "^1.49.1",
"@playwright/test": "^1.53.2",
"@sveltejs/adapter-auto": "^6.0.1",
"@sveltejs/kit": "^2.22.2",
"@sveltejs/vite-plugin-svelte": "^5.1.0",
"@tailwindcss/vite": "^4.1.11",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/svelte": "^5.2.8",
"@tiptap/extension-color": "^2.23.0",
"@tiptap/extension-font-family": "^2.23.0",
"@tiptap/extension-text-style": "^2.23.0",
"@tiptap/extension-underline": "^2.23.0",
"@types/node": "^24.0.4",
"@tiptap/extension-color": "^2.23.1",
"@tiptap/extension-font-family": "^2.23.1",
"@tiptap/extension-text-style": "^2.23.1",
"@tiptap/extension-underline": "^2.23.1",
"@types/node": "^24.0.8",
"file-type": "^21.0.0",
"jsdom": "^26.1.0",
"prettier": "^3.6.1",
"prettier": "^3.6.2",
"prettier-plugin-svelte": "^3.4.0",
"prettier-plugin-tailwindcss": "^0.6.13",
"svelte": "^5.34.8",
"svelte": "^5.34.9",
"svelte-check": "^4.2.2",
"tailwindcss": "^4.1.11",
"tslib": "^2.8.1",
Expand Down
2 changes: 1 addition & 1 deletion playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ export default defineConfig({
command: "npm run build && npm run preview",
port: 4173,
},
testDir: "src/e2e",
testDir: "src/tests/e2e",
});
8 changes: 6 additions & 2 deletions src/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/dph.svg" />

<link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="shortcut icon" href="/favicon.ico" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<meta name="apple-mobile-web-app-title" content="Text Editor" />
<link rel="manifest" href="/site.webmanifest" />
<link
rel="preload"
as="font"
Expand Down
17 changes: 17 additions & 0 deletions src/lib/components/CheckBox.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<script lang="ts">
import IconTick from "~icons/tabler/check";

let { value = $bindable(), label }: { value: boolean; label: string } =
$props();
</script>

<div class="flex items-center gap-2">
<button
name={label}
class="flex aspect-square size-8 flex-col items-center rounded-md bg-zinc-900"
onclick={() => (value = !value)}>
{#if value}
<IconTick class="m-auto text-lg" />
{/if}
</button>
</div>
31 changes: 5 additions & 26 deletions src/lib/components/modals/CustomSourceModal.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<script lang="ts">
import Modal from "$lib/components/Modal.svelte";
import IconTick from "~icons/tabler/check";
import type { ExternalSources } from "$lib/types";
import IconScore from "~icons/tabler/123";
import IconSelector from "~icons/tabler/at";
import IconNBT from "~icons/tabler/braces";
import IconKeybind from "~icons/tabler/keyboard";
import IconTranslate from "~icons/tabler/language";
import type { ExternalSources } from "$lib/types";
import CheckBox from "../CheckBox.svelte";
import MiniEditor from "../MiniEditor.svelte";

let {
Expand Down Expand Up @@ -214,14 +214,7 @@
bind:value={customValues.nbt.path} />

<div class="mt-2 flex items-center space-x-2">
<button
class="flex aspect-square size-8 flex-col items-center rounded-md bg-zinc-900"
onclick={() =>
(customValues.nbt.interpret = !customValues.nbt.interpret)}>
{#if customValues.nbt.interpret}
<IconTick class="m-auto text-lg" />
{/if}
</button>
<CheckBox bind:value={customValues.nbt.interpret} label="interpret" />
<label for="interpret"
>Interpret (parse nbt value as a text component)</label>
</div>
Expand Down Expand Up @@ -258,14 +251,7 @@
bind:value={customValues.nbt.path} />

<div class="mt-2 flex items-center space-x-2">
<button
class="flex aspect-square size-8 flex-col items-center rounded-md bg-zinc-900"
onclick={() =>
(customValues.nbt.interpret = !customValues.nbt.interpret)}>
{#if customValues.nbt.interpret}
<IconTick class="m-auto text-lg" />
{/if}
</button>
<CheckBox bind:value={customValues.nbt.interpret} label="interpret" />
<label for="interpret"
>Interpret (parse nbt value as a text component)</label>
</div>
Expand Down Expand Up @@ -302,14 +288,7 @@
bind:value={customValues.nbt.path} />

<div class="mt-2 flex items-center space-x-2">
<button
class="flex aspect-square size-8 flex-col items-center rounded-md bg-zinc-900"
onclick={() =>
(customValues.nbt.interpret = !customValues.nbt.interpret)}>
{#if customValues.nbt.interpret}
<IconTick class="m-auto text-lg" />
{/if}
</button>
<CheckBox bind:value={customValues.nbt.interpret} label="interpret" />
<label for="interpret"
>Interpret (parse nbt value as a text component)</label>
</div>
Expand Down
90 changes: 51 additions & 39 deletions src/lib/components/modals/ExportModal.svelte
Original file line number Diff line number Diff line change
@@ -1,18 +1,34 @@
<script lang="ts">
import Modal from "$lib/components/Modal.svelte";
import IconCopy from "~icons/tabler/copy";
import IconTick from "~icons/tabler/check";
import { translateJSON, convert } from "$lib/text/nbt_or_json";
import { translateMOTD } from "$lib/text/motd";
import { convert, translateJSON } from "$lib/text/nbt_or_json";
import IconCopy from "~icons/tabler/copy";
import CheckBox from "../CheckBox.svelte";
let {
outputDialog = $bindable(),
outputVersion = $bindable(),
editor,
recentlyCopied,
indent,
indentSize,
shouldOptimise = true,
} = $props();

let exportAsJSON = $state(false);

function exportThing(exportAsJSON: boolean) {
if (!exportAsJSON) {
return convert(
editor.getJSON(),
"item_lore",
outputVersion,
shouldOptimise,
);
}
return translateJSON(editor.getJSON(), {
exportType: "item_lore",
exportVersion: outputVersion,
optimise: shouldOptimise,
});
}
</script>

<Modal title="More output formats" bind:this={outputDialog} big key="E">
Expand All @@ -21,29 +37,36 @@
<option value="new">1.21.5+</option>
<option value="old">Before 1.21.5</option>
</select>
<div class="mt-2 flex w-full flex-col">
<p>For tellraw commands (send to chat):</p>
<div class="flex w-full flex-col">
{#if outputVersion == "new"}
<div class="flex items-center space-x-2 mt-1">
<CheckBox bind:value={exportAsJSON} label="json" />
<span>Toggle JSON mode (for use in json files)</span>
</div>
{/if}

<p class="mt-2">As {outputVersion == "new" ? " " : "JSON "}text components:</p>
<div class="flex items-start space-x-3 rounded-lg bg-zinc-950 p-3">
<button
class="rounded-md p-1 text-lg font-medium hover:bg-zinc-900 active:bg-white/10"
onclick={() => {
navigator.clipboard.writeText(
"/tellraw @s " +
convert(
editor.getJSON(),
"standard",
outputVersion,
shouldOptimise,
),
convert(
editor.getJSON(),
"standard",
outputVersion,
shouldOptimise,
exportAsJSON
),
);
recentlyCopied = true;
setTimeout(() => (recentlyCopied = false), 2000);
}}>
<IconCopy />
</button>
<code class="inline-block max-h-56 w-full overflow-auto"
>/tellraw @s {editor
? convert(editor.getJSON(), "standard", outputVersion, shouldOptimise)
<code class="inline-block max-h-56 w-full overflow-auto">
{editor
? convert(editor.getJSON(), "standard", outputVersion, shouldOptimise, exportAsJSON)
: "Loading..."}
</code>
</div>
Expand All @@ -54,35 +77,24 @@
class="rounded-md p-1 text-lg font-medium hover:bg-zinc-900 active:bg-white/10"
onclick={() => {
navigator.clipboard.writeText(
`[lore=${convert(editor.getJSON(), "item_lore", outputVersion, shouldOptimise)}]`,
`[lore=${convert(editor.getJSON(), "item_lore", outputVersion, shouldOptimise, exportAsJSON)}]`,
);
recentlyCopied = true;
setTimeout(() => (recentlyCopied = false), 2000);
}}>
<IconCopy />
</button>
{#if outputVersion == "new"}
<code class="inline-block max-h-56 w-full overflow-auto"
>[lore={editor
><span class="text-white/35">[lore=</span>{editor
? convert(
editor.getJSON(),
"item_lore",
outputVersion,
shouldOptimise,
)
: "Loading..."}]
</code>
{:else}
<code class="inline-block max-h-56 w-full overflow-auto"
>[lore={editor
? `'${translateJSON(editor.getJSON(), {
exportType: "item_lore",
exportVersion: outputVersion,
optimise: shouldOptimise,
})}`
: "Loading..."}]
editor.getJSON(),
"item_lore",
outputVersion,
shouldOptimise,
exportAsJSON
)
: "Loading..."}<span class="text-white/35">]</span>
</code>
{/if}
</div>

<p class="mt-2">As a MOTD:</p>
Expand All @@ -103,7 +115,7 @@
</code>
</div>

<p class="mt-2">As JSON:</p>
<!-- <p class="mt-2">As JSON:</p>
<div class="flex items-start space-x-3 rounded-lg bg-zinc-950 p-3">
<button
class="rounded-md p-1 text-lg font-medium hover:bg-zinc-900 active:bg-white/10"
Expand Down Expand Up @@ -154,6 +166,6 @@
min="1"
bind:value={indentSize}
class="w-fit rounded-md bg-zinc-900 p-2" />
{/if}
{/if} -->
</div>
</Modal>
3 changes: 2 additions & 1 deletion src/lib/text/nbt_or_json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -319,9 +319,10 @@ export function convert(
exportType: "standard" | "item_lore" = "standard",
exportVersion: "new" | "old" = "new",
optimise: boolean,
force_json: boolean = false
): string {
let out = translateJSON(jsonContent, { exportVersion, exportType, optimise });
if (exportVersion == "new") {
if (exportVersion == "new" && !force_json) {
// only remove strings
out = out.replace(/(?<=[{,]\s*)"[^"]*"\s*:/g, (match) =>
match.replace(/"/g, ""),
Expand Down
15 changes: 11 additions & 4 deletions src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import { fontLUT } from "$lib/tiptap/extensions/fonts";
import { tooltip } from "$lib/tooltip";
import { translateMOTD } from "$lib/text/motd";
import ExportModal from "$lib/components/modals/ExportModal.svelte";

let tiptapJSON: JSONContent = $state()!;

Expand Down Expand Up @@ -179,7 +180,7 @@
FontsExtension,
Placeholder.configure({
placeholder:
"Write text here, style it with the options above, and the output text components will appear at the bottom!",
"Write text here, style it with the options above, and the output text components will appear at the bottom. You can also import text components with the Import button above!",
}),
],
onTransaction: ({ editor: newEditor }) => {
Expand Down Expand Up @@ -569,9 +570,11 @@
<p class="font-lexend nomob text-xs text-white/60">
{getTextComponentCount()} components
</p>

<p class="font-lexend nomob text-xs text-white/60">•</p>

<p class="font-lexend text-xs text-white/60">
Click to change output settings:
click to change output settings:
</p>
<button
{@attach tooltip}
Expand All @@ -591,6 +594,12 @@
aria-label="Click to toggle whether the output should be optimised (shortest possible output), or expanded (easier to edit manually)."
onclick={() => (shouldOptimise = !shouldOptimise)}
>{shouldOptimise ? "optimised" : "expanded"}</button>

<p class="font-lexend nomob text-xs text-white/60">•</p>

<button class="font-lexend text-xs text-white/60 underline" onclick={outputDialog?.open}>
other output formats
</button>
</div>
{/if}
</div>
Expand Down Expand Up @@ -719,8 +728,6 @@
bind:outputDialog
bind:outputVersion
{editor}
{indent}
{indentSize}
{recentlyCopied} />
{/await}

Expand Down
Loading