Replace tiptap with marked + markdown lol
This commit is contained in:
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"files.associations": {
|
|
||||||
"*.css": "tailwindcss"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
"@tiptap/html": "^3.18.0",
|
"@tiptap/html": "^3.18.0",
|
||||||
"@tiptap/pm": "^3.18.0",
|
"@tiptap/pm": "^3.18.0",
|
||||||
"@tiptap/starter-kit": "^3.18.0",
|
"@tiptap/starter-kit": "^3.18.0",
|
||||||
|
"marked": "^17.0.1",
|
||||||
"postgres": "^3.4.8",
|
"postgres": "^3.4.8",
|
||||||
"tiptap": "^1.32.2"
|
"tiptap": "^1.32.2"
|
||||||
}
|
}
|
||||||
|
|||||||
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
@@ -32,6 +32,9 @@ importers:
|
|||||||
'@tiptap/starter-kit':
|
'@tiptap/starter-kit':
|
||||||
specifier: ^3.18.0
|
specifier: ^3.18.0
|
||||||
version: 3.18.0
|
version: 3.18.0
|
||||||
|
marked:
|
||||||
|
specifier: ^17.0.1
|
||||||
|
version: 17.0.1
|
||||||
postgres:
|
postgres:
|
||||||
specifier: ^3.4.8
|
specifier: ^3.4.8
|
||||||
version: 3.4.8
|
version: 3.4.8
|
||||||
@@ -1408,6 +1411,11 @@ packages:
|
|||||||
resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==}
|
resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
marked@17.0.1:
|
||||||
|
resolution: {integrity: sha512-boeBdiS0ghpWcSwoNm/jJBwdpFaMnZWRzjA6SkUMYb40SVaN1x7mmfGKp0jvexGcx+7y2La5zRZsYFZI6Qpypg==}
|
||||||
|
engines: {node: '>= 20'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
mdurl@2.0.0:
|
mdurl@2.0.0:
|
||||||
resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==}
|
resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==}
|
||||||
|
|
||||||
@@ -2698,6 +2706,8 @@ snapshots:
|
|||||||
punycode.js: 2.3.1
|
punycode.js: 2.3.1
|
||||||
uc.micro: 2.1.0
|
uc.micro: 2.1.0
|
||||||
|
|
||||||
|
marked@17.0.1: {}
|
||||||
|
|
||||||
mdurl@2.0.0: {}
|
mdurl@2.0.0: {}
|
||||||
|
|
||||||
mini-svg-data-uri@1.4.4: {}
|
mini-svg-data-uri@1.4.4: {}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
let {
|
let {
|
||||||
year = $bindable("2026"),
|
year = $bindable("2026"),
|
||||||
month = $bindable("0"),
|
month = $bindable("0"),
|
||||||
|
dayClickCallback = $bindable(() => {}),
|
||||||
entries,
|
entries,
|
||||||
} = $props();
|
} = $props();
|
||||||
|
|
||||||
@@ -212,11 +213,12 @@
|
|||||||
|
|
||||||
<div class="calendar">
|
<div class="calendar">
|
||||||
{#each days as day, index}
|
{#each days as day, index}
|
||||||
<div
|
<button
|
||||||
class="day"
|
class="day hover:brightness-80"
|
||||||
class:other-month={!day.isCurrentMonth}
|
class:other-month={!day.isCurrentMonth}
|
||||||
class:today={day.isToday}
|
class:today={day.isToday}
|
||||||
class:has-image={day.entry?.image}
|
class:has-image={day.entry?.image}
|
||||||
|
onclick={ day.entry ? () => dayClickCallback(day.entry.id) : null }
|
||||||
style={day.entry?.image
|
style={day.entry?.image
|
||||||
? `background-image: url(${day.entry.image}); background-size: cover; background-position: center;`
|
? `background-image: url(${day.entry.image}); background-size: cover; background-position: center;`
|
||||||
: ""}
|
: ""}
|
||||||
@@ -233,7 +235,7 @@
|
|||||||
<span class="entry-indicator"></span>
|
<span class="entry-indicator"></span>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</button>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
<style>
|
<style>
|
||||||
@import 'tailwindcss';
|
@import 'tailwindcss';
|
||||||
|
|
||||||
#img-upload-button {
|
/*#img-upload-button {
|
||||||
@apply text-center bg-white/30 h-60 w-full rounded-2xl block hover:text-white/30 transition-all;
|
@apply text-center bg-white/30 h-60 w-full rounded-2xl block hover:text-white/30 transition-all;
|
||||||
}
|
}*/
|
||||||
</style>
|
</style>
|
||||||
@@ -3,17 +3,10 @@
|
|||||||
import TextEditor from "./textEditor.svelte";
|
import TextEditor from "./textEditor.svelte";
|
||||||
import { formatDate } from "$lib/date.ts";
|
import { formatDate } from "$lib/date.ts";
|
||||||
|
|
||||||
let {
|
let { entry = $bindable({}) } = $props();
|
||||||
entry = $bindable(""),
|
|
||||||
editorState = $bindable({ editor: null })
|
|
||||||
} = $props();
|
|
||||||
|
|
||||||
let edit = $state(false);
|
let edit = $state(false);
|
||||||
let editModeText = $derived(edit ? "done" : "edit")
|
let editModeText = $derived(edit ? "done" : "edit")
|
||||||
|
|
||||||
function getContent() {
|
|
||||||
return editorState.editor.getJSON();
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex flex-row mb-2">
|
<div class="flex flex-row mb-2">
|
||||||
@@ -27,4 +20,4 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ImageTarget bind:image={entry.image} bind:edit />
|
<ImageTarget bind:image={entry.image} bind:edit />
|
||||||
<TextEditor bind:content={entry.content} bind:editorState bind:edit />
|
<TextEditor bind:content={entry.content} bind:edit />
|
||||||
|
|||||||
@@ -1,49 +1,20 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
let {
|
let {
|
||||||
content = $bindable(),
|
content = $bindable(""),
|
||||||
edit = $bindable(false),
|
edit = $bindable(false),
|
||||||
editorState = $bindable({ editor: null }),
|
|
||||||
} = $props();
|
} = $props();
|
||||||
|
|
||||||
import { onMount, onDestroy } from "svelte";
|
import { marked } from "marked";
|
||||||
import { Editor } from "@tiptap/core";
|
|
||||||
import { StarterKit } from "@tiptap/starter-kit";
|
|
||||||
|
|
||||||
let element = $state();
|
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
editorState.editor = new Editor({
|
|
||||||
element: element,
|
|
||||||
editable: edit,
|
|
||||||
extensions: [StarterKit],
|
|
||||||
content: content,
|
|
||||||
onTransaction: ({ editor }) => {
|
|
||||||
// Update the state signal to force a re-render
|
|
||||||
editorState = { editor };
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
onDestroy(() => {
|
|
||||||
editorState.editor?.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
$effect(() => editorState.editor.setOptions({ editable: edit }));
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="bg-white/20 rounded-2xl p-2 mt-4">
|
<div class="bg-white/20 min-h-30 rounded-2xl p-2 mt-4">
|
||||||
<div
|
{#if edit}
|
||||||
class="bg-white/10 rounded-xl p-2 text-white/90"
|
<textarea
|
||||||
bind:this={element}
|
class="w-full min-h-30 border-none bg-white/10 rounded-xl p-2"
|
||||||
></div>
|
bind:value={content}
|
||||||
|
></textarea>
|
||||||
|
{:else}
|
||||||
|
{@html marked(content)}
|
||||||
|
{/if}
|
||||||
|
<!-- <div class="bg-white/10 rounded-xl p-2 text-white/90"></div> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
|
||||||
button.active {
|
|
||||||
background: black;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(.tiptap) {
|
|
||||||
min-height: 240px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { generateHTML } from "@tiptap/html";
|
import { generateHTML } from "@tiptap/html";
|
||||||
|
import { marked } from 'marked';
|
||||||
import { StarterKit } from "@tiptap/starter-kit";
|
import { StarterKit } from "@tiptap/starter-kit";
|
||||||
import { formatDate } from "$lib/date.ts";
|
import { formatDate } from "$lib/date.ts";
|
||||||
|
|
||||||
@@ -12,7 +13,7 @@
|
|||||||
<div class="flex flex-row">
|
<div class="flex flex-row">
|
||||||
<div>
|
<div>
|
||||||
<p class="text-sm text-white/60">{formattedDate}</p>
|
<p class="text-sm text-white/60">{formattedDate}</p>
|
||||||
{@html generateHTML(entry.content, [StarterKit])}
|
{@html marked(entry.content)}
|
||||||
</div>
|
</div>
|
||||||
<img
|
<img
|
||||||
class="max-h-30 min-h-15 max-w-1/2 rounded-xl object-cover ml-auto"
|
class="max-h-30 min-h-15 max-w-1/2 rounded-xl object-cover ml-auto"
|
||||||
|
|||||||
@@ -4,6 +4,6 @@ export const entryTable = pgTable("entries", {
|
|||||||
id: integer().primaryKey().generatedAlwaysAsIdentity(),
|
id: integer().primaryKey().generatedAlwaysAsIdentity(),
|
||||||
date: timestamp({ mode: 'date', withTimezone: true }).notNull().defaultNow(),
|
date: timestamp({ mode: 'date', withTimezone: true }).notNull().defaultNow(),
|
||||||
location: json(),
|
location: json(),
|
||||||
content: json(),
|
content: text(),
|
||||||
image: text()
|
image: text()
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,21 +9,21 @@
|
|||||||
|
|
||||||
let edit = $state(false)
|
let edit = $state(false)
|
||||||
|
|
||||||
let selectedEntry = $state()
|
let selectedEntry = $state('')
|
||||||
|
|
||||||
let selectEntry = async (entryID) => {
|
let selectEntry = async (entryID: string) => {
|
||||||
const res = await fetch(`/api/entry?id=${entryID}`)
|
const res = await fetch(`/api/entry?id=${entryID}`)
|
||||||
selectedEntry = await res.json()
|
selectedEntry = await res.json()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Calendar entries={data.all} />
|
<Calendar entries={data.all} dayClickCallback={async (entryID: string) => await selectEntry(entryID)} />
|
||||||
|
|
||||||
<div class="flex flex-col md:flex-row space-y-4 w-full mt-6">
|
<div class="flex flex-col md:flex-row space-y-4 w-full mt-6">
|
||||||
|
|
||||||
<div class="md:w-1/2 md:order-2">
|
<div class="md:w-1/2 md:order-2">
|
||||||
{#if selectedEntry}
|
{#if selectedEntry}
|
||||||
<Editor bind:edit bind:entry={selectedEntry} />
|
<Editor bind:entry={selectedEntry} />
|
||||||
{:else}
|
{:else}
|
||||||
<div class="md:flex flex-col items-center justify-center mx-5 hidden">
|
<div class="md:flex flex-col items-center justify-center mx-5 hidden">
|
||||||
<p class="text-white/60">Select an entry to view/edit</p>
|
<p class="text-white/60">Select an entry to view/edit</p>
|
||||||
|
|||||||
Reference in New Issue
Block a user