mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-12-23 01:22:12 +03:00
Found this nice way of doing async derived stores
This commit is contained in:
parent
e8d8d158ce
commit
d9dc79a4b4
@ -17,6 +17,7 @@
|
||||
"@codemirror/merge": "^0.1.3",
|
||||
"@codemirror/state": "^6.2.0",
|
||||
"@codemirror/view": "^6.7.3",
|
||||
"@square/svelte-store": "^1.0.14",
|
||||
"@tauri-apps/api": "^1.2.0",
|
||||
"date-fns": "^2.29.3",
|
||||
"fluent-svelte": "^1.6.0",
|
||||
@ -35,16 +36,16 @@
|
||||
"@sveltejs/kit": "next",
|
||||
"@tauri-apps/cli": "^1.2.2",
|
||||
"@types/diff": "^5.0.2",
|
||||
"autoprefixer": "^10.4.7",
|
||||
"@typescript-eslint/eslint-plugin": "^5.45.0",
|
||||
"@typescript-eslint/parser": "^5.45.0",
|
||||
"autoprefixer": "^10.4.7",
|
||||
"eslint": "^8.28.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-svelte3": "^4.0.0",
|
||||
"prettier": "^2.8.0",
|
||||
"prettier-plugin-svelte": "^2.8.1",
|
||||
"postcss": "^8.4.14",
|
||||
"postcss-load-config": "^4.0.1",
|
||||
"prettier": "^2.8.0",
|
||||
"prettier-plugin-svelte": "^2.8.1",
|
||||
"svelte": "^3.55.1",
|
||||
"svelte-check": "^3.0.1",
|
||||
"tailwindcss": "^3.1.5",
|
||||
|
@ -5,6 +5,7 @@ specifiers:
|
||||
'@codemirror/merge': ^0.1.3
|
||||
'@codemirror/state': ^6.2.0
|
||||
'@codemirror/view': ^6.7.3
|
||||
'@square/svelte-store': ^1.0.14
|
||||
'@sveltejs/adapter-static': next
|
||||
'@sveltejs/kit': next
|
||||
'@tauri-apps/api': ^1.2.0
|
||||
@ -43,6 +44,7 @@ dependencies:
|
||||
'@codemirror/merge': 0.1.3
|
||||
'@codemirror/state': 6.2.0
|
||||
'@codemirror/view': 6.7.3
|
||||
'@square/svelte-store': 1.0.14
|
||||
'@tauri-apps/api': 1.2.0
|
||||
date-fns: 2.29.3
|
||||
fluent-svelte: 1.6.0
|
||||
@ -411,6 +413,13 @@ packages:
|
||||
resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==}
|
||||
dev: true
|
||||
|
||||
/@square/svelte-store/1.0.14:
|
||||
resolution: {integrity: sha512-kNaSpEec2JevfOB9XaWkq00oAOvm2fq8/0yotg++UVEHuHXQqM6pW602ByjBwFHn1gTRSdb568BAtkEDBt5uKQ==}
|
||||
dependencies:
|
||||
cookie-storage: 6.1.0
|
||||
svelte: 3.55.1
|
||||
dev: false
|
||||
|
||||
/@sveltejs/adapter-static/1.0.0-next.50_l5ueyfihz3gpzzvvyo2ean5u3e:
|
||||
resolution: {integrity: sha512-xZKBmiwFGW8nrH8+eysUAAo9XrtApI81q0m67y1bexVw8IY7/x741b6VEklNM7BZ7js0Mi2x+yCkHpOee8UZKQ==}
|
||||
peerDependencies:
|
||||
@ -992,6 +1001,10 @@ packages:
|
||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||
dev: true
|
||||
|
||||
/cookie-storage/6.1.0:
|
||||
resolution: {integrity: sha512-HeVqbVy8BjXhAAuFtL6MTG+witHoLbxfky2jgVh9FmxmyL6IKa9gSSyPNjevXCCCxPu6Tzd9J8+eXTRQzYU/cg==}
|
||||
dev: false
|
||||
|
||||
/cookie/0.5.0:
|
||||
resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
@ -2,9 +2,11 @@
|
||||
import { themeIcons } from 'seti-icons';
|
||||
import type { PageData } from './$types';
|
||||
import { derived } from 'svelte/store';
|
||||
import { asyncDerived } from '@square/svelte-store';
|
||||
import type { Session } from '$lib/sessions';
|
||||
import { startOfDay } from 'date-fns';
|
||||
import { list as listDeltas } from '$lib/deltas';
|
||||
import type { Delta } from '$lib/deltas';
|
||||
|
||||
export let data: PageData;
|
||||
const { project, sessions } = data;
|
||||
@ -48,17 +50,36 @@
|
||||
return svg;
|
||||
}
|
||||
|
||||
$: dateSessions = derived([sessions], ([sessions]) => {
|
||||
const dateSessions: Record<number, Session[]> = {};
|
||||
sessions.forEach((session) => {
|
||||
const date = startOfDay(new Date(session.meta.startTimestampMs));
|
||||
type UISession = { session: Session; deltas: Record<string, Delta[]> };
|
||||
|
||||
$: dateSessions = asyncDerived([sessions], async ([sessions]) => {
|
||||
const deltas = await Promise.all(
|
||||
sessions.map((session) => {
|
||||
return listDeltas({
|
||||
projectId: $project?.id,
|
||||
sessionId: session.id
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
const uiSessions = sessions
|
||||
.map((session, i) => {
|
||||
return { session, deltas: deltas[i] } as UISession;
|
||||
})
|
||||
.filter((uiSession) => {
|
||||
return Object.keys(uiSession.deltas).length > 0;
|
||||
});
|
||||
|
||||
const dateSessions: Record<number, UISession[]> = {};
|
||||
uiSessions.forEach((uiSession) => {
|
||||
const date = startOfDay(new Date(uiSession.session.meta.startTimestampMs));
|
||||
if (dateSessions[date.getTime()]) {
|
||||
dateSessions[date.getTime()]?.push(session);
|
||||
dateSessions[date.getTime()]?.push(uiSession);
|
||||
} else {
|
||||
dateSessions[date.getTime()] = [session];
|
||||
dateSessions[date.getTime()] = [uiSession];
|
||||
}
|
||||
});
|
||||
// TODO: maybe sort?
|
||||
|
||||
return dateSessions;
|
||||
});
|
||||
</script>
|
||||
@ -67,43 +88,48 @@
|
||||
<div class="m-6 overflow-x-hidden w-full">
|
||||
All sessions
|
||||
<div class="flex flex-row border overflow-x-auto space-x-12 px-4 py-12">
|
||||
{#each Object.entries($dateSessions) as [dateMilliseconds, sessions]}
|
||||
<!-- Day -->
|
||||
<div class="bg-zinc-600 py-1 min-w-full overflow-hidden">
|
||||
<div>{formatDate(new Date(+dateMilliseconds))}</div>
|
||||
<div class="flex space-x-2 ">
|
||||
{#each sessions as session}
|
||||
<!-- Session -->
|
||||
<div>
|
||||
<div class="text-sm rounded borded bg-orange-500 text-zinc-200">
|
||||
{formatTime(new Date(session.meta.startTimestampMs))}
|
||||
-
|
||||
{formatTime(new Date(session.meta.lastTimestampMs))}
|
||||
</div>
|
||||
<div title="Session duration">
|
||||
{Math.round(
|
||||
(session.meta.lastTimestampMs - session.meta.startTimestampMs) / 1000 / 60
|
||||
)} min
|
||||
</div>
|
||||
<div title="Session files">
|
||||
{#await listDeltas( { projectId: $project?.id, sessionId: session.id } ) then deltas}
|
||||
{#each Object.keys(deltas) as delta}
|
||||
{#if $dateSessions === undefined}
|
||||
<span>Loading...</span>
|
||||
{:else}
|
||||
{#each Object.entries($dateSessions) as [dateMilliseconds, uiSessions]}
|
||||
<!-- Day -->
|
||||
<div class="bg-zinc-600 py-1 min-w-full overflow-hidden">
|
||||
<div>{formatDate(new Date(+dateMilliseconds))}</div>
|
||||
<div class="flex space-x-2 ">
|
||||
{#each uiSessions as uiSession}
|
||||
<!-- Session -->
|
||||
<div>
|
||||
<div class="text-sm rounded borded bg-orange-500 text-zinc-200">
|
||||
{formatTime(new Date(uiSession.session.meta.startTimestampMs))}
|
||||
-
|
||||
{formatTime(new Date(uiSession.session.meta.lastTimestampMs))}
|
||||
</div>
|
||||
<div title="Session duration">
|
||||
{Math.round(
|
||||
(uiSession.session.meta.lastTimestampMs -
|
||||
uiSession.session.meta.startTimestampMs) /
|
||||
1000 /
|
||||
60
|
||||
)} min
|
||||
</div>
|
||||
<div title="Session files">
|
||||
{#each Object.keys(uiSession.deltas) as filePath}
|
||||
<div class="flex flex-row w-32 items-center">
|
||||
<div class="w-6 h-6 text-white fill-blue-400">
|
||||
{@html pathToIconSvg(delta)}
|
||||
{@html pathToIconSvg(filePath)}
|
||||
</div>
|
||||
<div class="text-white w-24 truncate">
|
||||
{pathToName(delta)}
|
||||
{pathToName(filePath)}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
{/await}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user