diff --git a/package.json b/package.json index 3899b31..e724b2c 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,10 @@ "vite-plugin-wasm": "^3.2.2" }, "dependencies": { + "@syncedstore/core": "^0.5.1", + "@syncedstore/svelte": "^0.5.1", "date-fns": "^2.30.0", + "dayjs": "^1.11.7", "nanoid": "^4.0.2", "svelt-yjs": "^1.1.0", "y-indexeddb": "^9.0.10", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1daf2e0..b021636 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,9 +1,18 @@ lockfileVersion: '6.0' dependencies: + '@syncedstore/core': + specifier: ^0.5.1 + version: 0.5.1(yjs@13.6.0) + '@syncedstore/svelte': + specifier: ^0.5.1 + version: 0.5.1(@reactivedata/reactive@0.2.0)(@syncedstore/core@0.5.1)(svelte@3.57.0) date-fns: specifier: ^2.30.0 version: 2.30.0 + dayjs: + specifier: ^1.11.7 + version: 1.11.7 nanoid: specifier: ^4.0.2 version: 4.0.2 @@ -297,6 +306,10 @@ packages: fastq: 1.15.0 dev: true + /@reactivedata/reactive@0.2.0: + resolution: {integrity: sha512-qWmVSmUrjKHBiD+ZS8TxNNzyk9J6rbcZSZJgcnKQpTLwORZoWuX5pYbl07aU0kzXGLaaVX2O/ZW+SZaBjRQW3g==} + dev: false + /@rollup/plugin-virtual@3.0.1: resolution: {integrity: sha512-fK8O0IL5+q+GrsMLuACVNk2x21g3yaw+sG2qn16SnUd3IlBsQyvWxLMGHmCmXRMecPjGRSZ/1LmZB4rjQm68og==} engines: {node: '>=14.0.0'} @@ -438,10 +451,57 @@ packages: '@swc/core-win32-x64-msvc': 1.3.56 dev: true + /@syncedstore/core@0.5.1(yjs@13.6.0): + resolution: {integrity: sha512-YTd6s2lQrkOYOooQkjKxBi41/4HxORnjiXxBU+fk+Qb7oq9ZD5XVaFkt8mrJcw4NQ/MZK3aGkaphdvETFPc7Kw==} + peerDependencies: + yjs: ^13.5.13 + dependencies: + '@reactivedata/reactive': 0.2.0 + '@syncedstore/yjs-reactive-bindings': 0.5.1(yjs@13.6.0) + '@types/eslint': 6.8.0 + yjs: 13.6.0 + dev: false + + /@syncedstore/svelte@0.5.1(@reactivedata/reactive@0.2.0)(@syncedstore/core@0.5.1)(svelte@3.57.0): + resolution: {integrity: sha512-9o1w5Pg6gkB41dBasef1sBFq5IvgrNzEO4IeBy8aVo1NtUWiv2h2Mp3q3FnpVpsdoDDvwwZ9m/ZTZ3B3Ie/Uaw==} + peerDependencies: + '@reactivedata/reactive': '*' + '@syncedstore/core': '*' + svelte: '*' + dependencies: + '@reactivedata/reactive': 0.2.0 + '@syncedstore/core': 0.5.1(yjs@13.6.0) + svelte: 3.57.0 + dev: false + + /@syncedstore/yjs-reactive-bindings@0.5.1(yjs@13.6.0): + resolution: {integrity: sha512-M1/YrK0gAiQAhTCekXtp+qAq4DVUdPCsEdsJ2Tcqo176WHcsjr0yOqjAYrva1Phh4DPTVx1GPWTCUWpxUBR1ug==} + peerDependencies: + yjs: ^13.5.13 + dependencies: + '@types/eslint': 6.8.0 + yjs: 13.6.0 + dev: false + /@tsconfig/svelte@4.0.1: resolution: {integrity: sha512-B+XlGpmuAQzJqDoBATNCvEPqQg0HkO7S8pM14QDI5NsmtymzRexQ1N+nX2H6RTtFbuFgaZD4I8AAi8voGg0GLg==} dev: true + /@types/eslint@6.8.0: + resolution: {integrity: sha512-hqzmggoxkOubpgTdcOltkfc5N8IftRJqU70d1jbOISjjZVPvjcr+CLi2CI70hx1SUIRkLgpglTy9w28nGe2Hsw==} + dependencies: + '@types/estree': 1.0.1 + '@types/json-schema': 7.0.11 + dev: false + + /@types/estree@1.0.1: + resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} + dev: false + + /@types/json-schema@7.0.11: + resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} + dev: false + /@types/pug@2.0.6: resolution: {integrity: sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==} dev: true @@ -530,6 +590,10 @@ packages: '@babel/runtime': 7.21.5 dev: false + /dayjs@1.11.7: + resolution: {integrity: sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==} + dev: false + /debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -1063,7 +1127,6 @@ packages: /svelte@3.57.0: resolution: {integrity: sha512-WMXEvF+RtAaclw0t3bPDTUe19pplMlfyKDsixbHQYgCWi9+O9VN0kXU1OppzrB9gPAvz4NALuoca2LfW2bOjTQ==} engines: {node: '>= 8'} - dev: true /to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} diff --git a/src/app.css b/src/app.css index 78f79ce..27d21f4 100644 --- a/src/app.css +++ b/src/app.css @@ -77,3 +77,12 @@ button:focus-visible { background-color: #f9f9f9; } } + +.icon-btn { + line-height: 1; + padding: 0.2em; +} +.icon-btn > svg { + width: 1.5em; + height: 1.5em; +} diff --git a/src/assets/eva-icons/edit-outline.svg b/src/assets/eva-icons/edit-outline.svg new file mode 100644 index 0000000..018fa58 --- /dev/null +++ b/src/assets/eva-icons/edit-outline.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/eva-icons/save-outline.svg b/src/assets/eva-icons/save-outline.svg new file mode 100644 index 0000000..a242959 --- /dev/null +++ b/src/assets/eva-icons/save-outline.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/doc.ts b/src/doc.ts index 1a6fdb4..f2cc6c7 100644 --- a/src/doc.ts +++ b/src/doc.ts @@ -1,16 +1,27 @@ import * as Y from "yjs"; import { WebrtcProvider } from "y-webrtc"; import { IndexeddbPersistence } from "y-indexeddb"; +import { syncedStore, getYjsDoc } from "@syncedstore/core"; +import { svelteSyncedStore } from "@syncedstore/svelte"; import { nanoid } from "nanoid"; +import type { MappedTypeDescription } from "@syncedstore/core/types/doc"; export type UserIdentifier = { room: string; password: string; }; +type SyncedStoreType = MappedTypeDescription<{ + doing: Doing[]; + done: Done[]; + name: Y.Text; +}>; + export type UserY = { - ydoc: Y.Doc; + // ydoc: Y.Doc; webrtcProvider: WebrtcProvider; + store: SyncedStoreType; + svelteStore: ReturnType>; }; export function createUser(): UserIdentifier { @@ -35,7 +46,14 @@ const credsReq = fetch( export function getUserY(world: UserIdentifier): UserY { if (userYCache[world.room]) return userYCache[world.room]; - const ydoc = new Y.Doc(); + + const store = syncedStore({ + doing: [] as Doing[], + done: [] as Done[], + name: "text", + }); + const svelteStore = svelteSyncedStore(store); + const ydoc = getYjsDoc(store); const provider = new WebrtcProvider(world.room, ydoc, { password: world.password, signaling: [ @@ -59,7 +77,7 @@ export function getUserY(world: UserIdentifier): UserY { } }); const idbProvider = new IndexeddbPersistence(world.room, ydoc); - const worldY = { ydoc, webrtcProvider: provider }; + const worldY = { webrtcProvider: provider, store, svelteStore }; userYCache[world.room] = worldY; return worldY; } @@ -77,9 +95,9 @@ export type Done = { started: number; took: number; }; -export function getData(userY: UserY) { - const ydoing: Y.Array = userY.ydoc.getArray("doing"); - const ydone: Y.Array = userY.ydoc.getArray("done"); - const yname: Y.Text = userY.ydoc.getText("name"); - return { ydoing, ydone, yname }; -} +// export function getData(userY: UserY) { +// const ydoing: Y.Array = userY.ydoc.getArray("doing"); +// const ydone: Y.Array = userY.ydoc.getArray("done"); +// const yname: Y.Text = userY.ydoc.getText("name"); +// return { ydoing, ydone, yname }; +// } diff --git a/src/lib/Amigxs.svelte b/src/lib/Amigxs.svelte index 3ba9c6e..1a430f9 100644 --- a/src/lib/Amigxs.svelte +++ b/src/lib/Amigxs.svelte @@ -1,11 +1,7 @@ changeName(e.currentTarget.value)} placeholder="tu nombre" /> @@ -53,14 +46,7 @@
    - {#each $allData as friend} -
  • - {#if friend.name} - {friend.name} ({friend.id.room}) - {:else} - {friend.id.room} - {/if} - -
  • + {#each $friendsData as friend} +
  • {/each}
diff --git a/src/lib/Amigxs/Friend.svelte b/src/lib/Amigxs/Friend.svelte new file mode 100644 index 0000000..99e41ed --- /dev/null +++ b/src/lib/Amigxs/Friend.svelte @@ -0,0 +1,19 @@ + + +{#if $friendStore.name.toString()} + {$friendStore.name} ({id.room}) +{:else} + {id.room} +{/if} + diff --git a/src/lib/Doing.svelte b/src/lib/Doing.svelte index d78248a..68a1c19 100644 --- a/src/lib/Doing.svelte +++ b/src/lib/Doing.svelte @@ -1,37 +1,35 @@ -{#if $doing.length > 0} - {#each $doing as doing, index} +{#if $userStore.doing.length > 0} + {#each $userStore.doing as doing, index}
{doing.description} @@ -53,17 +51,12 @@ {/if} -{#if $done.length > 0} +{#if $userStore.done.length > 0}

Ya hecho

    - {#each sortedDone as thing} + {#each $sortedDone as thing}
  • - {thing.description} - - ({formatDistance( - new Date(thing.took + thing.started), - new Date(thing.started) - )}) +
  • {/each}
diff --git a/src/lib/Others.svelte b/src/lib/Others.svelte index 420dbc9..361efea 100644 --- a/src/lib/Others.svelte +++ b/src/lib/Others.svelte @@ -1,46 +1,36 @@

actualmente:

    - {#each $allData as data} - {#if data.doing.length > 0} -
  • - {data.name || data.id.room} - {#each data.doing as d, i} - {#if i !== 0} y {/if} - {d.description} - hace - {formatDistanceShort( - intervalToDuration({ start: $sTimer, end: new Date(d.started) }) - )} - {/each} -
  • - {/if} + {#each $friendsData as friend} + {/each}

previamente:

    - {#each sortedDone as thing} + {#each $sortedDone as { thing, friend, id: friendId }}
  • - {thing.friend.name || thing.friend.id.room} + {friend.name || friendId.room} hizo {thing.description} por diff --git a/src/lib/Others/FriendDoing.svelte b/src/lib/Others/FriendDoing.svelte new file mode 100644 index 0000000..bbaf31b --- /dev/null +++ b/src/lib/Others/FriendDoing.svelte @@ -0,0 +1,27 @@ + + +{#if $friendStore.doing.length > 0} +
  • + {$friendStore.name || id.room} + {#each $friendStore.doing as d, i} + {#if i !== 0} y {/if} + {d.description} + hace + {formatDistanceShort( + intervalToDuration({ start: $sTimer, end: new Date(d.started) }) + )} + {/each} +
  • +{/if} diff --git a/src/lib/PersonalDoneThing.svelte b/src/lib/PersonalDoneThing.svelte new file mode 100644 index 0000000..e8c8b92 --- /dev/null +++ b/src/lib/PersonalDoneThing.svelte @@ -0,0 +1,38 @@ + + +{#if editing} + +
    + +
    + +
    + +{:else} + {thing.description} + + ({formatDistance( + new Date(thing.took + thing.started), + new Date(thing.started) + )}) + + +{/if} diff --git a/src/lib/general-components/DateTimeInput.svelte b/src/lib/general-components/DateTimeInput.svelte new file mode 100644 index 0000000..58ecac8 --- /dev/null +++ b/src/lib/general-components/DateTimeInput.svelte @@ -0,0 +1,19 @@ + + + diff --git a/src/lib/general-components/DurationInput.svelte b/src/lib/general-components/DurationInput.svelte new file mode 100644 index 0000000..92041a4 --- /dev/null +++ b/src/lib/general-components/DurationInput.svelte @@ -0,0 +1,63 @@ + + + +: + +: + + + diff --git a/src/lib/stores/friends.ts b/src/lib/stores/friends.ts index 3339654..39e62f5 100644 --- a/src/lib/stores/friends.ts +++ b/src/lib/stores/friends.ts @@ -1,8 +1,5 @@ import { derived, writable } from "svelte/store"; -import { readableArray } from "svelt-yjs/src/main"; -import { getData, getUserY, type UserIdentifier } from "../../doc"; -import { readableText } from "../helpers/readableText"; -import { deriveObj } from "../helpers/recursiveReadable"; +import { getUserY, type UserIdentifier } from "../../doc"; type Type = UserIdentifier[]; @@ -14,13 +11,5 @@ store.subscribe(save); export default store; export const friendsData = derived(store, ($friends) => - $friends - .map((id) => ({ id, ...getUserY(id) })) - .map((y) => ({ ...y, ...getData(y) })) - .map((y) => ({ - name: readableText(y.yname), - doing: readableArray(y.ydoing), - done: readableArray(y.ydone), - })) - .map((d) => deriveObj(d)) + $friends.map((id) => ({ id, userY: getUserY(id) })) );