GLORY BE TO THE TRIPPLE EQUAL

This commit is contained in:
Caleb Owens 2024-06-04 17:35:48 +02:00
parent 7978c67e6a
commit 4ef6b30255
No known key found for this signature in database
93 changed files with 381 additions and 377 deletions

View File

@ -31,6 +31,7 @@ module.exports = {
node: true
},
rules: {
eqeqeq: ['error', 'always'],
'import/no-cycle': 'error',
'import/order': [
'error',

View File

@ -67,8 +67,8 @@ function isOllamaChatResponse(response: unknown): response is OllamaChatResponse
return (
isNonEmptyObject(response.message) &&
typeof response.message.role == 'string' &&
typeof response.message.content == 'string'
typeof response.message.role === 'string' &&
typeof response.message.content === 'string'
);
}
@ -98,7 +98,7 @@ export class OllamaClient implements AIClient {
*/
private formatPrompt(prompt: Prompt) {
const withFormattedResponses = prompt.map((promptMessage) => {
if (promptMessage.role == MessageRole.Assistant) {
if (promptMessage.role === MessageRole.Assistant) {
return {
role: MessageRole.Assistant,
content: JSON.stringify({ result: promptMessage.content })

View File

@ -53,7 +53,7 @@ export class PromptService {
}
findPrompt(prompts: UserPrompt[], promptId: string) {
const prompt = prompts.find((userPrompt) => userPrompt.id == promptId)?.prompt;
const prompt = prompts.find((userPrompt) => userPrompt.id === promptId)?.prompt;
if (!prompt) return;
if (this.promptMissingContent(prompt)) return;
@ -62,14 +62,14 @@ export class PromptService {
}
promptEquals(prompt1: Prompt, prompt2: Prompt) {
if (prompt1.length != prompt2.length) return false;
if (prompt1.length !== prompt2.length) return false;
for (const indexPromptMessage of prompt1.entries()) {
const [index, promptMessage] = indexPromptMessage;
if (
promptMessage.role != prompt2[index].role ||
promptMessage.content != prompt2[index].content
promptMessage.role !== prompt2[index].role ||
promptMessage.content !== prompt2[index].content
) {
return false;
}
@ -90,7 +90,7 @@ export class PromptService {
return {
id: crypto.randomUUID(),
name: 'My Prompt',
prompt: type == 'branches' ? SHORT_DEFAULT_BRANCH_TEMPLATE : SHORT_DEFAULT_COMMIT_TEMPLATE
prompt: type === 'branches' ? SHORT_DEFAULT_BRANCH_TEMPLATE : SHORT_DEFAULT_COMMIT_TEMPLATE
};
}
}

View File

@ -160,9 +160,9 @@ export class AIService {
const anthropicKeyOption = await this.getAnthropicKeyOption();
const openAIActiveAndUsingButlerAPI =
modelKind == ModelKind.OpenAI && openAIKeyOption == KeyOption.ButlerAPI;
modelKind === ModelKind.OpenAI && openAIKeyOption === KeyOption.ButlerAPI;
const anthropicActiveAndUsingButlerAPI =
modelKind == ModelKind.Anthropic && anthropicKeyOption == KeyOption.ButlerAPI;
modelKind === ModelKind.Anthropic && anthropicKeyOption === KeyOption.ButlerAPI;
return openAIActiveAndUsingButlerAPI || anthropicActiveAndUsingButlerAPI;
}
@ -176,10 +176,10 @@ export class AIService {
if (await this.usingGitButlerAPI()) return !!userToken;
const openAIActiveAndKeyProvided = modelKind == ModelKind.OpenAI && !!openAIKey;
const anthropicActiveAndKeyProvided = modelKind == ModelKind.Anthropic && !!anthropicKey;
const openAIActiveAndKeyProvided = modelKind === ModelKind.OpenAI && !!openAIKey;
const anthropicActiveAndKeyProvided = modelKind === ModelKind.Anthropic && !!anthropicKey;
const ollamaActiveAndEndpointProvided =
modelKind == ModelKind.Ollama && !!ollamaEndpoint && !!ollamaModelName;
modelKind === ModelKind.Ollama && !!ollamaEndpoint && !!ollamaModelName;
return (
openAIActiveAndKeyProvided || anthropicActiveAndKeyProvided || ollamaActiveAndEndpointProvided
@ -200,13 +200,13 @@ export class AIService {
return new ButlerAIClient(this.cloud, userToken, modelKind);
}
if (modelKind == ModelKind.Ollama) {
if (modelKind === ModelKind.Ollama) {
const ollamaEndpoint = await this.getOllamaEndpoint();
const ollamaModelName = await this.getOllamaModelName();
return new OllamaClient(ollamaEndpoint, ollamaModelName);
}
if (modelKind == ModelKind.OpenAI) {
if (modelKind === ModelKind.OpenAI) {
const openAIModelName = await this.getOpenAIModleName();
const openAIKey = await this.getOpenAIKey();
@ -221,7 +221,7 @@ export class AIService {
return new OpenAIClient(openAIModelName, openAI);
}
if (modelKind == ModelKind.Anthropic) {
if (modelKind === ModelKind.Anthropic) {
const anthropicModelName = await this.getAnthropicModelName();
const anthropicKey = await this.getAnthropicKey();
@ -250,7 +250,7 @@ export class AIService {
const defaultedCommitTemplate = commitTemplate || aiClient.defaultCommitTemplate;
const prompt = defaultedCommitTemplate.map((promptMessage) => {
if (promptMessage.role != MessageRole.User) {
if (promptMessage.role !== MessageRole.User) {
return promptMessage;
}
@ -289,7 +289,7 @@ export class AIService {
const diffLengthLimit = await this.getDiffLengthLimitConsideringAPI();
const defaultedBranchTemplate = branchTemplate || aiClient.defaultBranchTemplate;
const prompt = defaultedBranchTemplate.map((promptMessage) => {
if (promptMessage.role != MessageRole.User) {
if (promptMessage.role !== MessageRole.User) {
return promptMessage;
}

View File

@ -64,7 +64,7 @@ export class UpdaterService {
if (update?.shouldUpdate) return update.manifest;
}),
// We don't need the stream to emit if the result is the same version
distinctUntilChanged((prev, curr) => prev?.version == curr?.version),
distinctUntilChanged((prev, curr) => prev?.version === curr?.version),
// Hide offline/timeout errors since no app ever notifies you about this
catchError((err) => {
if (!isOffline(err) && !isTimeoutError(err)) {
@ -106,11 +106,11 @@ export class UpdaterService {
}
function isOffline(err: any): boolean {
return typeof err == 'string' && err.includes('Could not fetch a valid release');
return typeof err === 'string' && err.includes('Could not fetch a valid release');
}
function isTimeoutError(err: any): boolean {
return err?.name == 'TimeoutError';
return err?.name === 'TimeoutError';
}
function showErrorToast(err: any) {

View File

@ -106,7 +106,7 @@ function mergeBranchesAndPrs(
if (vbranches) {
contributions.push(
...vbranches.map((vb) => {
const pr = pullRequests?.find((pr) => pr.sha == vb.head);
const pr = pullRequests?.find((pr) => pr.sha === vb.head);
return new CombinedBranch({ vbranch: vb, remoteBranch: vb.upstream, pr });
})
);
@ -116,9 +116,9 @@ function mergeBranchesAndPrs(
if (remoteBranches) {
contributions.push(
...remoteBranches
.filter((rb) => !contributions.some((cb) => rb.sha == cb.upstreamSha))
.filter((rb) => !contributions.some((cb) => rb.sha === cb.upstreamSha))
.map((rb) => {
const pr = pullRequests?.find((pr) => pr.sha == rb.sha);
const pr = pullRequests?.find((pr) => pr.sha === rb.sha);
return new CombinedBranch({ remoteBranch: rb, pr });
})
);
@ -128,7 +128,7 @@ function mergeBranchesAndPrs(
if (pullRequests) {
contributions.push(
...pullRequests
.filter((pr) => !contributions.some((cb) => pr.sha == cb.upstreamSha))
.filter((pr) => !contributions.some((cb) => pr.sha === cb.upstreamSha))
.map((pr) => {
return new CombinedBranch({ pr });
})

View File

@ -51,7 +51,7 @@ export class CombinedBranch {
}
get author(): Author | undefined {
if (this.authors.length == 0) {
if (this.authors.length === 0) {
return undefined;
}
return this.authors[0];
@ -65,7 +65,7 @@ export class CombinedBranch {
get color(): 'neutral' | 'success' | 'pop' | 'purple' | undefined {
if (this.pr?.mergedAt) return 'purple'; // merged PR
if (this.pr) return 'success'; // open PR
if (this.vbranch && this.vbranch.active == false) return 'pop'; // stashed virtual branches
if (this.vbranch && this.vbranch.active === false) return 'pop'; // stashed virtual branches
// if (this.remoteBranch?.isMergeable) return 'success'; // remote branches
return 'neutral';
}

View File

@ -12,7 +12,7 @@
let prompts: Prompts;
if (promptUse == 'commits') {
if (promptUse === 'commits') {
prompts = promptService.commitPrompts;
} else {
prompts = promptService.branchPrompts;
@ -28,7 +28,7 @@
}
function deletePrompt(targetPrompt: UserPrompt) {
const filteredPrompts = get(prompts.userPrompts).filter((prompt) => prompt != targetPrompt);
const filteredPrompts = get(prompts.userPrompts).filter((prompt) => prompt !== targetPrompt);
prompts.userPrompts.set(filteredPrompts);
}
</script>
@ -36,7 +36,7 @@
{#if prompts && $userPrompts}
<div class="prompt-item__title">
<h3 class="text-base-15 text-bold">
{promptUse == 'commits' ? 'Commit Message' : 'Branch Name'}
{promptUse === 'commits' ? 'Commit Message' : 'Branch Name'}
</h3>
<Button kind="solid" style="ghost" icon="plus-small" on:click={createNewPrompt}
>New prompt</Button

View File

@ -16,7 +16,7 @@
let initialName = promptName;
// Ensure the prompt messages have a default user prompt
if (promptMessages.length == 0) {
if (promptMessages.length === 0) {
promptMessages = [
...promptMessages,
{
@ -60,7 +60,7 @@
return;
}
if (promptName.trim() == '') {
if (promptName.trim() === '') {
promptName = initialName;
}
@ -75,7 +75,7 @@
editing = false;
}
$: isInEditing = displayMode == 'writable' && editing;
$: isInEditing = displayMode === 'writable' && editing;
function toggleExpand() {
if (isInEditing) return;
@ -87,7 +87,7 @@
let errors = [] as number[];
promptMessages.forEach((message, index) => {
if (message.content.trim() == '') {
if (message.content.trim() === '') {
errors.push(index);
}
});
@ -117,28 +117,28 @@
</div>
{#if expanded}
<div class="content" class:default-mode={prompt.id == 'default'} class:editing={isInEditing}>
<div class="content" class:default-mode={prompt.id === 'default'} class:editing={isInEditing}>
{#each promptMessages as promptMessage, index}
<DialogBubble
bind:promptMessage
editing={isInEditing}
isLast={index + 1 == promptMessages.length || promptMessages.length == 1}
disableRemove={promptMessages.length == 1}
isLast={index + 1 === promptMessages.length || promptMessages.length === 1}
disableRemove={promptMessages.length === 1}
on:addExample={addExample}
on:removeLastExample={removeLastExample}
on:input={() => {
errorMessages = errorMessages.filter((errorIndex) => errorIndex != index);
errorMessages = errorMessages.filter((errorIndex) => errorIndex !== index);
}}
isError={errorMessages.includes(index)}
/>
{#if index % 2 == 0}
{#if index % 2 === 0}
<hr class="sections-divider" />
{/if}
{/each}
</div>
{#if displayMode == 'writable'}
{#if displayMode === 'writable'}
<div class="actions">
{#if editing}
<Button kind="solid" style="ghost" on:click={() => cancel()}>Cancel</Button>

View File

@ -40,12 +40,12 @@
<div
class="bubble-wrap"
class:editing
class:bubble-wrap_user={promptMessage.role == MessageRole.User}
class:bubble-wrap_assistant={promptMessage.role == MessageRole.Assistant}
class:bubble-wrap_user={promptMessage.role === MessageRole.User}
class:bubble-wrap_assistant={promptMessage.role === MessageRole.Assistant}
>
<div class="bubble">
<div class="bubble__header text-base-13 text-bold">
{#if promptMessage.role == MessageRole.User}
{#if promptMessage.role === MessageRole.User}
<Icon name="profile" />
<span>User</span>
{:else}

View File

@ -15,7 +15,7 @@
let prompts: Prompts;
let selectedPromptId: Persisted<string | undefined>;
if (promptUse == 'commits') {
if (promptUse === 'commits') {
prompts = promptService.commitPrompts;
selectedPromptId = promptService.selectedCommitPromptId(project.id);
} else {
@ -48,9 +48,9 @@
bind:selectedItemId={$selectedPromptId}
itemId="id"
labelId="name"
disabled={allPrompts.length == 1}
disabled={allPrompts.length === 1}
wide={true}
label={promptUse == 'commits' ? 'Commit Message' : 'Branch Name'}
label={promptUse === 'commits' ? 'Commit Message' : 'Branch Name'}
>
<SelectItem slot="template" let:item let:selected {selected}>
{item.name}

View File

@ -16,14 +16,14 @@
let dismissed = false;
</script>
{#if $update$?.version && $update$.status != 'UPTODATE' && !dismissed}
<div class="update-banner" class:busy={$update$?.status == 'PENDING'}>
{#if $update$?.version && $update$.status !== 'UPTODATE' && !dismissed}
<div class="update-banner" class:busy={$update$?.status === 'PENDING'}>
<div class="floating-button">
<Button icon="cross-small" style="ghost" on:click={() => (dismissed = true)} />
</div>
<div class="img">
<div class="circle-img">
{#if $update$?.status != 'DONE'}
{#if $update$?.status !== 'DONE'}
<svg
class="arrow-img"
width="12"
@ -92,13 +92,13 @@
<h4 class="text-base-13 label">
{#if !$update$.status}
New version available
{:else if $update$.status == 'PENDING'}
{:else if $update$.status === 'PENDING'}
Downloading update...
{:else if $update$.status == 'DOWNLOADED'}
{:else if $update$.status === 'DOWNLOADED'}
Installing update...
{:else if $update$.status == 'DONE'}
{:else if $update$.status === 'DONE'}
Install complete
{:else if $update$.status == 'ERROR'}
{:else if $update$.status === 'ERROR'}
Error occurred...
{/if}
</h4>
@ -136,7 +136,7 @@
Download {$update$.version}
</Button>
</div>
{:else if $update$.status == 'DONE'}
{:else if $update$.status === 'DONE'}
<div class="cta-btn" transition:fade={{ duration: 100 }}>
<Button style="pop" kind="solid" wide on:click={() => updaterService.relaunchApp()}
>Restart</Button

View File

@ -16,8 +16,8 @@
<div
class="shadow-marker"
class:first={sectionFirst}
class:upstream={status == 'upstream'}
class:integrated={status == 'integrated'}
class:upstream={status === 'upstream'}
class:integrated={status === 'integrated'}
class:shadow-lane={shadowLane}
use:tooltip={help}
/>
@ -29,10 +29,10 @@
width="100"
height="100"
class:first={sectionFirst}
class:local={status == 'local'}
class:remote={status == 'remote'}
class:upstream={status == 'upstream'}
class:integrated={status == 'integrated'}
class:local={status === 'local'}
class:remote={status === 'remote'}
class:upstream={status === 'upstream'}
class:integrated={status === 'integrated'}
class:remote-lane={remoteLane}
class:shadow-lane={shadowLane}
use:tooltip={help}

View File

@ -22,7 +22,7 @@
let updateTargetModal: Modal;
let mergeUpstreamWarningDismissedCheckbox = false;
$: multiple = base ? base.upstreamCommits.length > 1 || base.upstreamCommits.length == 0 : false;
$: multiple = base ? base.upstreamCommits.length > 1 || base.upstreamCommits.length === 0 : false;
async function updateBaseBranch() {
let infoText = await branchController.updateBaseBranch();
@ -58,8 +58,8 @@
{#each base.upstreamCommits as commit, index}
<CommitCard
{commit}
first={index == 0}
last={index == base.upstreamCommits.length - 1}
first={index === 0}
last={index === base.upstreamCommits.length - 1}
isUnapplied={true}
commitUrl={base.commitUrl(commit.id)}
type="upstream"
@ -79,8 +79,8 @@
{#each base.recentCommits as commit, index}
<CommitCard
{commit}
first={index == 0}
last={index == base.recentCommits.length - 1}
first={index === 0}
last={index === base.recentCommits.length - 1}
isUnapplied={true}
commitUrl={base.commitUrl(commit.id)}
type="remote"

View File

@ -100,7 +100,7 @@
{#if $activeBranches && targetChangeDisabled}
<InfoMessage filled outlined={false} icon="info">
<svelte:fragment slot="content">
You have {$activeBranches.length == 1
You have {$activeBranches.length === 1
? '1 active branch'
: `${$activeBranches.length} active branches`} in your workspace. Please clear the workspace
before switching the base branch.
@ -114,8 +114,8 @@
on:click={onSetBaseBranchClick}
id="set-base-branch"
loading={isSwitching}
disabled={(selectedBranch.name == $baseBranch.branchName &&
selectedRemote.name == $baseBranch.actualPushRemoteName()) ||
disabled={(selectedBranch.name === $baseBranch.branchName &&
selectedRemote.name === $baseBranch.actualPushRemoteName()) ||
targetChangeDisabled}
>
{isSwitching ? 'Switching branches...' : 'Update configuration'}

View File

@ -60,7 +60,7 @@
}
}
const idx = children.indexOf(dragged);
if (idx != dropPosition) {
if (idx !== dropPosition) {
idx >= dropPosition
? children[dropPosition].before(dragged)
: children[dropPosition].after(dragged);
@ -70,7 +70,7 @@
if (!dragged) return;
if (!$activeBranches) return;
e.preventDefault();
if (priorPosition != dropPosition) {
if (priorPosition !== dropPosition) {
const el = $activeBranches.splice(priorPosition, 1);
$activeBranches.splice(dropPosition, 0, ...el);
$activeBranches.forEach((branch, i) => {
@ -88,7 +88,7 @@
draggable="true"
on:mousedown={(e) => (dragHandle = e.target)}
on:dragstart={(e) => {
if (dragHandle.dataset.dragHandle == undefined) {
if (dragHandle.dataset.dragHandle === undefined) {
// We rely on elements with id `drag-handle` to initiate this drag
e.preventDefault();
e.stopPropagation();
@ -112,11 +112,11 @@
</div>
{/each}
{#if $activeBranches.length == 0}
{#if $activeBranches.length === 0}
<div
data-tauri-drag-region
class="empty-board__wrapper"
class:transition-fly={$activeBranches.length == 0}
class:transition-fly={$activeBranches.length === 0}
>
<div class="empty-board">
<div class="empty-board__content">

View File

@ -108,14 +108,14 @@
});
function acceptMoveCommit(data: any) {
return data instanceof DraggableCommit && data.branchId != branch.id && data.isHeadCommit;
return data instanceof DraggableCommit && data.branchId !== branch.id && data.isHeadCommit;
}
function onCommitDrop(data: DraggableCommit) {
branchController.moveCommit(branch.id, data.commit.id);
}
function acceptCherrypick(data: any) {
return data instanceof DraggableRemoteCommit && data.branchId == branch.id;
return data instanceof DraggableRemoteCommit && data.branchId === branch.id;
}
function onCherrypicked(data: DraggableRemoteCommit) {
@ -123,9 +123,9 @@
}
function acceptBranchDrop(data: any) {
if (data instanceof DraggableHunk && data.branchId != branch.id) {
if (data instanceof DraggableHunk && data.branchId !== branch.id) {
return !data.hunk.locked;
} else if (data instanceof DraggableFile && data.branchId && data.branchId != branch.id) {
} else if (data instanceof DraggableFile && data.branchId && data.branchId !== branch.id) {
return !data.files.some((f) => f.locked);
} else {
return false;
@ -162,7 +162,7 @@
uncommittedChanges={branch.files.length}
bind:isLaneCollapsed
on:action={(e) => {
if (e.detail == 'generate-branch-name') {
if (e.detail === 'generate-branch-name') {
generateBranchName();
}
}}
@ -193,10 +193,10 @@
{isUnapplied}
bind:isLaneCollapsed
on:action={(e) => {
if (e.detail == 'generate-branch-name') {
if (e.detail === 'generate-branch-name') {
generateBranchName();
}
if (e.detail == 'collapse') {
if (e.detail === 'collapse') {
$isLaneCollapsed = true;
}
}}
@ -265,14 +265,14 @@
projectId={project.id}
expanded={commitBoxOpen}
on:action={(e) => {
if (e.detail == 'generate-branch-name') {
if (e.detail === 'generate-branch-name') {
generateBranchName();
}
}}
/>
{/if}
</div>
{:else if branch.commits.length == 0}
{:else if branch.commits.length === 0}
<div class="new-branch">
<EmptyStatePlaceholder image={laneNewSvg} width="11rem">
<svelte:fragment slot="title">This is a new branch</svelte:fragment>
@ -303,7 +303,7 @@
direction="right"
minWidth={380}
sticky
defaultLineColor={$fileIdSelection.length == 1 ? 'transparent' : 'var(--clr-border-2)'}
defaultLineColor={$fileIdSelection.length === 1 ? 'transparent' : 'var(--clr-border-2)'}
on:width={(e) => {
laneWidth = e.detail / (16 * $userSettings.zoom);
lscache.set(laneWidthKey + branch.id, laneWidth, 7 * 1440); // 7 day ttl

View File

@ -31,7 +31,7 @@
role="listbox"
tabindex="-1"
on:keydown={(e) => {
if (e.key == 'Escape') {
if (e.key === 'Escape') {
unselectAllFiles();
}
}}

View File

@ -31,7 +31,7 @@
for (let i = 1; i < files.length; i++) {
file = files[i];
const contained = selectedOwnership.contains(file.id, ...file.hunkIds);
if (contained != prev) {
if (contained !== prev) {
return true;
}
}

View File

@ -27,7 +27,7 @@
$localCommits.length > 0 || $remoteCommits.length > 0 || $unknownCommits.length > 0;
let isLoading: boolean;
$: isPushed = $localCommits.length == 0 && $unknownCommits.length == 0;
$: isPushed = $localCommits.length === 0 && $unknownCommits.length === 0;
</script>
{#if !isUnapplied && hasCommits}
@ -42,11 +42,11 @@
{isLoading}
on:trigger={async (e) => {
try {
if (e.detail.action == BranchAction.Push) {
if (e.detail.action === BranchAction.Push) {
isLoading = true;
await branchController.pushBranch($branch.id, $branch.requiresForce);
isLoading = false;
} else if (e.detail.action == BranchAction.Rebase) {
} else if (e.detail.action === BranchAction.Rebase) {
isLoading = true;
await branchController.mergeUpstream($branch.id);
isLoading = false;

View File

@ -41,7 +41,7 @@
let isTargetBranchAnimated = false;
function handleBranchNameChange(title: string) {
if (title == '') return;
if (title === '') return;
branchController.updateBranchName(branch.id, title);
}
@ -120,7 +120,7 @@
help="Uncommitted changes"
>
{uncommittedChanges}
{uncommittedChanges == 1 ? 'change' : 'changes'}
{uncommittedChanges === 1 ? 'change' : 'changes'}
</Button>
{/if}
</div>
@ -264,7 +264,7 @@
<div class="header__buttons">
{#if !hasPullRequest}
<PullRequestButton
on:click={async (e) => await createPr({ draft: e.detail.action == 'draft' })}
on:click={async (e) => await createPr({ draft: e.detail.action === 'draft' })}
loading={isLoading}
/>
{/if}

View File

@ -16,7 +16,7 @@
</script>
<div class="branch-icon {getIconColor(name)}" use:tooltip={help}>
{#if name == 'virtual-branch'}
{#if name === 'virtual-branch'}
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.75 8V4H4.25V8H5.75Z" />
<path
@ -24,14 +24,14 @@
/>
</svg>
{/if}
{#if name == 'remote-branch'}
{#if name === 'remote-branch'}
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M5.75 9.99973V4H4.25V16H5.75V13C5.75 11.7574 6.75736 10.75 8 10.75C10.0711 10.75 11.75 9.07107 11.75 7V4H10.25V7C10.25 8.24264 9.24264 9.25 8 9.25C7.1558 9.25 6.37675 9.52896 5.75 9.99973Z"
/>
</svg>
{/if}
{#if name == 'pr'}
{#if name === 'pr'}
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M3 5L8 2V4.25H10C11.5188 4.25 12.75 5.48122 12.75 7V16H11.25V7C11.25 6.30964 10.6904 5.75 10 5.75H8V8L3 5Z"
@ -39,7 +39,7 @@
<path d="M4.25 9L4.25 16H5.75L5.75 9H4.25Z" />
</svg>
{/if}
{#if name == 'pr-draft'}
{#if name === 'pr-draft'}
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M11.75 7.88555C12.7643 7.56698 13.5 6.61941 13.5 5.5C13.5 4.11929 12.3807 3 11 3C9.61929 3 8.5 4.11929 8.5 5.5C8.5 6.61941 9.23572 7.56698 10.25 7.88555V9H11.75V7.88555Z"
@ -49,7 +49,7 @@
<path d="M10.25 16V15H11.75V16H10.25Z" />
</svg>
{/if}
{#if name == 'pr-closed'}
{#if name === 'pr-closed'}
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M9.99999 4.93934L12.4697 2.46967L13.5303 3.53033L11.0607 6L13.5303 8.46967L12.4697 9.53033L9.99999 7.06066L7.53033 9.53033L6.46967 8.46967L8.93933 6L6.46967 3.53033L7.53033 2.46967L9.99999 4.93934Z"

View File

@ -36,13 +36,13 @@
inputEl.focus();
}}
on:blur={() => {
if (name == '') name = initialName;
if (name === '') name = initialName;
}}
on:focus={() => {
initialName = name;
}}
on:keydown={(e) => {
if (e.key == 'Enter' || e.key == 'Escape') {
if (e.key === 'Enter' || e.key === 'Escape') {
inputEl.blur();
}
}}

View File

@ -76,8 +76,8 @@
on:click={async () => {
if (
branch.name.toLowerCase().includes('virtual branch') &&
commits.length == 0 &&
branch.files?.length == 0
commits.length === 0 &&
branch.files?.length === 0
) {
await branchController.deleteBranch(branch.id);
} else {
@ -95,7 +95,7 @@
}}
disabled={isUnapplied ||
!($aiGenEnabled && aiConfigurationValid) ||
branch.files?.length == 0 ||
branch.files?.length === 0 ||
!branch.active}
/>
</ContextMenuSection>

View File

@ -83,7 +83,7 @@
}
function filterByText(branches: CombinedBranch[], search: string | undefined) {
if (search == undefined) return branches;
if (search === undefined) return branches;
return branches.filter((b) => searchMatchesAnIdentifier(search, b.searchableIdentifiers));
}
@ -128,7 +128,7 @@
bind:viewport
showBorderWhenScrolled
on:dragging={(e) => dispatch('scrollbarDragging', e.detail)}
fillViewport={$filteredBranches$.length == 0}
fillViewport={$filteredBranches$.length === 0}
>
<div class="scroll-container">
<TextBox icon="search" placeholder="Search" on:input={(e) => textFilter$.next(e.detail)} />

View File

@ -56,8 +56,8 @@
{#if SLOTS}
<span
class="label text-semibold"
class:text-base-12={size == 'button' || size == 'cta'}
class:text-base-11={size == 'tag'}
class:text-base-12={size === 'button' || size === 'cta'}
class:text-base-11={size === 'tag'}
>
<slot />
</span>

View File

@ -63,7 +63,7 @@
}
function onKeyup(e: KeyboardEvent) {
if (e.key == 'Enter' || e.key == ' ') {
if (e.key === 'Enter' || e.key === ' ') {
toggleFiles();
}
}
@ -140,10 +140,10 @@
class="accent-border-line"
class:is-first={first}
class:is-last={last}
class:local={type == 'local'}
class:remote={type == 'remote'}
class:upstream={type == 'upstream'}
class:integrated={type == 'integrated'}
class:local={type === 'local'}
class:remote={type === 'remote'}
class:upstream={type === 'upstream'}
class:integrated={type === 'integrated'}
/>
<div class="commit__content">
@ -157,13 +157,13 @@
>
{#if first}
<div class="commit__type text-semibold text-base-12">
{#if type == 'upstream'}
{#if type === 'upstream'}
Remote <Icon name="remote" />
{:else if type == 'local'}
{:else if type === 'local'}
Local <Icon name="local" />
{:else if type == 'remote'}
{:else if type === 'remote'}
Local and remote
{:else if type == 'integrated'}
{:else if type === 'integrated'}
Integrated
{/if}
</div>
@ -194,7 +194,7 @@
<span class="commit__subtitle-divider"></span>
<span
>{getTimeAgo(commit.createdAt)}{type == 'remote' || type == 'upstream'
>{getTimeAgo(commit.createdAt)}{type === 'remote' || type === 'upstream'
? ` by ${commit.author.name}`
: ''}</span
>
@ -252,7 +252,7 @@
{#if showDetails}
<div class="files-container">
<BranchFilesList title="Files" {files} {isUnapplied} readonly={type == 'upstream'} />
<BranchFilesList title="Files" {files} {isUnapplied} readonly={type === 'upstream'} />
</div>
{/if}
</div>

View File

@ -29,9 +29,9 @@
return false;
}
if (data instanceof DraggableHunk && data.branchId == $branch.id) {
if (data instanceof DraggableHunk && data.branchId === $branch.id) {
return true;
} else if (data instanceof DraggableFile && data.branchId == $branch.id) {
} else if (data instanceof DraggableFile && data.branchId === $branch.id) {
return true;
} else {
return false;
@ -70,7 +70,7 @@
}
return (data: any) => {
if (!(data instanceof DraggableCommit)) return false;
if (data.branchId != $branch.id) return false;
if (data.branchId !== $branch.id) return false;
if (data.commit.isParentOf(commit)) {
if (data.commit.isIntegrated) return false;

View File

@ -50,7 +50,7 @@
{sectionFirst}
status={shadowIn}
help={shadowHelp || help}
shadow={commitStatus && commitStatus != 'upstream'}
shadow={commitStatus && commitStatus !== 'upstream'}
shadowLane
/>
{/if}
@ -62,11 +62,11 @@
root={localRoot}
inType={remoteIn}
outType={remoteOut}
outDashed={remoteOut == 'integrated'}
inDashed={remoteIn == 'integrated'}
outDashed={remoteOut === 'integrated'}
inDashed={remoteIn === 'integrated'}
{integrated}
>
{#if !isRebased && (relatedToOther || commitStatus != 'local')}
{#if !isRebased && (relatedToOther || commitStatus !== 'local')}
<Avatar
{author}
{sectionFirst}
@ -88,7 +88,7 @@
root={remoteRoot}
longRoot={remoteRoot && !last}
>
{#if commitStatus == 'local'}
{#if commitStatus === 'local'}
<Avatar {help} {sectionFirst} {author} status={commitStatus} />
{/if}
</LocalLine>

View File

@ -43,14 +43,14 @@
$: forkPoint = $branch.forkPoint;
$: upstreamForkPoint = $branch.upstreamData?.forkPoint;
$: isRebased = !!forkPoint && !!upstreamForkPoint && forkPoint != upstreamForkPoint;
$: isRebased = !!forkPoint && !!upstreamForkPoint && forkPoint !== upstreamForkPoint;
let baseIsUnfolded = false;
function getRemoteOutType(commit: Commit): CommitStatus | undefined {
if (!hasShadowedCommits) {
const childStatus = commit.next?.status;
return childStatus != 'local' ? childStatus : undefined;
return childStatus !== 'local' ? childStatus : undefined;
}
// TODO: Consider introducing `relatedParent` and `relatedChildren`
@ -71,8 +71,8 @@
function getRemoteInType(commit: Commit): CommitStatus | undefined {
if (commit.prev) return getRemoteOutType(commit.prev || commit);
if (commit.status == 'remote' || commit.relatedTo) return 'remote';
if (commit.status == 'integrated') return 'integrated';
if (commit.status === 'remote' || commit.relatedTo) return 'remote';
if (commit.status === 'integrated') return 'integrated';
}
function insertBlankCommit(commitId: string, location: 'above' | 'below' = 'below') {
@ -80,7 +80,7 @@
console.error('Unable to insert commit');
return;
}
branchController.insertBlankCommit($branch.id, commitId, location == 'above' ? -1 : 1);
branchController.insertBlankCommit($branch.id, commitId, location === 'above' ? -1 : 1);
}
</script>
@ -94,8 +94,8 @@
branch={$branch}
{commit}
{isUnapplied}
first={idx == 0}
last={idx == $unknownCommits.length - 1}
first={idx === 0}
last={idx === $unknownCommits.length - 1}
commitUrl={$baseBranch?.commitUrl(commit.id)}
isHeadCommit={commit.id === headCommit?.id}
>
@ -106,24 +106,24 @@
localIn={'local'}
localOut={'local'}
author={commit.author}
sectionFirst={idx == 0}
sectionFirst={idx === 0}
inDashed={hasLocalColumn}
outDashed={hasLocalColumn}
commitStatus={commit.status}
help={getAvatarTooltip(commit)}
remoteIn={!isRebased ? 'upstream' : undefined}
remoteOut={!isRebased && idx != 0 ? 'upstream' : undefined}
remoteOut={!isRebased && idx !== 0 ? 'upstream' : undefined}
shadowIn={isRebased ? 'upstream' : undefined}
shadowOut={idx != 0 && isRebased ? 'upstream' : undefined}
shadowOut={idx !== 0 && isRebased ? 'upstream' : undefined}
/>
</svelte:fragment>
</CommitCard>
{/each}
{/if}
<QuickActionMenu
offset={$localCommits.length == 0 &&
$remoteCommits.length == 0 &&
$integratedCommits.length == 0
offset={$localCommits.length === 0 &&
$remoteCommits.length === 0 &&
$integratedCommits.length === 0
? 0
: 0.75}
padding={1}
@ -143,9 +143,9 @@
{commit}
{isUnapplied}
type="local"
first={idx == 0}
first={idx === 0}
branch={$branch}
last={idx == $localCommits.length - 1}
last={idx === $localCommits.length - 1}
commitUrl={$baseBranch?.commitUrl(commit.id)}
isHeadCommit={commit.id === headCommit?.id}
>
@ -156,18 +156,18 @@
localIn={'local'}
localOut={'local'}
author={commit.author}
sectionFirst={idx == 0}
sectionFirst={idx === 0}
commitStatus={commit.status}
help={getAvatarTooltip(commit)}
shadowHelp={getAvatarTooltip(commit.relatedTo)}
outDashed={hasLocalColumn && idx == 0}
outDashed={hasLocalColumn && idx === 0}
remoteIn={!isRebased ? getRemoteInType(commit) : undefined}
remoteOut={!isRebased ? getRemoteOutType(commit) : undefined}
shadowIn={isRebased ? getRemoteInType(commit) : undefined}
shadowOut={isRebased ? getRemoteOutType(commit) : undefined}
relatedToOther={commit?.relatedTo && commit.relatedTo.id != commit.id}
remoteRoot={idx == $localCommits.length - 1}
last={idx == $localCommits.length - 1 && !hasRemoteCommits && !hasIntegratedCommits}
relatedToOther={commit?.relatedTo && commit.relatedTo.id !== commit.id}
remoteRoot={idx === $localCommits.length - 1}
last={idx === $localCommits.length - 1 && !hasRemoteCommits && !hasIntegratedCommits}
/>
</svelte:fragment>
</CommitCard>
@ -177,7 +177,7 @@
/>
<QuickActionMenu
padding={1}
offset={$remoteCommits.length > 0 && idx + 1 == $localCommits.length ? 0.25 : 0}
offset={$remoteCommits.length > 0 && idx + 1 === $localCommits.length ? 0.25 : 0}
>
<Button style="ghost" size="tag" on:click={() => insertBlankCommit(commit.id, 'below')}
>Insert blank commit</Button
@ -192,10 +192,10 @@
{commit}
{isUnapplied}
type="remote"
first={idx == 0}
first={idx === 0}
branch={$branch}
last={idx == $remoteCommits.length - 1}
isHeadCommit={commit.id == headCommit?.id}
last={idx === $remoteCommits.length - 1}
isHeadCommit={commit.id === headCommit?.id}
commitUrl={$baseBranch?.commitUrl(commit.id)}
>
<svelte:fragment slot="lines">
@ -203,13 +203,13 @@
{hasLocalColumn}
{isRebased}
author={commit.author}
sectionFirst={idx == 0}
sectionFirst={idx === 0}
commitStatus={commit.status}
help={getAvatarTooltip(commit)}
shadowHelp={getAvatarTooltip(commit.relatedTo)}
integrated={commit.isIntegrated}
localRoot={idx == 0 && hasLocalCommits}
outDashed={idx == 0 && commit.prev?.status == 'local'}
localRoot={idx === 0 && hasLocalCommits}
outDashed={idx === 0 && commit.prev?.status === 'local'}
remoteIn={!isRebased ? getRemoteInType(commit) : undefined}
remoteOut={!isRebased ? getRemoteOutType(commit) : undefined}
shadowIn={isRebased ? getRemoteInType(commit) : undefined}
@ -235,10 +235,10 @@
{commit}
{isUnapplied}
type="integrated"
first={idx == 0}
first={idx === 0}
branch={$branch}
isHeadCommit={commit.id === headCommit?.id}
last={idx == $integratedCommits.length - 1}
last={idx === $integratedCommits.length - 1}
commitUrl={$baseBranch?.commitUrl(commit.id)}
>
<svelte:fragment slot="lines">
@ -246,7 +246,7 @@
{hasLocalColumn}
{isRebased}
author={commit.author}
sectionFirst={idx == 0}
sectionFirst={idx === 0}
commitStatus={commit.status}
help={getAvatarTooltip(commit)}
shadowIn={isRebased ? getRemoteInType(commit) : undefined}
@ -254,7 +254,7 @@
remoteIn={!isRebased ? getRemoteInType(commit) : undefined}
remoteOut={!isRebased ? getRemoteOutType(commit) : undefined}
integrated={true}
localRoot={idx == 0 && !hasRemoteCommits && hasLocalCommits}
localRoot={idx === 0 && !hasRemoteCommits && hasLocalCommits}
/>
</svelte:fragment>
</CommitCard>

View File

@ -15,15 +15,15 @@
function accepts(data: any) {
if (!(data instanceof DraggableCommit)) return false;
if (data.branchId != $branch.id) return false;
if (indexer.dropzoneCommitOffset(index, data.commit.id) == 0) return false;
if (data.branchId !== $branch.id) return false;
if (indexer.dropzoneCommitOffset(index, data.commit.id) === 0) return false;
return true;
}
function onDrop(data: any) {
if (!(data instanceof DraggableCommit)) return;
if (data.branchId != $branch.id) return;
if (data.branchId !== $branch.id) return;
const offset = indexer.dropzoneCommitOffset(index, data.commit.id);
branchController.reorderCommit($branch.id, data.commit.id, offset);

View File

@ -157,11 +157,11 @@
}}
on:keydown={(e) => {
const value = e.currentTarget.value;
if (e.key == 'Backspace' && value.length == 0) {
if (e.key === 'Backspace' && value.length === 0) {
e.preventDefault();
titleTextArea.focus();
useAutoHeight(e.currentTarget);
} else if (e.key == 'a' && (e.metaKey || e.ctrlKey) && value.length == 0) {
} else if (e.key === 'a' && (e.metaKey || e.ctrlKey) && value.length === 0) {
// select previous textarea on cmd+a if this textarea is empty
e.preventDefault();
titleTextArea.select();

View File

@ -108,7 +108,7 @@
disabled={loading}
on:click={checkCredentials}
>
{#if loading || checks.length == 0}
{#if loading || checks.length === 0}
Test credentials
{:else}
Re-test credentials

View File

@ -64,8 +64,8 @@
}}
bind:this={contextMenuContainer}
style:display={visible ? 'block' : 'none'}
class:dropdown-top={dropdownPosition == 'top'}
class:dropdown-bottom={dropdownPosition == 'bottom'}
class:dropdown-top={dropdownPosition === 'top'}
class:dropdown-bottom={dropdownPosition === 'bottom'}
>
<slot name="context-menu" />
</div>

View File

@ -9,9 +9,9 @@
<div
class="{className} dropzone"
class:small={radius == 's'}
class:medium={radius == 'm'}
class:large={radius == 'l'}
class:small={radius === 's'}
class:medium={radius === 'm'}
class:large={radius === 'l'}
>
<div class=" dropzone-wrapper">
<div class="dropzone-content">

View File

@ -6,9 +6,9 @@
<div
class="status"
class:added={status == 'A'}
class:modified={status == 'M'}
class:deleted={status == 'D'}
class:added={status === 'A'}
class:modified={status === 'M'}
class:deleted={status === 'D'}
></div>
<style lang="postcss">

View File

@ -117,7 +117,7 @@
</div>
<!-- EMPTY STATE -->
{#if $snapshots.length == 0 && !$loading}
{#if $snapshots.length === 0 && !$loading}
<EmptyStatePlaceholder image={emptyFolderSvg}>
<svelte:fragment slot="title">No snapshots yet</svelte:fragment>
<svelte:fragment slot="caption">
@ -128,7 +128,7 @@
{/if}
<!-- INITIAL LOADING -->
{#if $loading && $snapshots.length == 0}
{#if $loading && $snapshots.length === 0}
<FullviewLoading />
{/if}
@ -139,7 +139,7 @@
<!-- SNAPSHOTS FEED -->
{#each $snapshots as entry, idx (entry.id)}
{@const withinRestoreItems = findRestorationRanges($snapshots)}
{#if idx === 0 || createdOnDay(entry.createdAt) != createdOnDay($snapshots[idx - 1].createdAt)}
{#if idx === 0 || createdOnDay(entry.createdAt) !== createdOnDay($snapshots[idx - 1].createdAt)}
<div class="sideview__date-header">
<h4 class="text-base-13 text-semibold">
{createdOnDay(entry.createdAt)}
@ -161,8 +161,8 @@
on:diffClick={async (filePath) => {
const path = filePath.detail;
if (snapshotFilesTempStore?.entryId == entry.id) {
if (selectedFile?.path == path) {
if (snapshotFilesTempStore?.entryId === entry.id) {
if (selectedFile?.path === path) {
currentFilePreview = undefined;
selectedFile = undefined;
} else {

View File

@ -24,8 +24,8 @@
style:height={pxToRem(size)}
style="--spinner-radius: {spinnerRadius}"
>
{#if name == 'spinner'}
<g class:spinner={name == 'spinner'}>
{#if name === 'spinner'}
<g class:spinner={name === 'spinner'}>
<circle class="spinner-path" cx="8" cy="8" r={spinnerRadius} fill="none" />
<circle
class="spinner-back-path"

View File

@ -31,13 +31,13 @@
let credentialCheck: CredentialCheck;
let selectedType: KeyType =
typeof project.preferred_key == 'string' ? project.preferred_key : 'local';
typeof project.preferred_key === 'string' ? project.preferred_key : 'local';
let privateKeyPath =
typeof project.preferred_key == 'string' ? '' : project.preferred_key.local.private_key_path;
typeof project.preferred_key === 'string' ? '' : project.preferred_key.local.private_key_path;
function setLocalKey() {
if (privateKeyPath.trim().length == 0) return;
if (privateKeyPath.trim().length === 0) return;
updateKey({
preferred_key: {
local: {
@ -62,7 +62,7 @@
credentialCheck.reset();
const formData = new FormData(form);
selectedType = formData.get('credentialType') as KeyType;
if (selectedType != 'local') {
if (selectedType !== 'local') {
updateKey({ preferred_key: selectedType });
} else {
setLocalKey();
@ -93,7 +93,7 @@
>
<svelte:fragment slot="caption">
{#if selectedType == 'systemExecutable'}
{#if selectedType === 'systemExecutable'}
Git executable must be present on your PATH
{/if}
</svelte:fragment>
@ -106,7 +106,7 @@
<SectionCard
roundedTop={false}
roundedBottom={false}
bottomBorder={selectedType != 'local'}
bottomBorder={selectedType !== 'local'}
orientation="row"
labelFor="credential-local"
>
@ -117,13 +117,13 @@
</svelte:fragment>
<svelte:fragment slot="caption">
{#if selectedType == 'local'}
{#if selectedType === 'local'}
Add the path to an existing SSH key that GitButler can use.
{/if}
</svelte:fragment>
</SectionCard>
{#if selectedType == 'local'}
{#if selectedType === 'local'}
<SectionCard
topDivider
hasTopRadius={false}
@ -144,7 +144,7 @@
<SectionCard
roundedTop={false}
roundedBottom={false}
bottomBorder={selectedType != 'generated'}
bottomBorder={selectedType !== 'generated'}
orientation="row"
labelFor="credential-generated"
>
@ -155,14 +155,14 @@
</svelte:fragment>
<svelte:fragment slot="caption">
{#if selectedType == 'generated'}
{#if selectedType === 'generated'}
GitButler will use a locally generated SSH key. For this to work you need to add the
following public key to your Git remote provider:
{/if}
</svelte:fragment>
</SectionCard>
{#if selectedType == 'generated'}
{#if selectedType === 'generated'}
<SectionCard topDivider roundedTop={false} roundedBottom={false}>
<TextBox id="sshKey" readonly bind:value={sshKey} wide />
<div class="row-buttons">
@ -192,7 +192,7 @@
<svelte:fragment slot="title">Use a Git credentials helper</svelte:fragment>
<svelte:fragment slot="caption">
{#if selectedType == 'gitCredentialsHelper'}
{#if selectedType === 'gitCredentialsHelper'}
GitButler will use the system's git credentials helper.
<Link target="_blank" rel="noreferrer" href="https://git-scm.com/doc/credential-helpers">
Learn more

View File

@ -17,7 +17,7 @@
<div
class="local-line tip"
class:dashed={outDashed}
class:integrated={inType == 'integrated'}
class:integrated={inType === 'integrated'}
/>
{/if}
{#if inType}
@ -26,7 +26,7 @@
class:dashed={inDashed}
class:sectionFirst
class:has-root={root}
class:integrated={inType == 'integrated'}
class:integrated={inType === 'integrated'}
/>
{/if}
{#if root}

View File

@ -67,17 +67,17 @@
<ContextMenuItem
id={MergeMethod.Merge}
label="Merge pull request"
selected={$action == MergeMethod.Merge}
selected={$action === MergeMethod.Merge}
/>
<ContextMenuItem
id={MergeMethod.Rebase}
label="Rebase and merge"
selected={$action == MergeMethod.Rebase}
selected={$action === MergeMethod.Rebase}
/>
<ContextMenuItem
id={MergeMethod.Squash}
label="Squash and merge"
selected={$action == MergeMethod.Squash}
selected={$action === MergeMethod.Squash}
/>
</ContextMenuSection>
</ContextMenu>

View File

@ -31,9 +31,9 @@
<dialog
class="dialog-wrap"
class:s-default={width == 'default'}
class:s-small={width == 'small'}
class:s-large={width == 'large'}
class:s-default={width === 'default'}
class:s-small={width === 'small'}
class:s-large={width === 'large'}
bind:this={dialog}
on:close={close}
>

View File

@ -108,7 +108,7 @@
<!-- condition prevents split second UI shift -->
{#if $platformName}
<div class="navigation-top">
{#if $platformName == 'darwin'}
{#if $platformName === 'darwin'}
<div class="drag-region" data-tauri-drag-region />
{/if}
<ProjectSelector isNavCollapsed={$isNavCollapsed} />

View File

@ -13,7 +13,7 @@
<!--TODO: Add project id -->
<FullviewLoading />
{:then remoteBranches}
{#if remoteBranches.length == 0}
{#if remoteBranches.length === 0}
<ProblemLoadingRepo
error="Currently, GitButler requires a remote branch to base its virtual branch work on. To
use virtual branches, please push your code to a remote branch to use as a base"

View File

@ -22,11 +22,11 @@
let loading = false;
async function setTarget() {
if (selectedBranch[0] == '') return;
if (selectedBranch[0] === '') return;
loading = true;
try {
// TODO: Refactor temporary solution to forcing Windows to use system executable
if ($platformName == 'win32') {
if ($platformName === 'win32') {
project.preferred_key = 'systemExecutable';
projectService.updateProject(project);
}
@ -39,7 +39,7 @@
</script>
<DecorativeSplitView img={newProjectSvg}>
{#if selectedBranch[0] != '' && $platformName != 'win32'}
{#if selectedBranch[0] !== '' && $platformName !== 'win32'}
{@const [remoteName, branchName] = selectedBranch[0].split(/\/(.*)/s)}
<KeysForm {remoteName} {branchName} />
<div class="actions">
@ -53,7 +53,7 @@
on:branchSelected={(e) => {
selectedBranch = e.detail;
// TODO: Temporary solution to forcing Windows to use system executable
if ($platformName == 'win32') {
if ($platformName === 'win32') {
setTarget();
}
}}

View File

@ -241,7 +241,7 @@
icon="chevron-right-small"
id="set-base-branch"
>
{#if $platformName == 'win32'}
{#if $platformName === 'win32'}
Let's go
{:else}
Continue

View File

@ -51,7 +51,7 @@
style="pop"
kind="solid"
icon="chevron-right-small"
disabled={selectValue == project}
disabled={selectValue === project}
on:mousedown={() => {
if (selectValue) goto(`/${selectValue.id}/`);
}}

View File

@ -30,7 +30,7 @@
<ScrollableContainer maxHeight="20rem">
<div class="popup__projects">
{#each $projects as project}
{@const selected = project.id == $page.params.projectId}
{@const selected = project.id === $page.params.projectId}
<ListItem
{selected}
icon={selected ? 'tick' : undefined}

View File

@ -57,11 +57,11 @@
}}
>
<ContextMenuSection>
<ContextMenuItem id={Action.Create} label="Create PR" selected={$action == Action.Create} />
<ContextMenuItem id={Action.Create} label="Create PR" selected={$action === Action.Create} />
<ContextMenuItem
id={Action.Draft}
label="Create Draft PR"
selected={$action == Action.Draft}
selected={$action === Action.Draft}
/>
</ContextMenuSection>
</ContextMenu>

View File

@ -189,7 +189,7 @@
checksStatus: ChecksStatus | null | undefined,
isFetchingChecks: boolean
): StatusInfo | undefined {
if (mergeableState == 'blocked' && !checksStatus && !isFetchingChecks) {
if (mergeableState === 'blocked' && !checksStatus && !isFetchingChecks) {
return {
icon: 'error',
messageStyle: 'error',
@ -206,7 +206,7 @@
};
}
if (mergeableState == 'unstable') {
if (mergeableState === 'unstable') {
return {
icon: 'warning',
messageStyle: 'warning',
@ -214,7 +214,7 @@
};
}
if (mergeableState == 'dirty') {
if (mergeableState === 'dirty') {
return {
icon: 'warning',
messageStyle: 'warning',
@ -222,7 +222,7 @@
};
}
if (mergeableState == 'blocked' && !isFetchingChecks) {
if (mergeableState === 'blocked' && !isFetchingChecks) {
return {
icon: 'error',
messageStyle: 'error',
@ -285,7 +285,7 @@
clickable={false}
icon={checksTagInfo.icon}
style={checksTagInfo.style}
kind={checksTagInfo.icon == 'success-small' ? 'solid' : 'soft'}
kind={checksTagInfo.icon === 'success-small' ? 'solid' : 'soft'}
>
{checksTagInfo.text}
</Button>
@ -335,7 +335,7 @@
disabled={isFetchingChecks ||
isFetchingDetails ||
pr?.draft ||
(mergeableState != 'clean' && mergeableState != 'unstable')}
(mergeableState !== 'clean' && mergeableState !== 'unstable')}
loading={isMerging}
help="Merge pull request and refresh"
on:click={async (e) => {

View File

@ -37,7 +37,7 @@
let contextMenu: ContextMenu;
let dropDown: DropDownButton;
let disabled = false;
let isPushed = $localCommits.length == 0 && !branch.requiresForce;
let isPushed = $localCommits.length === 0 && !branch.requiresForce;
$: canBeRebased = $unknownCommits.length > 0;
$: selection$ = contextMenu?.selection$;
$: action = selectAction(isPushed, $preferredAction);
@ -92,7 +92,7 @@
<ContextMenuItem
id="push"
label={pushLabel}
selected={action == BranchAction.Push}
selected={action === BranchAction.Push}
disabled={isPushed}
/>
{/if}
@ -100,8 +100,8 @@
<ContextMenuItem
id="rebase"
label="Rebase upstream"
selected={action == BranchAction.Rebase}
disabled={isPushed || $unknownCommits.length == 0}
selected={action === BranchAction.Rebase}
disabled={isPushed || $unknownCommits.length === 0}
/>
{/if}
</ContextMenuSection>

View File

@ -66,8 +66,8 @@
<div>
{#each branchData.commits as commit, index (commit.id)}
<CommitCard
first={index == 0}
last={index == branchData.commits.length - 1}
first={index === 0}
last={index === branchData.commits.length - 1}
{commit}
commitUrl={$baseBranch?.commitUrl(commit.id)}
type="remote"

View File

@ -20,7 +20,7 @@
<div
class="remote-line base tip"
class:dashed={outDashed}
class:upstream={outType == 'upstream'}
class:upstream={outType === 'upstream'}
/>
{/if}
{#if root}
@ -47,8 +47,8 @@
<div
class="remote-line tip"
class:integrated
class:upstream={outType == 'upstream'}
class:remote={outType == 'remote'}
class:upstream={outType === 'upstream'}
class:remote={outType === 'remote'}
class:dashed={outDashed}
class:first={sectionFirst}
/>
@ -58,8 +58,8 @@
class="remote-line short"
class:integrated
class:first={sectionFirst}
class:upstream={inType == 'upstream'}
class:remote={inType == 'remote'}
class:upstream={inType === 'upstream'}
class:remote={inType === 'remote'}
class:dashed={inDashed}
/>
{/if}

View File

@ -42,10 +42,10 @@
document.addEventListener('mouseup', onMouseUp);
document.addEventListener('mousemove', onMouseMove);
if (direction == 'right') initial = e.clientX - viewport.clientWidth;
if (direction == 'left') initial = window.innerWidth - e.clientX - viewport.clientWidth;
if (direction == 'down') initial = e.clientY - viewport.clientHeight;
if (direction == 'up') initial = window.innerHeight - e.clientY - viewport.clientHeight;
if (direction === 'right') initial = e.clientX - viewport.clientWidth;
if (direction === 'left') initial = window.innerWidth - e.clientX - viewport.clientWidth;
if (direction === 'down') initial = e.clientY - viewport.clientHeight;
if (direction === 'up') initial = window.innerHeight - e.clientY - viewport.clientHeight;
dispatch('resizing', true);
}
@ -58,25 +58,25 @@
function onMouseMove(e: MouseEvent) {
dragging = true;
if (direction == 'down') {
if (direction === 'down') {
let height = e.clientY - initial;
dispatch('height', Math.max(height, minHeight));
onOverflowValue(height, minHeight);
}
if (direction == 'up') {
if (direction === 'up') {
let height = document.body.scrollHeight - e.clientY - initial;
dispatch('height', Math.max(height, minHeight));
onOverflowValue(height, minHeight);
}
if (direction == 'right') {
if (direction === 'right') {
let width = e.clientX - initial + 2;
dispatch('width', Math.max(width, minWidth));
onOverflowValue(width, minWidth);
}
if (direction == 'left') {
if (direction === 'left') {
let width = document.body.scrollWidth - e.clientX - initial;
dispatch('width', Math.max(width, minWidth));
@ -108,12 +108,12 @@
aria-valuenow={viewport?.clientHeight}
class="resizer"
class:dragging
class:vertical={orientation == 'vertical'}
class:horizontal={orientation == 'horizontal'}
class:up={direction == 'up'}
class:down={direction == 'down'}
class:left={direction == 'left'}
class:right={direction == 'right'}
class:vertical={orientation === 'vertical'}
class:horizontal={orientation === 'horizontal'}
class:up={direction === 'up'}
class:down={direction === 'down'}
class:left={direction === 'left'}
class:right={direction === 'right'}
class:sticky
style:z-index={zIndex}
>

View File

@ -48,7 +48,7 @@
bind:this={viewport}
on:scroll={(e) => {
const target = e.currentTarget;
scrolled = target.scrollTop != 0;
scrolled = target.scrollTop !== 0;
if (target.scrollTop + target.clientHeight + bottomBuffer >= target.scrollHeight) {
dispatch('bottomReached', true);

View File

@ -36,9 +36,9 @@
class:top-divider={topDivider}
class:bottom-border={bottomBorder}
class:no-border={noBorder}
class:loading={background == 'loading'}
class:success={background == 'success'}
class:error={background == 'error'}
class:loading={background === 'loading'}
class:success={background === 'success'}
class:error={background === 'error'}
class:clickable={labelFor !== '' || clickable}
class:disabled
on:click

View File

@ -33,8 +33,8 @@
<button
bind:this={ref}
class="segment-btn segment-{size}"
class:left={index == 0}
class:right={index == $length - 1}
class:left={index === 0}
class:right={index === $length - 1}
role="tab"
tabindex={isSelected ? -1 : 0}
aria-selected={isSelected}

View File

@ -27,7 +27,7 @@
addSegment: ({ id, index, disabled }) => {
segments = [...segments, { id, index, disabled }];
length.set(segments.length);
if (index == selectedIndex) selected = id;
if (index === selectedIndex) selected = id;
},
setSelected: (segmentIndex) => {
if (segmentIndex >= 0 && segmentIndex < segments.length) {

View File

@ -18,7 +18,7 @@
export let placeholder = '';
export let maxHeight: number | undefined = 260;
$: if (selectedItemId) value = items.find((item) => item[itemId] == selectedItemId);
$: if (selectedItemId) value = items.find((item) => item[itemId] === selectedItemId);
const SLOTS = $$props.$$slots;
const dispatch = createEventDispatcher<{ select: { value: any } }>();
@ -88,13 +88,13 @@
{#each items as item}
<div
class="option"
class:selected={item == value}
class:selected={item === value}
tabindex="-1"
role="none"
on:mousedown={() => handleItemClick(item)}
on:keydown|preventDefault|stopPropagation
>
<slot name="template" {item} selected={item == value} />
<slot name="template" {item} selected={item === value} />
</div>
{/each}
</div>

View File

@ -12,12 +12,12 @@
<div class="shadow-column">
{#if outType}
<div class="shadow-line tip" class:dashed={outDashed} class:upstream={outType == 'upstream'} />
<div class="shadow-line tip" class:dashed={outDashed} class:upstream={outType === 'upstream'} />
{/if}
{#if inType}
<div
class="shadow-line short"
class:upstream={inType == 'upstream'}
class:upstream={inType === 'upstream'}
class:first={sectionFirst}
class:dashed={inDashed}
/>

View File

@ -37,7 +37,7 @@
return lowerCaseStr.charAt(0).toUpperCase() + lowerCaseStr.slice(1);
}
// if (entry.details?.operation == 'RestoreFromSnapshot') {
// if (entry.details?.operation === 'RestoreFromSnapshot') {
// console.log(entry.details);
// }
@ -52,42 +52,42 @@
// BRANCH OPERATIONS
case 'DeleteBranch':
return {
text: `Delete branch "${entry.details?.trailers.find((t) => t.key == 'name')?.value}"`,
text: `Delete branch "${entry.details?.trailers.find((t) => t.key === 'name')?.value}"`,
icon: 'item-cross'
};
case 'ApplyBranch':
return {
text: `Apply branch "${entry.details?.trailers.find((t) => t.key == 'name')?.value}"`,
text: `Apply branch "${entry.details?.trailers.find((t) => t.key === 'name')?.value}"`,
icon: 'item-tick'
};
case 'UnapplyBranch':
return {
text: `Unapply branch "${snapshotDetails.trailers.find((t) => t.key == 'name')?.value}"`,
text: `Unapply branch "${snapshotDetails.trailers.find((t) => t.key === 'name')?.value}"`,
icon: 'item-dashed'
};
case 'UpdateBranchName':
return {
text: `Renamed branch "${snapshotDetails.trailers.find((t) => t.key == 'before')?.value}" to "${snapshotDetails.trailers.find((t) => t.key == 'after')?.value}"`,
text: `Renamed branch "${snapshotDetails.trailers.find((t) => t.key === 'before')?.value}" to "${snapshotDetails.trailers.find((t) => t.key === 'after')?.value}"`,
icon: 'item-slash'
};
case 'CreateBranch':
return {
text: `Create branch "${snapshotDetails.trailers.find((t) => t.key == 'name')?.value}"`,
text: `Create branch "${snapshotDetails.trailers.find((t) => t.key === 'name')?.value}"`,
icon: 'item-plus'
};
case 'ReorderBranches':
return {
text: `Reorder branches "${snapshotDetails.trailers.find((t) => t.key == 'before')?.value}" and "${snapshotDetails.trailers.find((t) => t.key == 'after')?.value}"`,
text: `Reorder branches "${snapshotDetails.trailers.find((t) => t.key === 'before')?.value}" and "${snapshotDetails.trailers.find((t) => t.key === 'after')?.value}"`,
icon: 'item-link'
};
case 'SelectDefaultVirtualBranch':
return {
text: `Select default virtual branch "${snapshotDetails.trailers.find((t) => t.key == 'after')?.value}"`,
text: `Select default virtual branch "${snapshotDetails.trailers.find((t) => t.key === 'after')?.value}"`,
icon: 'item-dot'
};
case 'UpdateBranchRemoteName':
return {
text: `Update branch remote name "${snapshotDetails.trailers.find((t) => t.key == 'before')?.value}" to "${snapshotDetails.trailers.find((t) => t.key == 'after')?.value}"`,
text: `Update branch remote name "${snapshotDetails.trailers.find((t) => t.key === 'before')?.value}" to "${snapshotDetails.trailers.find((t) => t.key === 'after')?.value}"`,
icon: 'item-slash'
};
case 'SetBaseBranch':
@ -98,15 +98,15 @@
// COMMIT OPERATIONS
case 'CreateCommit':
return {
text: `Create commit ${getShortSha(entry.details?.trailers.find((t) => t.key == 'sha')?.value)}`,
text: `Create commit ${getShortSha(entry.details?.trailers.find((t) => t.key === 'sha')?.value)}`,
icon: 'new-commit',
commitMessage: entry.details?.trailers.find((t) => t.key == 'message')?.value
commitMessage: entry.details?.trailers.find((t) => t.key === 'message')?.value
};
case 'UndoCommit':
return {
text: `Undo commit ${getShortSha(entry.details?.trailers.find((t) => t.key == 'sha')?.value)}`,
text: `Undo commit ${getShortSha(entry.details?.trailers.find((t) => t.key === 'sha')?.value)}`,
icon: 'undo-commit',
commitMessage: entry.details?.trailers.find((t) => t.key == 'message')?.value
commitMessage: entry.details?.trailers.find((t) => t.key === 'message')?.value
};
case 'AmendCommit':
return { text: 'Amend commit', icon: 'amend-commit' };
@ -126,7 +126,7 @@
// FILE OPERATIONS
case 'MoveHunk':
return {
text: `Move hunk to "${entry.details?.trailers.find((t) => t.key == 'name')?.value}"`,
text: `Move hunk to "${entry.details?.trailers.find((t) => t.key === 'name')?.value}"`,
icon: 'item-move'
};
case 'DiscardHunk':
@ -148,7 +148,7 @@
}
}
const isRestoreSnapshot = entry.details?.operation == 'RestoreFromSnapshot';
const isRestoreSnapshot = entry.details?.operation === 'RestoreFromSnapshot';
const operation = mapOperation(entry.details);
@ -210,8 +210,8 @@
{#each entry.filesChanged as filePath}
<button
class="files-attacment__file"
class:file-selected={selectedFile?.path == filePath &&
selectedFile?.entryId == entry.id}
class:file-selected={selectedFile?.path === filePath &&
selectedFile?.entryId === entry.id}
on:click={() => {
dispatch('diffClick', filePath);
}}
@ -243,12 +243,15 @@
<div class="restored-attacment__content">
<h4 class="text-base-13 text-semibold">
{camelToTitleCase(
entry.details?.trailers.find((t) => t.key == 'restored_operation')?.value
entry.details?.trailers.find((t) => t.key === 'restored_operation')?.value
)}
</h4>
<span class="restored-attacment__details text-base-12">
{getShortSha(entry.details?.trailers.find((t) => t.key == 'restored_from')?.value)}{createdOnDayAndTime(
parseInt(entry.details?.trailers.find((t) => t.key == 'restored_date')?.value || '')
{getShortSha(entry.details?.trailers.find((t) => t.key === 'restored_from')?.value)}
{createdOnDayAndTime(
parseInt(
entry.details?.trailers.find((t) => t.key === 'restored_date')?.value || ''
)
)}
</span>
</div>

View File

@ -80,10 +80,10 @@
autocomplete={autocomplete ? 'on' : 'off'}
min={minVal}
max={maxVal}
{...type == 'password' && showPassword ? { type: 'text' } : { type }}
{...type === 'password' && showPassword ? { type: 'text' } : { type }}
class:show-count-actions={showCountActions}
class="text-input textbox__input text-base-13"
class:textbox__readonly={type != 'select' && readonly}
class:textbox__readonly={type !== 'select' && readonly}
class:select-none={noselect}
style:text-align={textAlign}
bind:value
@ -99,7 +99,7 @@
on:keydown={(e) => dispatch('keydown', e)}
/>
{#if type == 'number' && showCountActions}
{#if type === 'number' && showCountActions}
<div class="textbox__count-actions">
<button
class="textbox__count-btn"
@ -128,7 +128,7 @@
</div>
{/if}
{#if type == 'password'}
{#if type === 'password'}
<button
class="textbox__show-hide-icon"
on:click={() => {

View File

@ -51,7 +51,7 @@
<li>
<button
class="profile-sidebar__menu-item"
class:item_selected={currentSection == 'profile'}
class:item_selected={currentSection === 'profile'}
on:mousedown={() => onMenuClick('profile')}
>
<Icon name="profile" />
@ -61,7 +61,7 @@
<li>
<button
class="profile-sidebar__menu-item"
class:item_selected={currentSection == 'git'}
class:item_selected={currentSection === 'git'}
on:mousedown={() => onMenuClick('git')}
>
<Icon name="git" />
@ -73,7 +73,7 @@
<li>
<button
class="profile-sidebar__menu-item"
class:item_selected={currentSection == 'integrations'}
class:item_selected={currentSection === 'integrations'}
on:mousedown={() => onMenuClick('integrations')}
>
<Icon name="integrations" />
@ -84,7 +84,7 @@
<li>
<button
class="profile-sidebar__menu-item"
class:item_selected={currentSection == 'ai'}
class:item_selected={currentSection === 'ai'}
on:mousedown={() => onMenuClick('ai')}
>
<Icon name="ai" />
@ -94,7 +94,7 @@
<li>
<button
class="profile-sidebar__menu-item"
class:item_selected={currentSection == 'telemetry'}
class:item_selected={currentSection === 'telemetry'}
on:mousedown={() => onMenuClick('telemetry')}
>
<Icon name="stat" />
@ -104,7 +104,7 @@
<li>
<button
class="profile-sidebar__menu-item"
class:item_selected={currentSection == 'experimental'}
class:item_selected={currentSection === 'experimental'}
on:mousedown={() => onMenuClick('experimental')}
>
<Icon name="idea" />

View File

@ -10,7 +10,7 @@ const defaultDropzoneOptions: Dropzone = {
disabled: false,
active: 'dropzone-active',
hover: 'dropzone-hover',
accepts: (data) => data == 'default',
accepts: (data) => data === 'default',
onDrop: () => {}
};
@ -48,6 +48,6 @@ function register(node: HTMLElement, dropzone: Dropzone) {
}
function unregister(dropzone: Dropzone) {
const index = dzRegistry.findIndex(([, dz]) => dz == dropzone);
const index = dzRegistry.findIndex(([, dz]) => dz === dropzone);
if (index >= 0) dzRegistry.splice(index, 1);
}

View File

@ -35,7 +35,7 @@ export class ReorderDropzoneIndexer {
dropzoneIndexBelowCommit(commitId: string) {
const index = this.dropzoneIndexes.get(commitId);
if (index == undefined) {
if (index === undefined) {
throw new Error(`Commit ${commitId} not found in dropzoneIndexes`);
}
@ -45,7 +45,7 @@ export class ReorderDropzoneIndexer {
commitIndex(commitId: string) {
const index = this.commitIndexes.get(commitId);
if (index == undefined) {
if (index === undefined) {
throw new Error(`Commit ${commitId} not found in commitIndexes`);
}
@ -58,7 +58,7 @@ export class ReorderDropzoneIndexer {
dropzoneCommitOffset(dropzoneIndex: number, commitId: string) {
const commitIndex = this.commitIndexes.get(commitId);
if (commitIndex == undefined) {
if (commitIndex === undefined) {
throw new Error(`Commit ${commitId} not found in commitIndexes`);
}

View File

@ -210,7 +210,7 @@ export class GitHubService {
if (pr) this.prCache.set(branchSha, { value: pr, fetchedAt: new Date() });
return pr;
} catch (err: any) {
if (err.status != 422) throw err;
if (err.status !== 422) throw err;
await sleep(1000);
}
}
@ -224,15 +224,15 @@ export class GitHubService {
if (!checkSuites) return true;
// Continue waiting if some check suites are in progress
if (checkSuites.some((suite) => suite.status != 'completed')) return true;
if (checkSuites.some((suite) => suite.status !== 'completed')) return true;
}
getListedPr(branchSha: string): PullRequest | undefined {
return this.prs?.find((pr) => pr.sha == branchSha);
return this.prs?.find((pr) => pr.sha === branchSha);
}
getPr$(branchSha: string): Observable<PullRequest | undefined> {
return this.prs$.pipe(map((prs) => prs.find((pr) => pr.sha == branchSha)));
return this.prs$.pipe(map((prs) => prs.find((pr) => pr.sha === branchSha)));
}
/* TODO: Figure out a way to cleanup old behavior subjects */
@ -354,7 +354,7 @@ export class GitHubService {
// If there are no checks then there is no status to report
const checks = resp.data.check_runs;
if (checks.length == 0) return null;
if (checks.length === 0) return null;
// Establish when the first check started running, useful for showing
// how long something has been running.
@ -363,16 +363,16 @@ export class GitHubService {
.filter((startedAt) => startedAt !== null) as string[];
const startTimes = starts.map((startedAt) => new Date(startedAt));
const queued = checks.filter((c) => c.status == 'queued').length;
const failed = checks.filter((c) => c.conclusion == 'failure').length;
const skipped = checks.filter((c) => c.conclusion == 'skipped').length;
const succeeded = checks.filter((c) => c.conclusion == 'success').length;
const queued = checks.filter((c) => c.status === 'queued').length;
const failed = checks.filter((c) => c.conclusion === 'failure').length;
const skipped = checks.filter((c) => c.conclusion === 'skipped').length;
const succeeded = checks.filter((c) => c.conclusion === 'success').length;
const firstStart = new Date(Math.min(...startTimes.map((date) => date.getTime())));
const completed = checks.every((check) => !!check.completed_at);
const totalCount = resp?.data.total_count;
const success = queued == 0 && failed == 0 && skipped + succeeded == totalCount;
const success = queued === 0 && failed === 0 && skipped + succeeded === totalCount;
const finished = checks.filter(
(c) => c.conclusion && ['failure', 'success'].includes(c.conclusion)
).length;
@ -415,7 +415,7 @@ export class GitHubService {
let retried = 0;
let shouldWait: boolean | undefined = undefined;
while (resp.data.total_count == 0 && retried < retries) {
while (resp.data.total_count === 0 && retried < retries) {
if (shouldWait === undefined && retried > 0) {
shouldWait = await this.shouldWaitForChecks(ref);
if (!shouldWait) {
@ -592,14 +592,14 @@ export class GitHubService {
*/
function mapErrorToToast(err: any): Toast | undefined {
// We expect an object to be thrown by octokit.
if (typeof err != 'object') return;
if (typeof err !== 'object') return;
const { status, response } = err;
const { data } = response;
const { message, errors } = data;
// If this expectation isn't met we must be doing something wrong
if (status == undefined || message == undefined) return;
if (status === undefined || message === undefined) return;
if (message.includes('Draft pull requests are not supported')) {
return {

View File

@ -93,7 +93,7 @@ export function ghResponseToInstance(
? {
name: pr.user.login || undefined,
email: pr.user.email || undefined,
isBot: pr.user.type.toLowerCase() == 'bot',
isBot: pr.user.type.toLowerCase() === 'bot',
gravatarUrl: new URL(pr.user.avatar_url)
}
: null,

View File

@ -34,7 +34,7 @@ export class HistoryService {
// TODO: Update API so we don't have to .slice()
const more = (await this.fetch(this.cursor)).slice(1);
if (more.length == 0) {
if (more.length === 0) {
this.isAllLoaded.set(true);
} else {
this.snapshots.update((snapshots) => [...snapshots, ...more]);
@ -78,5 +78,5 @@ export class HistoryService {
export function createdOnDay(d: Date) {
const t = new Date();
return `${t.toDateString() == d.toDateString() ? 'Today' : d.toLocaleDateString('en-US', { weekday: 'short' })}, ${d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}`;
return `${t.toDateString() === d.toDateString() ? 'Today' : d.toLocaleDateString('en-US', { weekday: 'short' })}, ${d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}`;
}

View File

@ -16,14 +16,14 @@ let idCounter = 0;
export function showToast(toast: Toast) {
toast.message = toast.message?.replace(/^ */gm, '');
toastStore.update((items) => [
...items.filter((t) => toast.id == undefined || t.id != toast.id),
...items.filter((t) => toast.id === undefined || t.id !== toast.id),
{ id: (idCounter++).toString(), ...toast }
]);
}
export function showError(title: string, error: any) {
// Silence GitHub octokit.js when disconnected
if (error.status == 500 && error.message == 'Load failed') return;
if (error.status === 500 && error.message === 'Load failed') return;
const message = error.message || error.toString();
showToast({ title, error: message, style: 'error' });
@ -35,5 +35,5 @@ export function showInfo(title: string, message: string) {
export function dismissToast(messageId: string | undefined) {
if (!messageId) return;
toastStore.update((items) => items.filter((m) => m.id != messageId));
toastStore.update((items) => items.filter((m) => m.id !== messageId));
}

View File

@ -93,7 +93,7 @@ export function parseHunkSection(hunk: Hunk | RemoteHunk): HunkSection {
const line = lines.shift();
if (!line) break;
if (line.startsWith('-')) {
if (!currentSection || currentSection.sectionType != SectionType.RemovedLines) {
if (!currentSection || currentSection.sectionType !== SectionType.RemovedLines) {
if (currentSection) hunkSection.subSections.push(currentSection);
currentSection = plainToInstance(ContentSection, {
expanded: true,
@ -108,7 +108,7 @@ export function parseHunkSection(hunk: Hunk | RemoteHunk): HunkSection {
});
currentBeforeLineNumber++;
} else if (line.startsWith('+')) {
if (!currentSection || currentSection.sectionType != SectionType.AddedLines) {
if (!currentSection || currentSection.sectionType !== SectionType.AddedLines) {
if (currentSection) hunkSection.subSections.push(currentSection);
currentSection = plainToInstance(ContentSection, {
expanded: true,
@ -123,7 +123,7 @@ export function parseHunkSection(hunk: Hunk | RemoteHunk): HunkSection {
});
currentAfterLineNumber++;
} else {
if (!currentSection || currentSection.sectionType != SectionType.Context) {
if (!currentSection || currentSection.sectionType !== SectionType.Context) {
if (currentSection) hunkSection.subSections.push(currentSection);
currentSection = plainToInstance(ContentSection, {
expanded: true,

View File

@ -4,7 +4,7 @@ export type FileStatus = 'A' | 'M' | 'D';
export function computeFileStatus(file: AnyFile): FileStatus {
if (file instanceof RemoteFile) {
if (file.hunks.length == 1) {
if (file.hunks.length === 1) {
const diff = file.hunks[0].diff;
if (/^@@ -1,1 /.test(diff)) return 'A';
if (/^@@ -0,0 /.test(diff)) return 'A';
@ -14,11 +14,11 @@ export function computeFileStatus(file: AnyFile): FileStatus {
return 'M';
}
if (file.hunks.length == 1) {
if (file.hunks.length === 1) {
const changeType = file.hunks[0].changeType;
if (changeType == 'added') {
if (changeType === 'added') {
return 'A';
} else if (changeType == 'deleted') {
} else if (changeType === 'deleted') {
return 'D';
}
}

View File

@ -22,21 +22,21 @@ export function selectFilesInList(
}
} else if (e.shiftKey && allowMultiple) {
const initiallySelectedIndex = sortedFiles.findIndex(
(f) => f.id == fileIdSelection.only()?.fileId
(f) => f.id === fileIdSelection.only()?.fileId
);
// detect the direction of the selection
const selectionDirection =
initiallySelectedIndex < sortedFiles.findIndex((f) => f.id == file.id) ? 'down' : 'up';
initiallySelectedIndex < sortedFiles.findIndex((f) => f.id === file.id) ? 'down' : 'up';
const updatedSelection = sortedFiles.slice(
Math.min(
initiallySelectedIndex,
sortedFiles.findIndex((f) => f.id == file.id)
sortedFiles.findIndex((f) => f.id === file.id)
),
Math.max(
initiallySelectedIndex,
sortedFiles.findIndex((f) => f.id == file.id)
sortedFiles.findIndex((f) => f.id === file.id)
) + 1
);
@ -48,7 +48,7 @@ export function selectFilesInList(
fileIdSelection.set(selectedFileIds);
} else {
// if only one file is selected and it is already selected, unselect it
if (selectedFileIds.length == 1 && isAlreadySelected) {
if (selectedFileIds.length === 1 && isAlreadySelected) {
fileIdSelection.clear();
} else {
fileIdSelection.set([stringifyFileKey(file.id, commit?.id)]);

View File

@ -5,19 +5,19 @@ import type { FileIdSelection } from '$lib/vbranches/fileIdSelection';
import type { AnyFile } from '$lib/vbranches/types';
export function getNextFile(files: AnyFile[], current: string) {
const fileIndex = files.findIndex((f) => f.id == current);
if (fileIndex != -1 && fileIndex + 1 < files.length) return files[fileIndex + 1];
const fileIndex = files.findIndex((f) => f.id === current);
if (fileIndex !== -1 && fileIndex + 1 < files.length) return files[fileIndex + 1];
}
export function getPreviousFile(files: AnyFile[], current: string) {
const fileIndex = files.findIndex((f) => f.id == current);
const fileIndex = files.findIndex((f) => f.id === current);
if (fileIndex > 0) return files[fileIndex - 1];
}
export function getFileByKey(key: string, current: string, files: AnyFile[]): AnyFile | undefined {
if (key == 'ArrowUp') {
if (key === 'ArrowUp') {
return getPreviousFile(files, current);
} else if (key == 'ArrowDown') {
} else if (key === 'ArrowDown') {
return getNextFile(files, current);
}
}
@ -37,7 +37,7 @@ export function updateFocus(
) {
const selected = fileIdSelection.only();
if (!selected) return;
if (selected.fileId == file.id && selected.commitId == commitId) elt.focus();
if (selected.fileId === file.id && selected.commitId === commitId) elt.focus();
}
export function maybeMoveSelection(
@ -46,7 +46,7 @@ export function maybeMoveSelection(
files: AnyFile[],
fileIdSelection: FileIdSelection
) {
if (key != 'ArrowUp' && key != 'ArrowDown') return;
if (key !== 'ArrowUp' && key !== 'ArrowDown') return;
const newSelection = getFileByKey(key, file.id, files);
if (newSelection) {

View File

@ -25,17 +25,17 @@ export function initTheme(userSettings: Writable<Settings>) {
export function updateDom() {
const docEl = document.documentElement;
if (
selectedTheme == 'dark' ||
(selectedTheme == 'system' && systemTheme == 'dark') ||
(selectedTheme == undefined && systemTheme == 'dark')
selectedTheme === 'dark' ||
(selectedTheme === 'system' && systemTheme === 'dark') ||
(selectedTheme === undefined && systemTheme === 'dark')
) {
docEl.classList.remove('light');
docEl.classList.add('dark');
docEl.style.colorScheme = 'dark';
} else if (
selectedTheme == 'light' ||
(selectedTheme == 'system' && systemTheme == 'light') ||
(selectedTheme == undefined && systemTheme == 'light')
selectedTheme === 'light' ||
(selectedTheme === 'system' && systemTheme === 'light') ||
(selectedTheme === undefined && systemTheme === 'light')
) {
docEl.classList.remove('dark');
docEl.classList.add('light');

View File

@ -23,7 +23,7 @@ export function tooltip(node: HTMLElement, optsOrString: ToolTipOptions | string
// Most use cases only involve passing a string, so we allow either opts of
// simple text.
function setOpts(opts: ToolTipOptions | string | undefined) {
if (typeof opts == 'string') {
if (typeof opts === 'string') {
text = opts;
} else if (opts) {
({ text, delay, noMaxWidth } = opts || {});

View File

@ -6,7 +6,7 @@ export function openExternalUrl(href: string) {
try {
open(href);
} catch (e) {
if (typeof e == 'string' || e instanceof String) {
if (typeof e === 'string' || e instanceof String) {
// TODO: Remove if/when we've resolved all external URL problems.
posthog.capture('Link Error', { href, message: e });

View File

@ -73,7 +73,7 @@ export class BaseBranchService {
action: action || 'auto'
});
} catch (err: any) {
if (err.code == Code.DefaultTargetNotFound) {
if (err.code === Code.DefaultTargetNotFound) {
// Swallow this error since user should be taken to project setup page
return;
} else if (err.code === Code.ProjectsGitAuth) {

View File

@ -17,7 +17,7 @@ export function parseFileKey(fileKeyString: string): FileKey {
return {
fileId,
commitId: commitId == 'undefined' ? undefined : commitId
commitId: commitId === 'undefined' ? undefined : commitId
};
}
@ -57,7 +57,7 @@ export class FileIdSelection {
}
remove(fileId: string, commitId?: string) {
this.value = this.value.filter((key) => key != stringifyFileKey(fileId, commitId));
this.value = this.value.filter((key) => key !== stringifyFileKey(fileId, commitId));
this.emit();
}
@ -82,14 +82,14 @@ export class FileIdSelection {
}
only(): FileKey | undefined {
if (this.value.length == 0) return;
if (this.value.length === 0) return;
const fileKey = parseFileKey(this.value[0]);
return fileKey;
}
selectedFile(localFiles: LocalFile[], branchId: string) {
return derived(this, async (value): Promise<AnyFile | undefined> => {
if (value.length != 1) return;
if (value.length !== 1) return;
const fileKey = parseFileKey(value[0]);
return await findFileByKey(localFiles, branchId, fileKey);
});
@ -115,8 +115,8 @@ export class FileIdSelection {
export async function findFileByKey(localFiles: LocalFile[], projectId: string, key: FileKey) {
if (key.commitId) {
const remoteFiles = await listRemoteCommitFiles(projectId, key.commitId);
return remoteFiles.find((file) => file.id == key.fileId);
return remoteFiles.find((file) => file.id === key.fileId);
} else {
return localFiles.find((file) => file.id == key.fileId);
return localFiles.find((file) => file.id === key.fileId);
}
}

View File

@ -14,9 +14,9 @@ export interface TreeNode {
}
function createNode(acc: TreeNode, pathParts: string[]) {
if (pathParts.length == 0) return acc;
if (pathParts.length === 0) return acc;
const node = acc.children?.find((f) => f.name == pathParts[0]);
const node = acc.children?.find((f) => f.name === pathParts[0]);
if (node) return createNode(node, pathParts.slice(1));
const newDir = { name: pathParts[0], children: [], parent: acc };

View File

@ -54,7 +54,7 @@ export class Ownership {
if (!claims) return this;
hunkIds.forEach((hunkId) => {
claims.get(fileId)?.delete(hunkId);
if (claims.get(fileId)?.size == 0) claims.delete(fileId);
if (claims.get(fileId)?.size === 0) claims.delete(fileId);
});
return this;
}
@ -99,6 +99,6 @@ export class Ownership {
}
isEmpty() {
return this.claims.size == 0;
return this.claims.size === 0;
}
}

View File

@ -10,7 +10,7 @@ export function getLockText(hunkLocks: HunkLock | HunkLock[] | string, commits:
.filter(unique)
.map((lock) => {
const commit = commits.find((c) => {
return c.id == lock.commitId;
return c.id === lock.commitId;
});
const shortCommitId = commit?.id.slice(0, 7);
if (commit) {

View File

@ -46,8 +46,8 @@ export class LocalFile {
@Transform((obj) => new Date(obj.value))
modifiedAt!: Date;
// This indicates if a file has merge conflict markers generated and not yet resolved.
// This is true for files after a branch which does not apply cleanly (Branch.isMergeable == false) is applied.
// (therefore this field is applicable only for the workspace, i.e. active == true)
// This is true for files after a branch which does not apply cleanly (Branch.isMergeable === false) is applied.
// (therefore this field is applicable only for the workspace, i.e. active === true)
conflicted!: boolean;
content!: string;
binary!: boolean;
@ -120,7 +120,7 @@ export class Branch {
// This should actually be named "canBeCleanlyApplied" - if it's false, applying this branch will generate conflict markers,
// but it's totatlly okay for a user to apply it.
// If the branch has been already applied, then it was either performed cleanly or we generated conflict markers in the diffs.
// (therefore this field is applicable for stashed/unapplied or remote branches, i.e. active == false)
// (therefore this field is applicable for stashed/unapplied or remote branches, i.e. active === false)
isMergeable!: Promise<boolean>;
@Transform((obj) => new Date(obj.value))
updatedAt!: Date;
@ -132,15 +132,15 @@ export class Branch {
forkPoint!: string;
get localCommits() {
return this.commits.filter((c) => c.status == 'local');
return this.commits.filter((c) => c.status === 'local');
}
get remoteCommits() {
return this.commits.filter((c) => c.status == 'remote');
return this.commits.filter((c) => c.status === 'remote');
}
get integratedCommits() {
return this.commits.filter((c) => c.status == 'integrated');
return this.commits.filter((c) => c.status === 'integrated');
}
get displayName() {
@ -188,7 +188,7 @@ export class Commit {
get status(): CommitStatus {
if (this.isIntegrated) return 'integrated';
if (this.isRemote && (!this.relatedTo || this.id == this.relatedTo.id)) return 'remote';
if (this.isRemote && (!this.relatedTo || this.id === this.relatedTo.id)) return 'remote';
return 'local';
}
@ -260,8 +260,8 @@ export const INTEGRATED_COMMITS = Symbol('IntegratedCommits');
export const UNKNOWN_COMMITS = Symbol('UnknownCommits');
export function commitCompare(left: AnyCommit, right: AnyCommit): boolean {
if (left.id == right.id) return true;
if (left.changeId && right.changeId && left.changeId == right.changeId) return true;
if (left.id === right.id) return true;
if (left.changeId && right.changeId && left.changeId === right.changeId) return true;
return false;
}
@ -363,7 +363,7 @@ export class RemoteBranchData {
get authors(): Author[] {
const allAuthors = this.commits.map((commit) => commit.author);
const uniqueAuthors = allAuthors.filter(
(author, index) => allAuthors.findIndex((a) => a.email == author.email) == index
(author, index) => allAuthors.findIndex((a) => a.email === author.email) === index
);
return uniqueAuthors;
}

View File

@ -130,7 +130,7 @@ export class VirtualBranchService {
return await firstValueFrom(
this.branches$.pipe(
timeout(10000),
map((branches) => branches?.find((b) => b.id == branchId && b.upstream))
map((branches) => branches?.find((b) => b.id === branchId && b.upstream))
)
);
}
@ -139,7 +139,7 @@ export class VirtualBranchService {
return await firstValueFrom(
this.branches$.pipe(
timeout(10000),
map((branches) => branches?.find((b) => b.upstream?.sha == upstreamSha))
map((branches) => branches?.find((b) => b.upstream?.sha === upstreamSha))
)
);
}
@ -159,14 +159,14 @@ export async function listVirtualBranches(params: { projectId: string }): Promis
function linkAsParentChildren(commits: Commit[] | RemoteCommit[]) {
for (let j = 0; j < commits.length; j++) {
const commit = commits[j];
if (j == 0) {
if (j === 0) {
commit.next = undefined;
} else {
const child = commits[j - 1];
if (child instanceof Commit) commit.next = child;
if (child instanceof RemoteCommit) commit.next = child;
}
if (j != commits.length - 1) {
if (j !== commits.length - 1) {
commit.prev = commits[j + 1];
}
}

View File

@ -65,7 +65,7 @@
hotkeys.on('Meta+T', () => {
userSettings.update((s) => ({
...s,
theme: $userSettings.theme == 'light' ? 'dark' : 'light'
theme: $userSettings.theme === 'light' ? 'dark' : 'light'
}));
}),
hotkeys.on('Backspace', (e) => {

View File

@ -22,7 +22,7 @@
const persistedId = projectService.getLastOpenedProject();
const redirect = derived(projects, (projects) => {
if (debug || !projects) return null;
const projectId = projects.find((p) => p.id == persistedId)?.id;
const projectId = projects.find((p) => p.id === persistedId)?.id;
if (projectId) return projectId;
if (projects.length > 0) return projects[0].id;
return null;

View File

@ -38,7 +38,7 @@ export async function load({ params, parent }) {
const fetches$ = getFetchNotifications(projectId);
const heads$ = getHeads(projectId);
const gbBranchActive$ = heads$.pipe(map((head) => head == 'gitbutler/integration'));
const gbBranchActive$ = heads$.pipe(map((head) => head === 'gitbutler/integration'));
const historyService = new HistoryService(projectId);
const baseBranchService = new BaseBranchService(projectId, remoteUrl$, fetches$, heads$);

View File

@ -14,7 +14,7 @@
const githubService = getContext(GitHubService);
$: pr$ = githubService.prs$?.pipe(
map((prs) => prs.find((b) => b.number.toString() == $page.params.number))
map((prs) => prs.find((b) => b.number.toString() === $page.params.number))
);
</script>

View File

@ -16,7 +16,7 @@
$: ({ error, branches } = data.remoteBranchService);
$: branch = $branches?.find((b) => b.sha == $page.params.sha);
$: branch = $branches?.find((b) => b.sha === $page.params.sha);
$: pr = branch && githubService.getListedPr(branch.sha);
</script>

View File

@ -47,7 +47,7 @@
{/if}
<CloudForm />
<DetailsForm />
{#if $platformName != 'win32'}
{#if $platformName !== 'win32'}
<KeysForm showProjectName={false} />
<Spacer />
{/if}

View File

@ -19,7 +19,7 @@
$: branches$ = vbranchService.branches$;
$: error = vbranchService.branchesError;
$: branch = $branches$?.find((b) => b.id == $page.params.branchId);
$: branch = $branches$?.find((b) => b.id === $page.params.branchId);
</script>
{#if $error}

View File

@ -150,14 +150,14 @@
roundedBottom={false}
orientation="row"
labelFor="open-ai"
bottomBorder={modelKind != ModelKind.OpenAI}
bottomBorder={modelKind !== ModelKind.OpenAI}
>
<svelte:fragment slot="title">Open AI</svelte:fragment>
<svelte:fragment slot="actions">
<RadioButton name="modelKind" id="open-ai" value={ModelKind.OpenAI} />
</svelte:fragment>
</SectionCard>
{#if modelKind == ModelKind.OpenAI}
{#if modelKind === ModelKind.OpenAI}
<SectionCard
hasTopRadius={false}
roundedTop={false}
@ -178,7 +178,7 @@
</SelectItem>
</Select>
{#if openAIKeyOption == KeyOption.ButlerAPI}
{#if openAIKeyOption === KeyOption.ButlerAPI}
<InfoMessage filled outlined={false} style="pop" icon="ai">
<svelte:fragment slot="title">
GitButler uses OpenAI API for commit messages and branch names
@ -186,7 +186,7 @@
</InfoMessage>
{/if}
{#if openAIKeyOption == KeyOption.BringYourOwn}
{#if openAIKeyOption === KeyOption.BringYourOwn}
<TextBox label="API Key" bind:value={openAIKey} required placeholder="sk-..." />
<Select
@ -212,14 +212,14 @@
roundedBottom={false}
orientation="row"
labelFor="anthropic"
bottomBorder={modelKind != ModelKind.Anthropic}
bottomBorder={modelKind !== ModelKind.Anthropic}
>
<svelte:fragment slot="title">Anthropic</svelte:fragment>
<svelte:fragment slot="actions">
<RadioButton name="modelKind" id="anthropic" value={ModelKind.Anthropic} />
</svelte:fragment>
</SectionCard>
{#if modelKind == ModelKind.Anthropic}
{#if modelKind === ModelKind.Anthropic}
<SectionCard
hasTopRadius={false}
roundedTop={false}
@ -240,7 +240,7 @@
</SelectItem>
</Select>
{#if anthropicKeyOption == KeyOption.ButlerAPI}
{#if anthropicKeyOption === KeyOption.ButlerAPI}
<InfoMessage filled outlined={false} style="pop" icon="ai">
<svelte:fragment slot="title">
GitButler uses Anthropic API for commit messages and branch names
@ -248,7 +248,7 @@
</InfoMessage>
{/if}
{#if anthropicKeyOption == KeyOption.BringYourOwn}
{#if anthropicKeyOption === KeyOption.BringYourOwn}
<TextBox
label="API Key"
bind:value={anthropicKey}
@ -276,17 +276,17 @@
<SectionCard
roundedTop={false}
roundedBottom={modelKind != ModelKind.Ollama}
roundedBottom={modelKind !== ModelKind.Ollama}
orientation="row"
labelFor="ollama"
bottomBorder={modelKind != ModelKind.Ollama}
bottomBorder={modelKind !== ModelKind.Ollama}
>
<svelte:fragment slot="title">Ollama 🦙</svelte:fragment>
<svelte:fragment slot="actions">
<RadioButton name="modelKind" id="ollama" value={ModelKind.Ollama} />
</svelte:fragment>
</SectionCard>
{#if modelKind == ModelKind.Ollama}
{#if modelKind === ModelKind.Ollama}
<SectionCard hasTopRadius={false} roundedTop={false} orientation="row" topDivider>
<div class="inputs-group">
<TextBox

View File

@ -26,7 +26,7 @@
onMount(async () => {
sshKey = await authService.getPublicKey();
annotateCommits = (await gitConfig.get('gitbutler.gitbutlerCommitter')) == '1';
annotateCommits = (await gitConfig.get('gitbutler.gitbutlerCommitter')) === '1';
});
</script>

View File

@ -41,7 +41,7 @@ export default defineConfig({
},
build: {
// Tauri supports es2021
target: process.env.TAURI_PLATFORM == 'windows' ? 'chrome105' : 'safari13',
target: process.env.TAURI_PLATFORM === 'windows' ? 'chrome105' : 'safari13',
// minify production builds
minify: !process.env.TAURI_DEBUG ? 'esbuild' : false,
// ship sourcemaps for better sentry error reports