lane style updates

This commit is contained in:
Pavel Laptev 2024-01-23 16:38:46 +01:00 committed by GitButler
parent 7f0434cbb1
commit db309df701
5 changed files with 278 additions and 253 deletions

View File

@ -205,9 +205,10 @@
flex-shrink: 1;
align-items: flex-start;
height: 100%;
padding: 0 var(--space-8);
/* padding: 0 var(--space-8); */
user-select: none;
}
.loading {
display: flex;
justify-content: center;

View File

@ -142,143 +142,164 @@
}
</script>
<div bind:this={rsViewport} class="branch-card resize-viewport" data-tauri-drag-region>
<ScrollableContainer>
<div style:width={`${laneWidth || $defaultBranchWidthRem}rem`} class="branch-card__contents">
<BranchHeader
{readonly}
{branchController}
{branch}
{base}
{githubService}
projectId={project.id}
on:action={(e) => {
if (e.detail == 'generate-branch-name') {
generateBranchName();
}
}}
/>
<!-- DROPZONES -->
<div class="branch-card" data-tauri-drag-region class:target-branch={branch.selectedForChanges}>
<div
bind:this={rsViewport}
style:width={`${laneWidth || $defaultBranchWidthRem}rem`}
class="branch-card__contents"
class:first-child={branch.order == 0}
>
<BranchHeader
{readonly}
{branchController}
{branch}
{base}
{githubService}
projectId={project.id}
on:action={(e) => {
if (e.detail == 'generate-branch-name') {
generateBranchName();
}
}}
/>
<!-- DROPZONES -->
<DropzoneOverlay class="cherrypick-dz-marker" label="Apply here" />
<DropzoneOverlay class="lane-dz-marker" label="Move here" />
<div
class="branch-card__dropzone-wrapper"
use:dropzone={{
hover: 'cherrypick-dz-hover',
active: 'cherrypick-dz-active',
accepts: acceptCherrypick,
onDrop: onCherrypicked
}}
use:dropzone={{
hover: 'lane-dz-hover',
active: 'lane-dz-active',
accepts: acceptBranchDrop,
onDrop: onBranchDrop
}}
>
<DropzoneOverlay class="cherrypick-dz-marker" label="Apply here" />
<DropzoneOverlay class="lane-dz-marker" label="Move here" />
<div
class="branch-card__dropzone-wrapper"
use:dropzone={{
hover: 'cherrypick-dz-hover',
active: 'cherrypick-dz-active',
accepts: acceptCherrypick,
onDrop: onCherrypicked
}}
use:dropzone={{
hover: 'lane-dz-hover',
active: 'lane-dz-active',
accepts: acceptBranchDrop,
onDrop: onBranchDrop
}}
>
<DropzoneOverlay class="cherrypick-dz-marker" label="Apply here" />
<DropzoneOverlay class="lane-dz-marker" label="Move here" />
{#if branch.files?.length > 0}
<div class="card">
<BranchFiles
{#if branch.files?.length > 0}
<div class="card">
<BranchFiles
{branch}
{readonly}
{selectedOwnership}
{selectedFiles}
showCheckboxes={$commitBoxOpen}
/>
{#if branch.active}
<CommitDialog
projectId={project.id}
{branchController}
{branch}
{readonly}
{cloud}
{selectedOwnership}
{selectedFiles}
showCheckboxes={$commitBoxOpen}
{user}
bind:expanded={commitBoxOpen}
on:action={(e) => {
if (e.detail == 'generate-branch-name') {
generateBranchName();
}
}}
/>
{#if branch.active}
<CommitDialog
projectId={project.id}
{branchController}
{branch}
{cloud}
{selectedOwnership}
{user}
bind:expanded={commitBoxOpen}
on:action={(e) => {
if (e.detail == 'generate-branch-name') {
generateBranchName();
}
{/if}
</div>
{:else if branch.commits.length == 0}
<div class="new-branch card" data-dnd-ignore>
<div class="new-branch__content">
<div class="new-branch__image">
<ImgThemed
imgSet={{
light: '/images/lane-new-light.webp',
dark: '/images/lane-new-dark.webp'
}}
/>
{/if}
</div>
{:else if branch.commits.length == 0}
<div class="new-branch card" data-dnd-ignore>
<div class="new-branch__content">
<div class="new-branch__image">
<ImgThemed
imgSet={{
light: '/images/lane-new-light.webp',
dark: '/images/lane-new-dark.webp'
}}
/>
</div>
<h2 class="new-branch__title text-base-body-15 text-semibold">
This is a new branch.
</h2>
<p class="new-branch__caption text-base-body-13">
You can drag and drop files or parts of files here.
</p>
</div>
<h2 class="new-branch__title text-base-body-15 text-semibold">This is a new branch.</h2>
<p class="new-branch__caption text-base-body-13">
You can drag and drop files or parts of files here.
</p>
</div>
{:else}
<!-- attention: these markers have custom css at the bottom of thise file -->
<div class="no-changes card" data-dnd-ignore>
<div class="new-branch__content">
<div class="new-branch__image">
<ImgThemed
imgSet={{
light: '/images/lane-no-changes-light.webp',
dark: '/images/lane-no-changes-dark.webp'
}}
/>
</div>
<h2 class="new-branch__caption text-base-body-13">
No uncommitted changes<br />on this branch
</h2>
</div>
{:else}
<!-- attention: these markers have custom css at the bottom of thise file -->
<div class="no-changes card" data-dnd-ignore>
<div class="new-branch__content">
<div class="new-branch__image">
<ImgThemed
imgSet={{
light: '/images/lane-no-changes-light.webp',
dark: '/images/lane-no-changes-dark.webp'
}}
/>
</div>
<h2 class="new-branch__caption text-base-body-13">
No uncommitted changes<br />on this branch
</h2>
</div>
{/if}
</div>
<BranchCommits
{base}
{branch}
{project}
{githubService}
{branchController}
{branchCount}
{readonly}
/>
</div>
{/if}
</div>
</ScrollableContainer>
<BranchCommits
{base}
{branch}
{project}
{githubService}
{branchController}
{branchCount}
{readonly}
/>
<Resizer
viewport={rsViewport}
direction="right"
inside={$selectedFiles.length > 0}
minWidth={320}
on:width={(e) => {
laneWidth = e.detail / (16 * $userSettings.zoom);
lscache.set(laneWidthKey + branch.id, laneWidth, 7 * 1440); // 7 day ttl
$defaultBranchWidthRem = laneWidth;
}}
/>
<Resizer
viewport={rsViewport}
direction="right"
inside={$selectedFiles.length > 0}
minWidth={320}
on:width={(e) => {
laneWidth = e.detail / (16 * $userSettings.zoom);
lscache.set(laneWidthKey + branch.id, laneWidth, 7 * 1440); // 7 day ttl
$defaultBranchWidthRem = laneWidth;
}}
/>
</div>
<slot name="file-view" />
</div>
<style lang="postcss">
.resize-viewport {
.branch-card {
height: 100%;
position: relative;
display: flex;
--target-branch-background: var(--clr-theme-container-pale);
display: flex;
/* flex-direction: column; */
user-select: none;
overflow-x: hidden;
overflow-y: scroll;
/* padding: 8px; */
/* border-radius: var(--radius-l); */
background-color: var(--target-branch-background);
/* remover scrollbar */
&::-webkit-scrollbar {
width: 0px;
background: transparent; /* Chrome/Safari/Webkit */
}
}
.branch-card {
display: flex;
flex-direction: column;
user-select: none;
.target-branch {
--target-branch-background: color-mix(
in srgb,
var(--clr-theme-scale-pop-60) 30%,
var(--clr-theme-container-pale)
);
}
.branch-card__dropzone-wrapper {
@ -286,15 +307,15 @@
}
.branch-card__contents {
position: relative;
display: flex;
flex-direction: column;
padding-top: 20px;
gap: var(--space-4);
padding: var(--space-16) var(--space-8) var(--space-16) var(--space-8);
padding: var(--space-8);
}
.resize-viewport {
position: relative;
.first-child {
/* padding-left: var(--space-16); */
}
.new-branch__content {

View File

@ -148,7 +148,7 @@
.header__wrapper {
z-index: 10;
position: sticky;
top: var(--space-16);
top: var(--space-8);
}
.header {
z-index: 2;
@ -170,7 +170,7 @@
left: 0;
width: 100%;
height: var(--space-20);
background: var(--clr-theme-container-pale);
background: var(--target-branch-background);
/* background-color: red; */
}
.header__info {

View File

@ -49,24 +49,26 @@
{user}
{selectedFiles}
{githubService}
/>
{#if selected}
<FileCard
conflicted={selected.conflicted}
branchId={branch.id}
file={selected}
projectId={project.id}
{projectPath}
{branchController}
{selectedOwnership}
selectable={$commitBoxOpen && !readonly}
on:close={() => {
const selectedId = selected?.id;
selectedFiles.update((fileIds) => fileIds.filter((file) => file.id != selectedId));
}}
/>
{/if}
>
<svelte:fragment slot="file-view">
{#if selected}
<FileCard
conflicted={selected.conflicted}
branchId={branch.id}
file={selected}
projectId={project.id}
{projectPath}
{branchController}
{selectedOwnership}
selectable={$commitBoxOpen && !readonly}
on:close={() => {
const selectedId = selected?.id;
selectedFiles.update((fileIds) => fileIds.filter((file) => file.id != selectedId));
}}
/>
{/if}
</svelte:fragment>
</BranchCard>
</div>
<style lang="postcss">

View File

@ -131,137 +131,138 @@
</div>
{/if}
<ScrollableContainer wide>
<div class="hunks">
{#if file.binary}
Binary content not shown
{:else if file.large}
Diff too large to be shown
{:else}
{#each sections as section}
{@const { added, removed } = computedAddedRemoved(section)}
{#if 'hunk' in section}
<div class="hunk-wrapper">
<div class="indicators text-base-11">
<span class="added">+{added}</span>
<span class="removed">+{removed}</span>
{#if section.hunk.locked}
<div title={section.hunk.lockedTo}>
<Icon name="locked-small" color="warn" />
</div>
{/if}
</div>
<div
tabindex="0"
role="cell"
use:draggable={{
...draggableHunk(branchId, section.hunk),
disabled: readonly || section.hunk.locked
}}
on:dblclick
class="hunk"
class:opacity-60={section.hunk.locked && !isFileLocked}
>
<div class="hunk__inner custom-scrollbar">
<div class="hunk__inner_inner">
{#each section.subSections as subsection, sidx}
{@const hunk = section.hunk}
{#each subsection.lines.slice(0, subsection.expanded ? subsection.lines.length : 0) as line}
<RenderedLine
{line}
{minWidth}
{selectable}
selected={$selectedOwnership.containsHunk(hunk.filePath, hunk.id)}
on:selected={(e) => onHunkSelected(hunk, e.detail)}
sectionType={subsection.sectionType}
filePath={file.path}
on:contextmenu={(e) =>
popupMenu.openByMouse(e, {
hunk,
section: subsection,
lineNumber: line.afterLineNumber
? line.afterLineNumber
: line.beforeLineNumber
})}
/>
{/each}
{#if !subsection.expanded}
<div
role="group"
class="border-color-3 flex w-full"
class:border-t={sidx == section.subSections.length - 1 ||
(sidx > 0 && sidx < section.subSections.length - 1)}
class:border-b={sidx == 0 ||
(sidx > 0 && sidx < section.subSections.length - 1)}
on:contextmenu|preventDefault={(e) =>
popupMenu.openByMouse(e, {
section: section,
hunk
})}
>
<div
class="bg-color-4 text-color-4 hover:text-color-2 border-color-3 border-r text-center"
style:min-width={`calc(${2 * minWidth}rem - 1px)`}
>
<button
class="flex justify-center py-0.5 text-sm"
style:width={`calc(${2 * minWidth}rem - 1px)`}
on:click={() => {
if ('expanded' in subsection) {
subsection.expanded = true;
}
}}
>
{#if sidx == 0}
<IconExpandUp />
{:else if sidx == section.subSections.length - 1}
<IconExpandDown />
{:else}
<IconExpandUpDown />
{/if}
</button>
</div>
<div class="bg-color-4 flex-grow" />
</div>
{/if}
<div class="hunks">
{#if file.binary}
Binary content not shown
{:else if file.large}
Diff too large to be shown
{:else}
{#each sections as section}
{@const { added, removed } = computedAddedRemoved(section)}
{#if 'hunk' in section}
<div class="hunk-wrapper">
<div class="indicators text-base-11">
<span class="added">+{added}</span>
<span class="removed">+{removed}</span>
{#if section.hunk.locked}
<div title={section.hunk.lockedTo}>
<Icon name="locked-small" color="warn" />
</div>
{/if}
</div>
<div
tabindex="0"
role="cell"
use:draggable={{
...draggableHunk(branchId, section.hunk),
disabled: readonly || section.hunk.locked
}}
on:dblclick
class="hunk"
class:opacity-60={section.hunk.locked && !isFileLocked}
>
<div class="hunk__inner custom-scrollbar">
<div class="hunk__inner_inner">
{#each section.subSections as subsection, sidx}
{@const hunk = section.hunk}
{#each subsection.lines.slice(0, subsection.expanded ? subsection.lines.length : 0) as line}
<RenderedLine
{line}
{minWidth}
{selectable}
selected={$selectedOwnership.containsHunk(hunk.filePath, hunk.id)}
on:selected={(e) => onHunkSelected(hunk, e.detail)}
sectionType={subsection.sectionType}
filePath={file.path}
on:contextmenu={(e) =>
popupMenu.openByMouse(e, {
hunk,
section: subsection,
lineNumber: line.afterLineNumber
? line.afterLineNumber
: line.beforeLineNumber
})}
/>
{/each}
</div>
{#if !subsection.expanded}
<div
role="group"
class="border-color-3 flex w-full"
class:border-t={sidx == section.subSections.length - 1 ||
(sidx > 0 && sidx < section.subSections.length - 1)}
class:border-b={sidx == 0 ||
(sidx > 0 && sidx < section.subSections.length - 1)}
on:contextmenu|preventDefault={(e) =>
popupMenu.openByMouse(e, {
section: section,
hunk
})}
>
<div
class="bg-color-4 text-color-4 hover:text-color-2 border-color-3 border-r text-center"
style:min-width={`calc(${2 * minWidth}rem - 1px)`}
>
<button
class="flex justify-center py-0.5 text-sm"
style:width={`calc(${2 * minWidth}rem - 1px)`}
on:click={() => {
if ('expanded' in subsection) {
subsection.expanded = true;
}
}}
>
{#if sidx == 0}
<IconExpandUp />
{:else if sidx == section.subSections.length - 1}
<IconExpandDown />
{:else}
<IconExpandUpDown />
{/if}
</button>
</div>
<div class="bg-color-4 flex-grow" />
</div>
{/if}
{/each}
</div>
</div>
</div>
{/if}
{/each}
{/if}
</div>
</ScrollableContainer>
</div>
{/if}
{/each}
{/if}
</div>
<Resizer
viewport={rsViewport}
direction="right"
inside
minWidth={240}
on:width={(e) => {
fileWidth = e.detail / (16 * $userSettings.zoom);
lscache.set(fileWidthKey + file.id, fileWidth, 7 * 1440); // 7 day ttl
$defaultFileWidthRem = fileWidth;
}}
/>
</div>
<Resizer
viewport={rsViewport}
direction="right"
inside
minWidth={240}
on:width={(e) => {
fileWidth = e.detail / (16 * $userSettings.zoom);
lscache.set(fileWidthKey + file.id, fileWidth, 7 * 1440); // 7 day ttl
$defaultFileWidthRem = fileWidth;
}}
/>
</div>
<style lang="postcss">
.resize-viewport {
position: relative;
position: sticky;
top: 0;
display: flex;
height: 100%;
align-items: self-start;
overflow: hidden;
padding: var(--space-16) var(--space-6);
padding: var(--space-8) var(--space-8) var(--space-8) 0;
margin-left: calc(var(--space-4) * -1);
}
.file-card {
background: var(--clr-theme-container-light);
overflow: hidden;
display: flex;
flex-direction: column;
width: 100%;
max-height: 100%;
}
.hunks {