mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-11-29 06:18:12 +03:00
Increase selection and recording functionality
- Added a button to each delta for selection - Updated the `session` store to return the first session if the sessionId is not found - Updated the `previousSession` store to return the session before the current one if it exists - Updated the `docsNext` derived store to include the `selection` store - Added an `if` statement for `files` in `+page.svelte` [src/routes/projects/[projectId]/sessions/[sessionId]/+page.ts] - Changed the import of `svelte/store` to include `writable` - Changed the `session` store to return the first session if the sessionId is not found - Changed the `previousSession` store to return the session before the current one if it exists [src/routes/projects/[projectId]/sessions/[sessionId]/+page.svelte] - Move the `Timeline` component import from `+page.svelte` - Initialize `selection` store in `+page.svelte` - Update `docsNext` derived store to include the `selection` store - Add a button to each delta for selection - Add an `if` statement for `files` in `+page.svelte` - Delete `contentWithDeltasApplied` function from `+page.
This commit is contained in:
parent
5697b204cb
commit
c5c46e8a25
@ -1,9 +1,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Doc } from "yjs";
|
import { Doc } from "yjs";
|
||||||
import { Timeline, CodeViewer } from "$lib/components";
|
import { CodeViewer } from "$lib/components";
|
||||||
import { Operation } from "$lib/deltas";
|
import { Operation } from "$lib/deltas";
|
||||||
import type { Delta } from "$lib/deltas";
|
import { derived } from "svelte/store";
|
||||||
import { derived, writable } from "svelte/store";
|
|
||||||
import type { PageData } from "./$types";
|
import type { PageData } from "./$types";
|
||||||
import SessionNav from "$lib/components/session/SessionNav.svelte";
|
import SessionNav from "$lib/components/session/SessionNav.svelte";
|
||||||
import { toHumanReadableTime } from "$lib/time";
|
import { toHumanReadableTime } from "$lib/time";
|
||||||
@ -15,21 +14,32 @@
|
|||||||
$: nextSession = data.nextSession;
|
$: nextSession = data.nextSession;
|
||||||
$: session = data.session;
|
$: session = data.session;
|
||||||
$: deltas = data.deltas;
|
$: deltas = data.deltas;
|
||||||
$: files = data.files;
|
|
||||||
|
|
||||||
const value = writable(new Date().getTime());
|
$: selection = {} as Record<string, Record<string, number>>;
|
||||||
|
|
||||||
const docs = derived(value, (value) =>
|
$: docsNext = derived([data.deltas], ([deltas]) =>
|
||||||
Object.fromEntries(
|
Object.fromEntries(
|
||||||
Object.entries($deltas).map(([filePath, deltas]) => {
|
Object.entries(deltas).map(([filePath, deltas]) => {
|
||||||
const doc = new Doc();
|
const doc = new Doc();
|
||||||
const text = doc.getText();
|
const text = doc.getText();
|
||||||
if (filePath in files) {
|
if (filePath in data.files) {
|
||||||
text.insert(0, files[filePath]);
|
text.insert(0, data.files[filePath]);
|
||||||
}
|
}
|
||||||
|
const contentAtStart = text.toString();
|
||||||
|
|
||||||
|
if (!selection.hasOwnProperty($session?.id)) {
|
||||||
|
selection[$session.id] = {};
|
||||||
|
}
|
||||||
|
if (!selection[$session.id].hasOwnProperty(filePath)) {
|
||||||
|
selection[$session?.id][filePath] = deltas.length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
const operations = deltas
|
const operations = deltas
|
||||||
.filter((delta) => delta.timestampMs <= value)
|
.filter(
|
||||||
|
(_, index) => index <= selection[$session.id][filePath]
|
||||||
|
)
|
||||||
.flatMap((delta) => delta.operations);
|
.flatMap((delta) => delta.operations);
|
||||||
|
|
||||||
operations.forEach((operation) => {
|
operations.forEach((operation) => {
|
||||||
if (Operation.isInsert(operation)) {
|
if (Operation.isInsert(operation)) {
|
||||||
text.insert(operation.insert[0], operation.insert[1]);
|
text.insert(operation.insert[0], operation.insert[1]);
|
||||||
@ -37,36 +47,12 @@
|
|||||||
text.delete(operation.delete[0], operation.delete[1]);
|
text.delete(operation.delete[0], operation.delete[1]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return [filePath, text.toString()];
|
|
||||||
|
const contentAfterDeltas = text.toString();
|
||||||
|
return [filePath, { a: contentAtStart, b: contentAfterDeltas }];
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
const contentWithDeltasApplied = (
|
|
||||||
contentAtSessionStart: string,
|
|
||||||
deltas: Delta[]
|
|
||||||
) => {
|
|
||||||
const doc = new Doc();
|
|
||||||
const text = doc.getText();
|
|
||||||
text.insert(0, contentAtSessionStart);
|
|
||||||
const operations = deltas.flatMap((delta) => delta.operations);
|
|
||||||
operations.forEach((operation) => {
|
|
||||||
if (Operation.isInsert(operation)) {
|
|
||||||
text.insert(operation.insert[0], operation.insert[1]);
|
|
||||||
} else if (Operation.isDelete(operation)) {
|
|
||||||
text.delete(operation.delete[0], operation.delete[1]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return text.toString();
|
|
||||||
};
|
|
||||||
|
|
||||||
// const timestamps = Object.values(deltas).flatMap((deltas) =>
|
|
||||||
// Object.values(deltas).map((delta) => delta.timestampMs)
|
|
||||||
// );
|
|
||||||
|
|
||||||
// const min = Math.min(...timestamps);
|
|
||||||
// const max = Math.max(...timestamps);
|
|
||||||
// const showTimeline = isFinite(min) && isFinite(max);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex flex-col w-full h-full overflow-hidden space-y-2">
|
<div class="flex flex-col w-full h-full overflow-hidden space-y-2">
|
||||||
@ -78,36 +64,30 @@
|
|||||||
previousSesssion={$previousSesssion}
|
previousSesssion={$previousSesssion}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="overflow-auto h-2/3 mx-4">
|
<div class="overflow-auto h-2/3 mx-4">
|
||||||
{#each Object.entries(files) as [filepath, contentAtSessionStart]}
|
{#each Object.entries($docsNext) as [filepath, content]}
|
||||||
{#if $deltas[filepath]}
|
<details open>
|
||||||
<details open>
|
<summary>{filepath}</summary>
|
||||||
<summary>
|
<div class="flex flex-col">
|
||||||
{filepath}
|
<div class="flex space-x-1">
|
||||||
</summary>
|
{#each $deltas[filepath] as delta, i}
|
||||||
<CodeViewer
|
<button
|
||||||
value={contentAtSessionStart}
|
on:click={() => {
|
||||||
newValue={contentWithDeltasApplied(
|
selection[$session.id][filepath] = i;
|
||||||
contentAtSessionStart,
|
}}
|
||||||
$deltas[filepath]
|
class="{selection[$session.id][filepath] == i
|
||||||
)}
|
? 'bg-orange-300'
|
||||||
/>
|
: ''} text-center items-center justify-center text-xs rounded-full h-4 w-4 bg-zinc-400 text-zinc-600 hover:bg-zinc-200"
|
||||||
</details>
|
title={toHumanReadableTime(delta.timestampMs)}
|
||||||
{/if}
|
>
|
||||||
{/each}
|
<span>{delta.operations.length}</span>
|
||||||
</div>
|
</button>
|
||||||
<div class="flex flex-col border-t border-zinc-700 mt-2">
|
{/each}
|
||||||
{#each Object.entries($deltas) as [filepath, deltas]}
|
</div>
|
||||||
<div class="flex">
|
<CodeViewer value={content.a} newValue={content.b} />
|
||||||
<div class="w-32">{filepath}</div>
|
|
||||||
<div class="flex space-x-2 items-center">
|
|
||||||
{#each deltas as delta}
|
|
||||||
<div class="cursor-pointer text-center items-center justify-center text-xs rounded-full h-4 w-4 bg-zinc-400 text-zinc-600 hover:bg-zinc-200" title="{toHumanReadableTime(delta.timestampMs)}">
|
|
||||||
<span>{delta.operations.length}</span>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</details>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { PageLoad } from "./$types";
|
import type { PageLoad } from "./$types";
|
||||||
import { derived, readable } from "svelte/store";
|
import { derived, readable, writable } from "svelte/store";
|
||||||
import { building } from "$app/environment";
|
import { building } from "$app/environment";
|
||||||
import type { Delta } from "$lib/deltas";
|
import type { Delta } from "$lib/deltas";
|
||||||
|
|
||||||
@ -19,8 +19,10 @@ export const load: PageLoad = async ({ parent, params }) => {
|
|||||||
sessionId: params.sessionId,
|
sessionId: params.sessionId,
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
session: derived(sessions, (sessions) =>
|
session: derived(sessions, (sessions) => {
|
||||||
sessions.find((session) => session.id === params.sessionId)
|
const result = sessions.find((session) => session.id === params.sessionId)
|
||||||
|
return result ? result : sessions[0];
|
||||||
|
}
|
||||||
),
|
),
|
||||||
previousSesssion: derived(sessions, (sessions) => {
|
previousSesssion: derived(sessions, (sessions) => {
|
||||||
const currentSessionIndex = sessions.findIndex(
|
const currentSessionIndex = sessions.findIndex(
|
||||||
|
Loading…
Reference in New Issue
Block a user