diff --git a/package.json b/package.json index 9b66a471d..4314f5c2f 100644 --- a/package.json +++ b/package.json @@ -67,11 +67,11 @@ "prettier": "^2.8.0", "prettier-plugin-svelte": "^2.8.1", "prettier-plugin-tailwindcss": "^0.3.0", - "svelte": "^3.55.1", + "svelte": "~3.55.1", "svelte-check": "^3.0.1", "svelte-floating-ui": "^1.5.2", "svelte-french-toast": "^1.0.3", - "svelte-loadable-store": "^1.0.1", + "svelte-loadable-store": "^1.0.7", "svelte-outclick": "^3.5.0", "svelte-resize-observer": "^2.0.0", "tailwindcss": "^3.1.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f2f534f62..267eea1ee 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -155,7 +155,7 @@ devDependencies: specifier: ^0.3.0 version: 0.3.0(prettier-plugin-svelte@2.9.0)(prettier@2.8.4) svelte: - specifier: ^3.55.1 + specifier: ~3.55.1 version: 3.55.1 svelte-check: specifier: ^3.0.1 @@ -167,8 +167,8 @@ devDependencies: specifier: ^1.0.3 version: 1.0.3(svelte@3.55.1) svelte-loadable-store: - specifier: ^1.0.1 - version: 1.0.1 + specifier: ^1.0.7 + version: 1.0.7(svelte@3.55.1) svelte-outclick: specifier: ^3.5.0 version: 3.5.0(svelte@3.55.1) @@ -3655,10 +3655,12 @@ packages: svelte: 3.55.1 dev: true - /svelte-loadable-store@1.0.1: - resolution: {integrity: sha512-ZPRBNqaDF6PW4nruHWh73b9WWdmt5SMAZ6he9KsZo4XDvl1h4jECBKPVdnHCc4zEQMCig01BofH3bwu67G44SQ==} + /svelte-loadable-store@1.0.7(svelte@3.55.1): + resolution: {integrity: sha512-FLahOiMtD9lxVNS9bzbdxHC8+D0y7qxZjaaeybCyxc9uzS3/9EMTSDpv/FMTLwncQ4syOtwz5oQBO+9iAqm7hQ==} + peerDependencies: + svelte: ^3.0.0 dependencies: - svelte: 3.59.1 + svelte: 3.55.1 dev: true /svelte-outclick@3.5.0(svelte@3.55.1): @@ -3738,11 +3740,6 @@ packages: engines: {node: '>= 8'} dev: true - /svelte@3.59.1: - resolution: {integrity: sha512-pKj8fEBmqf6mq3/NfrB9SLtcJcUvjYSWyePlfCqN9gujLB25RitWK8PvFzlwim6hD/We35KbPlRteuA6rnPGcQ==} - engines: {node: '>= 8'} - dev: true - /symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} dev: true diff --git a/src/lib/stores/deltas.ts b/src/lib/stores/deltas.ts index 3b0c673eb..49be29418 100644 --- a/src/lib/stores/deltas.ts +++ b/src/lib/stores/deltas.ts @@ -16,7 +16,9 @@ export default (params: { projectId: string; sessionId: string }) => { } else { set({ ...oldValue.value, - [filePath]: [...oldValue.value[filePath], ...newDeltas] + [filePath]: oldValue.value[filePath] + ? [...oldValue.value[filePath], ...newDeltas] + : newDeltas }); } }) diff --git a/src/routes/projects/[projectId]/player/[date]/+layout.svelte b/src/routes/projects/[projectId]/player/[date]/+layout.svelte index 090fb8f34..198d5af27 100644 --- a/src/routes/projects/[projectId]/player/[date]/+layout.svelte +++ b/src/routes/projects/[projectId]/player/[date]/+layout.svelte @@ -1,110 +1,69 @@
- {#await richSessions.load()} + {#if $richSessions.isLoading || $currentSession.isLoading}

Loading...

- {:then} -
-
-
🧰
-
Working History
-
- {$richSessions.length} -
-
-
- - - {/await} + {:else} + + {/if}
- {#await Promise.all([currentSession.load(), nextSessionId.load(), prevSessionId.load()])} + {#if $currentSession.isLoading || $richSessions.isLoading} Loading... - {:then} - {#if !$currentSession} - No session found - {:else} - - {format($currentSession.meta.startTimestampMs, 'EEEE, LLL d, HH:mm')} - - - {format($currentSession.meta.lastTimestampMs, 'HH:mm')} - - - {/if} - {/await} + {:else if !$currentSession.value} + No session found + {:else} + + {/if}
- + diff --git a/src/routes/projects/[projectId]/player/[date]/SessionCard.svelte b/src/routes/projects/[projectId]/player/[date]/SessionCard.svelte index f5bddbc48..f0ee1f3d1 100644 --- a/src/routes/projects/[projectId]/player/[date]/SessionCard.svelte +++ b/src/routes/projects/[projectId]/player/[date]/SessionCard.svelte @@ -2,34 +2,31 @@ import type { Delta, Session } from '$lib/api'; import { page } from '$app/stores'; import { collapse } from '$lib/paths'; - import { derived, type Loadable } from '@square/svelte-store'; + import { derived } from '@square/svelte-store'; import { stores } from '$lib'; import { IconBookmarkFilled } from '$lib/icons'; export let isCurrent: boolean; export let session: Session; export let currentFilepath: string; - export let deltas: Loadable>; + export let deltas: Record; - $: bookmarks = derived( - [stores.bookmarks({ projectId: session.projectId }), deltas], - ([bookmarks, deltas]) => { - if (bookmarks.isLoading) return []; - const timestamps = Object.values(deltas ?? {}).flatMap((deltas) => - deltas.map((d) => d.timestampMs) - ); - const start = Math.min(...timestamps); - const end = Math.max(...timestamps); - return bookmarks.value - .filter((bookmark) => !bookmark.deleted) - .filter((bookmark) => bookmark.timestampMs >= start && bookmark.timestampMs < end); - } - ); + $: bookmarks = derived(stores.bookmarks({ projectId: session.projectId }), (bookmarks) => { + if (bookmarks.isLoading) return []; + const timestamps = Object.values(deltas ?? {}).flatMap((deltas) => + deltas.map((d) => d.timestampMs) + ); + const start = Math.min(...timestamps); + const end = Math.max(...timestamps); + return bookmarks.value + .filter((bookmark) => !bookmark.deleted) + .filter((bookmark) => bookmark.timestampMs >= start && bookmark.timestampMs < end); + }); const unique = (value: any, index: number, self: any[]) => self.indexOf(value) === index; const lexically = (a: string, b: string) => a.localeCompare(b); - const changedFiles = derived(deltas, (deltas) => Object.keys(deltas ?? {}).filter(unique)); + const changedFiles = Object.keys(deltas ?? {}).filter(unique); const sessionDuration = (session: Session) => `${Math.round((session.meta.lastTimestampMs - session.meta.startTimestampMs) / 1000 / 60)} min`; @@ -59,9 +56,15 @@ `/projects/${$page.params.projectId}/player/${ $page.params.date }/${sessionId}?${removeFromSearchParams($page.url.searchParams, 'delta').toString()}`; + + let card: HTMLLIElement; + $: if (isCurrent) { + card?.scrollIntoView({ behavior: 'smooth' }); + }
  • - {$changedFiles.length} - {$changedFiles.length !== 1 ? 'files' : 'file'} + {changedFiles.length} + {changedFiles.length !== 1 ? 'files' : 'file'} {#if isCurrent} - {#await changedFiles.load() then} -
      - {#each $changedFiles.sort(lexically) as filename} -
    • - {collapse(filename)} -
    • - {/each} -
    - {/await} +
      + {#each changedFiles.sort(lexically) as filename} +
    • + {collapse(filename)} +
    • + {/each} +
    {/if}
  • diff --git a/src/routes/projects/[projectId]/player/[date]/SessionNavigations.svelte b/src/routes/projects/[projectId]/player/[date]/SessionNavigations.svelte new file mode 100644 index 000000000..2fb0416e6 --- /dev/null +++ b/src/routes/projects/[projectId]/player/[date]/SessionNavigations.svelte @@ -0,0 +1,98 @@ + + + + {format(currentSession.meta.startTimestampMs, 'EEEE, LLL d, HH:mm')} + - + {format(currentSession.meta.lastTimestampMs, 'HH:mm')} + + +
    + {#if !$prevSessionId.isLoading && !$nextSessionId.isLoading} + + + + + + + {/if} +
    diff --git a/src/routes/projects/[projectId]/player/[date]/SessionsList.svelte b/src/routes/projects/[projectId]/player/[date]/SessionsList.svelte new file mode 100644 index 000000000..30775f4d1 --- /dev/null +++ b/src/routes/projects/[projectId]/player/[date]/SessionsList.svelte @@ -0,0 +1,49 @@ + + +
    +
    +
    🧰
    +
    Working History
    +
    + {visibleSessions.filter(({ visible }) => visible).length} +
    +
    +
    + +
      + {#each visibleSessions as session, i} + {@const isCurrent = session.id === currentSession?.id} + {#if session.visible && !$visibleDeltas.isLoading} + + {/if} + {:else} +
      No activities found
      + {/each} +