mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-12-26 02:51:57 +03:00
140 lines
3.8 KiB
Svelte
140 lines
3.8 KiB
Svelte
<script lang="ts">
|
|
import BranchFilesHeader from './BranchFilesHeader.svelte';
|
|
import FileListItem from './FileListItem.svelte';
|
|
import LazyloadContainer from '$lib/shared/LazyloadContainer.svelte';
|
|
import TextBox from '$lib/shared/TextBox.svelte';
|
|
import { copyToClipboard } from '$lib/utils/clipboard';
|
|
import { getContext } from '$lib/utils/context';
|
|
import { selectFilesInList } from '$lib/utils/selectFilesInList';
|
|
import { maybeMoveSelection } from '$lib/utils/selection';
|
|
import { getCommitStore } from '$lib/vbranches/contexts';
|
|
import { FileIdSelection, stringifyFileKey } from '$lib/vbranches/fileIdSelection';
|
|
import { sortLikeFileTree } from '$lib/vbranches/filetree';
|
|
import Button from '@gitbutler/ui/inputs/Button.svelte';
|
|
import type { AnyFile } from '$lib/vbranches/types';
|
|
|
|
export let files: AnyFile[];
|
|
export let isUnapplied = false;
|
|
export let showCheckboxes = false;
|
|
export let allowMultiple = false;
|
|
export let readonly = false;
|
|
|
|
const fileIdSelection = getContext(FileIdSelection);
|
|
const commit = getCommitStore();
|
|
|
|
function chunk<T>(arr: T[], size: number) {
|
|
return Array.from({ length: Math.ceil(arr.length / size) }, (v, i) =>
|
|
arr.slice(i * size, i * size + size)
|
|
);
|
|
}
|
|
|
|
let chunkedFiles: AnyFile[][] = [];
|
|
let displayedFiles: AnyFile[] = [];
|
|
let currentDisplayIndex = 0;
|
|
|
|
function setFiles(files: AnyFile[]) {
|
|
chunkedFiles = chunk(sortLikeFileTree(files), 100);
|
|
displayedFiles = chunkedFiles[0] || [];
|
|
currentDisplayIndex = 0;
|
|
}
|
|
|
|
// Make sure we display when the file list is reset
|
|
$: setFiles(files);
|
|
|
|
export function loadMore() {
|
|
if (currentDisplayIndex + 1 >= chunkedFiles.length) return;
|
|
|
|
currentDisplayIndex += 1;
|
|
displayedFiles = [...displayedFiles, ...chunkedFiles[currentDisplayIndex]];
|
|
}
|
|
let mergeDiffCommand = 'git diff-tree --cc ';
|
|
</script>
|
|
|
|
{#if !$commit?.isMergeCommit()}
|
|
<BranchFilesHeader title="Changed files" {files} {showCheckboxes} />
|
|
{:else}
|
|
<div class="merge-commit-error">
|
|
<p class="info">
|
|
Displaying diffs for merge commits is currently not supported. Please view the merge commit in
|
|
GitHub, or run the following command in your project directory:
|
|
</p>
|
|
<div class="command">
|
|
<TextBox value={mergeDiffCommand + $commit.id.slice(0, 7)} wide readonly />
|
|
<Button
|
|
icon="copy"
|
|
style="ghost"
|
|
outline
|
|
on:mousedown={() => copyToClipboard(mergeDiffCommand + $commit.id.slice(0, 7))}
|
|
/>
|
|
</div>
|
|
</div>
|
|
{/if}
|
|
|
|
{#if displayedFiles.length > 0}
|
|
<!-- Maximum amount for initial render is 100 files
|
|
`minTriggerCount` set to 80 in order to start the loading a bit earlier. -->
|
|
<LazyloadContainer
|
|
minTriggerCount={80}
|
|
ontrigger={() => {
|
|
console.log('loading more files...');
|
|
loadMore();
|
|
}}
|
|
role="listbox"
|
|
>
|
|
{#each displayedFiles as file (file.id)}
|
|
<FileListItem
|
|
{file}
|
|
{readonly}
|
|
{isUnapplied}
|
|
showCheckbox={showCheckboxes}
|
|
selected={$fileIdSelection.includes(stringifyFileKey(file.id, $commit?.id))}
|
|
on:click={(e) => {
|
|
selectFilesInList(e, file, fileIdSelection, displayedFiles, allowMultiple, $commit);
|
|
}}
|
|
on:keydown={(e) => {
|
|
e.preventDefault();
|
|
maybeMoveSelection(
|
|
{
|
|
allowMultiple,
|
|
shiftKey: e.shiftKey,
|
|
key: e.key,
|
|
targetElement: e.currentTarget as HTMLElement,
|
|
file,
|
|
files: displayedFiles,
|
|
selectedFileIds: $fileIdSelection,
|
|
fileIdSelection
|
|
}
|
|
);
|
|
|
|
if (e.key === 'Escape') {
|
|
fileIdSelection.clear();
|
|
|
|
const targetEl = e.target as HTMLElement;
|
|
targetEl.blur();
|
|
}
|
|
}}
|
|
/>
|
|
{/each}
|
|
</LazyloadContainer>
|
|
{/if}
|
|
|
|
<style lang="postcss">
|
|
.merge-commit-error {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 14px;
|
|
padding: 14px;
|
|
|
|
& .info {
|
|
color: var(--clr-text-2);
|
|
}
|
|
|
|
& .command {
|
|
display: flex;
|
|
gap: 8px;
|
|
align-items: center;
|
|
width: 100%;
|
|
}
|
|
}
|
|
</style>
|