mostrar titulo de mundo en index (fixes #3)
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed

This commit is contained in:
Cat /dev/Nulo 2023-04-18 12:08:46 -03:00
parent 56d8aca9b0
commit 73381b0dd7
5 changed files with 85 additions and 8 deletions

View 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
View 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
View 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);
}

View file

@ -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(

View file

@ -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>