Files
Website/src/components/admin/pages/edit/Editor.svelte
2024-12-14 18:10:50 +01:00

105 lines
3.6 KiB
Svelte

<!--
- This file is a part of the SteamWar software.
-
- Copyright (C) 2023 SteamWar.de-Serverteam
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<script lang="ts">
import {Spinner, Toolbar, ToolbarButton, ToolbarGroup} from "flowbite-svelte";
import {json} from "@codemirror/lang-json";
import CodeMirror from "svelte-codemirror-editor";
import {base64ToBytes} from "../../util.ts";
import type {Page} from "@type/page.ts";
import {materialDark} from "@ddietr/codemirror-themes/material-dark";
import {createEventDispatcher} from "svelte";
import MDEMarkdownEditor from "./MDEMarkdownEditor.svelte";
import {pageRepo} from "@repo/page.ts";
interface Props {
pageId: number;
branch: string;
dirty?: boolean;
}
let { pageId, branch, dirty = $bindable(false) }: Props = $props();
let dispatcher = createEventDispatcher();
let pageContent = $state("");
let page: Page | null = $state(null);
function getPage(value: Page): Page {
page = value;
if (!dirty || confirm("You have unchanged Changes! Discard them? ")) {
navigator.clipboard.writeText(pageContent);
dirty = false;
pageContent = new TextDecoder().decode(base64ToBytes(value.content));
}
return value;
}
function savePage() {
let message = window.prompt("Commit message:", "Update " + page!.name);
if (message) {
$pageRepo.updatePage(pageId, pageContent, page!.sha, message, branch);
dirty = false;
}
}
async function deletePage() {
let message = window.prompt("Commit message:", "Delete " + page!.name);
if (message) {
await $pageRepo.deletePage(pageId, message, page!.sha, branch);
dirty = false;
dispatcher("reload");
}
}
let pageFuture = $derived($pageRepo.getPage(pageId, branch).then(getPage));
</script>
<svelte:window onbeforeunload={() => {
if (dirty) {
return "You have unsaved changes. Are you sure you want to leave?";
}
}}/>
{#await pageFuture}
<Spinner/>
{:then p}
<div>
<div>
<Toolbar class="!bg-gray-900">
{#snippet end()}
<ToolbarGroup >
<ToolbarButton onclick={deletePage}>
Delete
</ToolbarButton>
<ToolbarButton color="primary" onclick={savePage}>
Save
</ToolbarButton>
</ToolbarGroup>
{/snippet}
</Toolbar>
</div>
{#if page?.name.endsWith("md") || page?.name.endsWith("mdx")}
<MDEMarkdownEditor bind:value={pageContent} bind:dirty/>
{:else}
<CodeMirror bind:value={pageContent} lang={json()} theme={materialDark} on:change={() => dirty = true}/>
{/if}
</div>
{:catch error}
<p>{error.message}</p>
{/await}