diff --git a/src/lib/components/CommandPalette/commands.ts b/src/lib/components/CommandPalette/commands.ts index eb52a9807..c89f15c2f 100644 --- a/src/lib/components/CommandPalette/commands.ts +++ b/src/lib/components/CommandPalette/commands.ts @@ -1,5 +1,5 @@ import { type Project, git } from '$lib/api'; -import { events, stores } from '$lib'; +import { events } from '$lib'; import { IconGitCommit, IconFile, @@ -13,6 +13,8 @@ import { IconBookmark } from '$lib/icons'; import type { SvelteComponent } from 'svelte'; +import { page } from '$app/stores'; +import { get } from '@square/svelte-store'; type ActionLink = { href: string; @@ -80,6 +82,22 @@ const projectsGroup = ({ projects, input }: { projects: Project[]; input: string const commandsGroup = ({ project, input }: { project?: Project; input: string }): Group => ({ title: 'Commands', commands: [ + ...(project && get(page).params.date + ? [ + { + title: 'Bookmark', + hotkey: 'Meta+Shift+D', + action: () => events.emit('openBookmarkModal'), + icon: IconBookmark + }, + { + title: 'Quick Bookmark', + hotkey: 'D', + action: () => events.emit('createBookmark', { projectId: project.id }), + icon: IconBookmark + } + ] + : []), ...(project ? [ { @@ -96,18 +114,6 @@ const commandsGroup = ({ project, input }: { project?: Project; input: string }) }, icon: IconRewind }, - { - title: 'Quick Bookmark', - hotkey: 'D', - action: () => stores.bookmarks({ projectId: project.id }).create(), - icon: IconBookmark - }, - { - title: 'Bookmark', - hotkey: 'Meta+Shift+D', - action: () => events.emit('openBookmarkModal'), - icon: IconBookmark - }, { title: 'Project settings', hotkey: 'Meta+Shift+,', diff --git a/src/lib/events.ts b/src/lib/events.ts index 01d9d7d5a..dc7616d25 100644 --- a/src/lib/events.ts +++ b/src/lib/events.ts @@ -8,6 +8,7 @@ type Events = { openQuickCommitModal: () => void; openSendIssueModal: () => void; openBookmarkModal: () => void; + createBookmark: (params: { projectId: string }) => void; }; const events = createNanoEvents(); diff --git a/src/lib/stores/bookmarks.ts b/src/lib/stores/bookmarks.ts index c48650bfe..68816f2ad 100644 --- a/src/lib/stores/bookmarks.ts +++ b/src/lib/stores/bookmarks.ts @@ -21,7 +21,6 @@ export default (params: { projectId: string }): Store => { if (!oldBookmark) return true; return oldBookmark !== bookmark; }); - console.log('changedBookmarks', changedBookmarks); await Promise.all(changedBookmarks.map((bookmark) => bookmarks.upsert(bookmark))); return newValue; } diff --git a/src/routes/projects/[projectId]/+layout.svelte b/src/routes/projects/[projectId]/+layout.svelte index 301d67004..471ccdb1f 100644 --- a/src/routes/projects/[projectId]/+layout.svelte +++ b/src/routes/projects/[projectId]/+layout.svelte @@ -10,8 +10,6 @@ import { unsubscribe } from '$lib/utils'; import { PUBLIC_API_BASE_URL } from '$env/static/public'; import { events, hotkeys, stores } from '$lib'; - import BookmarkModal from './BookmarkModal.svelte'; - import { bookmarks } from '$lib/stores'; export let data: LayoutData; const { cloud, project, head, statuses, diffs } = data; @@ -28,14 +26,10 @@ $: selection = $page?.route?.id?.split('/')?.[3]; let quickCommitModal: QuickCommitModal; - let bookmarkModal: BookmarkModal; onMount(() => unsubscribe( events.on('openQuickCommitModal', () => quickCommitModal?.show()), - events.on('openBookmarkModal', () => bookmarkModal?.show()), - hotkeys.on('D', () => bookmarks({ projectId: $project.id }).create()), - hotkeys.on('Meta+Shift+D', () => bookmarkModal?.show()), hotkeys.on('C', () => events.emit('openQuickCommitModal')), hotkeys.on('Meta+Shift+C', () => goto(`/projects/${$project.id}/commit/`)), hotkeys.on('Meta+T', () => goto(`/projects/${$project.id}/terminal/`)), @@ -165,7 +159,3 @@ /> {/if} {/await} - -{#await project.load() then} - -{/await} diff --git a/src/routes/projects/[projectId]/player/[date]/+layout.svelte b/src/routes/projects/[projectId]/player/[date]/+layout.svelte index 883a82fbe..8be98b29a 100644 --- a/src/routes/projects/[projectId]/player/[date]/+layout.svelte +++ b/src/routes/projects/[projectId]/player/[date]/+layout.svelte @@ -23,11 +23,14 @@ import { asyncDerived, derived } from '@square/svelte-store'; import { format } from 'date-fns'; import { onMount } from 'svelte'; + import { events, hotkeys, stores, toasts } from '$lib'; + import BookmarkModal from './BookmarkModal.svelte'; import tinykeys from 'tinykeys'; import { goto } from '$app/navigation'; + import { unsubscribe } from '$lib/utils'; export let data: LayoutData; - const { currentFilepath } = data; + const { currentFilepath, currentTimestamp } = data; const unique = (value: any, index: number, self: any[]) => self.indexOf(value) === index; const lexically = (a: string, b: string) => a.localeCompare(b); @@ -116,17 +119,30 @@ $page.params.date }/${sessionId}?${removeFromSearchParams($page.url.searchParams, 'delta').toString()}`; + let bookmarkModal: BookmarkModal; + onMount(() => - tinykeys(window, { - 'Shift+ArrowRight': () => - nextSessionId.load().then((sessionId) => { - if (sessionId) goto(getSessionURI(sessionId)); - }), - 'Shift+ArrowLeft': () => - prevSessionId.load().then((sessionId) => { - if (sessionId) goto(getSessionURI(sessionId)); - }) - }) + unsubscribe( + tinykeys(window, { + 'Shift+ArrowRight': () => + nextSessionId.load().then((sessionId) => { + if (sessionId) goto(getSessionURI(sessionId)); + }), + 'Shift+ArrowLeft': () => + prevSessionId.load().then((sessionId) => { + if (sessionId) goto(getSessionURI(sessionId)); + }) + }), + + events.on('openBookmarkModal', () => bookmarkModal?.show($currentTimestamp)), + hotkeys.on('Meta+Shift+D', () => bookmarkModal?.show($currentTimestamp)), + hotkeys.on('D', () => + stores + .bookmarks({ projectId: $projectId }) + .create({ timestampMs: $currentTimestamp }) + .then(() => toasts.success('Bookmark created')) + ) + ) ); @@ -240,3 +256,5 @@ + + diff --git a/src/routes/projects/[projectId]/player/[date]/+layout.ts b/src/routes/projects/[projectId]/player/[date]/+layout.ts index b69936cff..7b689ad41 100644 --- a/src/routes/projects/[projectId]/player/[date]/+layout.ts +++ b/src/routes/projects/[projectId]/player/[date]/+layout.ts @@ -3,5 +3,6 @@ import type { LayoutLoad } from './$types'; export const load: LayoutLoad = () => ({ currentFilepath: writable(''), - currentSessionId: writable('') + currentSessionId: writable(''), + currentTimestamp: writable(-1) }); diff --git a/src/routes/projects/[projectId]/BookmarkModal.svelte b/src/routes/projects/[projectId]/player/[date]/BookmarkModal.svelte similarity index 90% rename from src/routes/projects/[projectId]/BookmarkModal.svelte rename to src/routes/projects/[projectId]/player/[date]/BookmarkModal.svelte index 00b6de953..06438bd9e 100644 --- a/src/routes/projects/[projectId]/BookmarkModal.svelte +++ b/src/routes/projects/[projectId]/player/[date]/BookmarkModal.svelte @@ -8,13 +8,16 @@ const bookmarks = stores.bookmarks({ projectId }); let isCreating = false; + let timestampMs: number | undefined; const reset = () => { note = ''; + timestampMs = undefined; }; - export const show = () => { + export const show = (ts: number) => { reset(); + timestampMs = ts; modal.show(); }; @@ -24,7 +27,7 @@ const createBookmark = () => Promise.resolve() .then(() => (isCreating = true)) - .then(() => bookmarks.create({ note })) + .then(() => bookmarks.create({ note, timestampMs })) .then(() => { toasts.success('Bookmark created'); modal.close(); diff --git a/src/routes/projects/[projectId]/player/[date]/[sessionId]/+page.svelte b/src/routes/projects/[projectId]/player/[date]/[sessionId]/+page.svelte index d71557893..e0e2bc708 100644 --- a/src/routes/projects/[projectId]/player/[date]/[sessionId]/+page.svelte +++ b/src/routes/projects/[projectId]/player/[date]/[sessionId]/+page.svelte @@ -30,10 +30,11 @@ import { asyncDerived, derived, writable } from '@square/svelte-store'; import { format } from 'date-fns'; import { onMount } from 'svelte'; - import tinykeys from 'tinykeys'; + import { unsubscribe } from '$lib/utils'; + import { hotkeys } from '$lib'; export let data: PageData; - const { currentFilepath } = data; + const { currentFilepath, currentTimestamp } = data; let fullContext = true; let context = 8; @@ -112,6 +113,14 @@ }); frame.subscribe((frame) => frame?.filepath && currentFilepath.set(frame.filepath)); + $: currentDelta = $frame?.deltas[$frame?.deltas.length - 1]; + $: { + const timestamp = currentDelta?.timestampMs; + if (timestamp) { + currentTimestamp.set(timestamp); + } + } + // scroller const maxInput = derived(richSessions, (sessions) => sessions ? sessions.flatMap((session) => session.deltas).length : 0 @@ -182,17 +191,17 @@ }; onMount(() => - tinykeys(window, { - ArrowRight: gotoNextDelta, - ArrowLeft: gotoPrevDelta, - Space: () => { + unsubscribe( + hotkeys.on('ArrowRight', () => gotoNextDelta()), + hotkeys.on('ArrowLeft', () => gotoPrevDelta()), + hotkeys.on('Space', () => { if (isPlaying) { stop(); } else { play(); } - } - }) + }) + ) ); @@ -218,23 +227,27 @@ -
- - {collapse($frame.filepath)} - - - – - {new Date($frame.deltas[$frame.deltas.length - 1].timestampMs).toLocaleString('en-US')} - -
+ > + + {collapse($frame.filepath)} + + + – + {currentDelta.timestampMs} + – + {new Date(currentDelta.timestampMs).toLocaleString('en-US')} + + + {/if}