mostrar titulo de mundo en index (fixes #3)
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
This commit is contained in:
parent
56d8aca9b0
commit
73381b0dd7
5 changed files with 85 additions and 8 deletions
18
src/components/WorldLink.svelte
Normal file
18
src/components/WorldLink.svelte
Normal file
|
@ -0,0 +1,18 @@
|
|||
<script>
|
||||
import { inject } from "regexparam";
|
||||
import { getWorldY } from "../lib/doc";
|
||||
import { titleStore } from "../lib/titleStore";
|
||||
import { routes } from "../lib/routes";
|
||||
|
||||
/** @type {import("../lib/doc").WorldIdentifier} */
|
||||
export let world;
|
||||
|
||||
$: title = titleStore(getWorldY(world).ydoc, "page/index");
|
||||
</script>
|
||||
|
||||
<a
|
||||
href={inject(routes.Page, {
|
||||
worldId: world.room,
|
||||
pageId: "index",
|
||||
})}>{$title || world.room}</a
|
||||
>
|
26
src/lib/getTitle.js
Normal file
26
src/lib/getTitle.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
import { yDocToProsemirrorJSON } from "y-prosemirror";
|
||||
import { Node } from "prosemirror-model";
|
||||
import { schema } from "../editor/schema";
|
||||
|
||||
/**
|
||||
* @param {import("yjs").Doc} ydoc
|
||||
* @param {string} name
|
||||
* @returns {string=}
|
||||
*/
|
||||
export function getTitle(ydoc, name) {
|
||||
const json = yDocToProsemirrorJSON(ydoc, name);
|
||||
const node = Node.fromJSON(schema, json);
|
||||
/** @type {any} */
|
||||
let titleNode = null;
|
||||
node.descendants((node) => {
|
||||
if (titleNode) return false;
|
||||
if (node.type.name === "heading" && node.attrs.level === 1) {
|
||||
titleNode = node;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (titleNode) {
|
||||
// prettier-ignore
|
||||
return /** @type {Node} */(titleNode).textContent;
|
||||
}
|
||||
}
|
32
src/lib/titleStore.js
Normal file
32
src/lib/titleStore.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
import { getTitle } from "./getTitle.js";
|
||||
import { makeYdocStore } from "./makeYdocStore";
|
||||
|
||||
/**
|
||||
* @param {import("yjs").Doc} ydoc
|
||||
* @param {string} id
|
||||
* @returns {import("svelte/store").Readable<string | null>}
|
||||
*/
|
||||
export function titleStore(ydoc, id) {
|
||||
/** @type {(() => void) | null } */
|
||||
let observer = null;
|
||||
/** @type {import("yjs").AbstractType<any> | null} */
|
||||
let y = null;
|
||||
|
||||
/** @type {string|null} */
|
||||
let title = null;
|
||||
|
||||
return makeYdocStore(
|
||||
(_, __, ydoc) => {
|
||||
const setTitle = () => (title = getTitle(ydoc, id) || null);
|
||||
if (!y) {
|
||||
setTitle();
|
||||
y = ydoc.getXmlFragment(id);
|
||||
observer = setTitle;
|
||||
y.observeDeep(observer);
|
||||
}
|
||||
|
||||
return title;
|
||||
},
|
||||
() => observer && y?.unobserveDeep(observer)
|
||||
)(ydoc);
|
||||
}
|
|
@ -1,11 +1,16 @@
|
|||
import type { WorldIdentifier } from "./doc";
|
||||
import { getWorldY, type WorldIdentifier } from "./doc";
|
||||
|
||||
const localStorageKey = "schreiben-worlds";
|
||||
|
||||
export function loadWorlds(): Promise<WorldIdentifier[]> {
|
||||
let json = localStorage.getItem(localStorageKey);
|
||||
if (!json) json = "[]";
|
||||
return Promise.resolve(JSON.parse(json));
|
||||
const worlds = JSON.parse(json);
|
||||
for (const world of worlds) {
|
||||
// empezar a cargar el Ydoc
|
||||
getWorldY(world);
|
||||
}
|
||||
return Promise.resolve(worlds);
|
||||
}
|
||||
|
||||
export async function writeWorlds(
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import { inject } from "regexparam";
|
||||
import { loadWorlds } from "../lib/worldStorage";
|
||||
import { routes } from "../lib/routes";
|
||||
import WorldLink from "../components/WorldLink.svelte";
|
||||
|
||||
const worldsPromise = loadWorlds();
|
||||
</script>
|
||||
|
@ -13,12 +14,7 @@
|
|||
<ul>
|
||||
{#each worlds as world}
|
||||
<li>
|
||||
<a
|
||||
href={inject(routes.Page, {
|
||||
worldId: world.room,
|
||||
pageId: "index",
|
||||
})}>{world.room}</a
|
||||
>
|
||||
<WorldLink {world} />
|
||||
</li>
|
||||
{/each}
|
||||
<li><a href={routes.CreateWorld}>Crear mundo</a></li>
|
||||
|
|
Loading…
Reference in a new issue