mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-12-29 20:43:37 +03:00
cleanup new timeline layout +some animations
This commit is contained in:
parent
32368fb689
commit
a6a3df025e
@ -39,7 +39,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="flex-auto overflow-auto bg-zinc-800 text-zinc-400">
|
<div class="flex-auto overflow-auto bg-zinc-900 text-zinc-400">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
<Toaster />
|
<Toaster />
|
||||||
|
@ -7,6 +7,10 @@
|
|||||||
import { startOfDay } from "date-fns";
|
import { startOfDay } from "date-fns";
|
||||||
import { list as listDeltas } from "$lib/deltas";
|
import { list as listDeltas } from "$lib/deltas";
|
||||||
import type { Delta } from "$lib/deltas";
|
import type { Delta } from "$lib/deltas";
|
||||||
|
import { toHumanBranchName } from "$lib/branch";
|
||||||
|
import { fly } from "svelte/transition";
|
||||||
|
import { quintOut } from "svelte/easing";
|
||||||
|
import { crossfade } from "svelte/transition";
|
||||||
|
|
||||||
export let data: PageData;
|
export let data: PageData;
|
||||||
const { project, sessions } = data;
|
const { project, sessions } = data;
|
||||||
@ -92,13 +96,17 @@
|
|||||||
selection = {} as Selection;
|
selection = {} as Selection;
|
||||||
};
|
};
|
||||||
|
|
||||||
function scrollExpandedIntoView() {
|
function scrollExpandedIntoView(dateMilliseconds: string) {
|
||||||
new Promise((r) => setTimeout(r, 100)).then(() => {
|
new Promise((r) => setTimeout(r, 10)).then(() => {
|
||||||
document.getElementById("expanded").scrollIntoView({
|
document.getElementById(dateMilliseconds).scrollIntoView({
|
||||||
behavior: "smooth",
|
// behavior: "smooth",
|
||||||
|
block: "center",
|
||||||
|
inline: "center",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let animatingOut = false;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="h-full">
|
<div class="h-full">
|
||||||
@ -108,192 +116,135 @@
|
|||||||
<span>Loading...</span>
|
<span>Loading...</span>
|
||||||
{:else}
|
{:else}
|
||||||
<div
|
<div
|
||||||
class="h-full flex-auto flex flex-row overflow-x-auto space-x-12 px-4 py-4"
|
class="h-full flex-auto flex flex-row overflow-x-auto space-x-12 px-4 py-4 pb-6"
|
||||||
>
|
>
|
||||||
{#each Object.entries($dateSessions) as [dateMilliseconds, uiSessions]}
|
{#each Object.entries($dateSessions) as [dateMilliseconds, uiSessions]}
|
||||||
{#if selection.dateMilliseconds == +dateMilliseconds}
|
<!-- Day -->
|
||||||
<!-- Day expanded -->
|
<div
|
||||||
|
id={dateMilliseconds}
|
||||||
|
class="bg-zinc-800/50 rounded-xl border border-zinc-700 flex flex-col space-y-2
|
||||||
|
{selection.dateMilliseconds == +dateMilliseconds
|
||||||
|
? 'min-w-full overflow-x-hidden'
|
||||||
|
: ''}
|
||||||
|
"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
class="bg-zinc-600 py-1 min-w-full overflow-x-hidden"
|
class="font-medium border-b border-zinc-700 bg-zinc-700/30 h-6 flex items-center pl-4"
|
||||||
>
|
>
|
||||||
<div>
|
<span
|
||||||
|
class={animatingOut
|
||||||
|
? "animate-pulse text-orange-300"
|
||||||
|
: ""}
|
||||||
|
>
|
||||||
{formatDate(new Date(+dateMilliseconds))}
|
{formatDate(new Date(+dateMilliseconds))}
|
||||||
</div>
|
</span>
|
||||||
<div class="flex space-x-2 " id="expanded">
|
|
||||||
{#each uiSessions as uiSession, i}
|
|
||||||
<!-- Session (overview) -->
|
|
||||||
<!-- Only show nearest neighbors -->
|
|
||||||
{#if Math.abs(i - selection.sessionIdx) < 2}
|
|
||||||
{#if i === selection.sessionIdx}
|
|
||||||
<!-- content here -->
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="bg-zinc-700 {i ==
|
|
||||||
selection.sessionIdx
|
|
||||||
? 'flex-grow'
|
|
||||||
: 'w-4'}"
|
|
||||||
>
|
|
||||||
<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>
|
|
||||||
<button
|
|
||||||
on:click={resetSelection}
|
|
||||||
>close</button
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
{:else}
|
|
||||||
<div
|
|
||||||
class="bg-zinc-700 {i ==
|
|
||||||
selection.sessionIdx
|
|
||||||
? 'flex-grow'
|
|
||||||
: 'w-4'}"
|
|
||||||
>
|
|
||||||
<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(
|
|
||||||
filePath
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="text-white w-24 truncate"
|
|
||||||
>
|
|
||||||
{pathToName(
|
|
||||||
filePath
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
{/if}
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
<div
|
||||||
<!-- Day -->
|
class="h-2/3 flex space-x-2 border-b border-zinc-700 px-4"
|
||||||
<div class="bg-zinc-600 py-1 flex flex-col">
|
>
|
||||||
<div>
|
{#if selection.dateMilliseconds !== +dateMilliseconds}
|
||||||
{formatDate(new Date(+dateMilliseconds))}
|
|
||||||
</div>
|
|
||||||
<div class="h-2/3 flex space-x-2">
|
|
||||||
{#each uiSessions as uiSession, i}
|
{#each uiSessions as uiSession, i}
|
||||||
<!-- Session (overview) -->
|
<!-- Session (overview) -->
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="bg-zinc-700 overflow-y-auto"
|
out:fly={{
|
||||||
|
x: i <= 3 ? -800 : 800,
|
||||||
|
duration: 900,
|
||||||
|
}}
|
||||||
|
on:outrostart={() =>
|
||||||
|
(animatingOut = true)}
|
||||||
|
on:outroend={() =>
|
||||||
|
(animatingOut = false)}
|
||||||
|
class="flex flex-col py-2 w-40"
|
||||||
>
|
>
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<div
|
<div
|
||||||
class="text-sm rounded borded bg-orange-500 text-zinc-200"
|
class="
|
||||||
|
cursor-pointer
|
||||||
|
text-sm text-center font-medium rounded borded text-zinc-800 p-1 border bg-orange-400 border-orange-400 hover:bg-[#fdbc87]"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
selection = {
|
selection = {
|
||||||
sessionIdx: i,
|
sessionIdx: i,
|
||||||
dateMilliseconds:
|
dateMilliseconds:
|
||||||
+dateMilliseconds,
|
+dateMilliseconds,
|
||||||
};
|
};
|
||||||
scrollExpandedIntoView();
|
scrollExpandedIntoView(
|
||||||
|
dateMilliseconds
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{formatTime(
|
{i}
|
||||||
new Date(
|
{toHumanBranchName(
|
||||||
uiSession.session.meta.startTimestampMs
|
uiSession.session.meta
|
||||||
)
|
.branch
|
||||||
)}
|
|
||||||
-
|
|
||||||
{formatTime(
|
|
||||||
new Date(
|
|
||||||
uiSession.session.meta.lastTimestampMs
|
|
||||||
)
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div title="Session duration">
|
|
||||||
{Math.round(
|
<div
|
||||||
(uiSession.session.meta
|
class="flex flex-col h-full overflow-y-hidden p-1"
|
||||||
.lastTimestampMs -
|
id="sessions-details"
|
||||||
uiSession.session.meta
|
>
|
||||||
.startTimestampMs) /
|
<div
|
||||||
1000 /
|
class="text-zinc-400 font-medium"
|
||||||
60
|
>
|
||||||
)} min
|
{formatTime(
|
||||||
</div>
|
new Date(
|
||||||
<div class="" title="Session files">
|
uiSession.session.meta.startTimestampMs
|
||||||
{#each Object.keys(uiSession.deltas) as filePath}
|
)
|
||||||
<div
|
)}
|
||||||
class="flex flex-row w-32 items-center"
|
-
|
||||||
>
|
{formatTime(
|
||||||
|
new Date(
|
||||||
|
uiSession.session.meta.lastTimestampMs
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="text-zinc-500 text-sm"
|
||||||
|
title="Session duration"
|
||||||
|
>
|
||||||
|
{Math.round(
|
||||||
|
(uiSession.session.meta
|
||||||
|
.lastTimestampMs -
|
||||||
|
uiSession.session
|
||||||
|
.meta
|
||||||
|
.startTimestampMs) /
|
||||||
|
1000 /
|
||||||
|
60
|
||||||
|
)} min
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="overflow-y-auto overflow-x-hidden"
|
||||||
|
title="Session files"
|
||||||
|
>
|
||||||
|
{#each Object.keys(uiSession.deltas) as filePath}
|
||||||
<div
|
<div
|
||||||
class="w-6 h-6 text-white fill-blue-400"
|
class="flex flex-row w-32 items-center"
|
||||||
>
|
>
|
||||||
{@html pathToIconSvg(
|
<div
|
||||||
filePath
|
class="w-6 h-6 text-zinc-200 fill-blue-400"
|
||||||
)}
|
>
|
||||||
|
{@html pathToIconSvg(
|
||||||
|
filePath
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="text-zinc-300 w-24 truncate"
|
||||||
|
>
|
||||||
|
{pathToName(
|
||||||
|
filePath
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
{/each}
|
||||||
class="text-white w-24 truncate"
|
</div>
|
||||||
>
|
|
||||||
{pathToName(
|
|
||||||
filePath
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
{/if}
|
||||||
<div class="flex-grow border border-green-700">
|
|
||||||
Day summary
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
<div class="flex-grow px-4">Day summary</div>
|
||||||
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
Loading…
Reference in New Issue
Block a user