Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/desktop/src/components/BranchCard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@
>
{#if args.type === "stack-branch"}
{@const moveHandler = args.stackId
? new MoveCommitDzHandler(stackService, args.stackId, projectId, uiState)
? new MoveCommitDzHandler(args.stackId, projectId)
: undefined}
{#if !args.prNumber && args.stackId}
<PrNumberUpdater {projectId} stackId={args.stackId} {branchName} />
Expand Down
109 changes: 51 additions & 58 deletions apps/desktop/src/components/BranchCommitList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@
import { HOOKS_SERVICE } from "$lib/hooks/hooksService";
import { IRC_API_SERVICE } from "$lib/irc/ircApiService";
import { createCommitSelection } from "$lib/selection/key";
import { getStackContext } from "$lib/stack/stackController.svelte";
import { STACK_SERVICE } from "$lib/stacks/stackService.svelte";

import { combineResults } from "$lib/state/helpers";
import { UI_STATE } from "$lib/state/uiState.svelte";
import { ensureValue } from "$lib/utils/validation";
import { inject } from "@gitbutler/core/context";
import { persisted } from "@gitbutler/shared/persisted";
import { Button, Modal, RadioButton, TestId } from "@gitbutler/ui";
Expand All @@ -45,61 +47,36 @@
import type { BranchDetails } from "$lib/stacks/stack";

interface Props {
projectId: string;
stackId?: string;
laneId: string;
branchName: string;
lastBranch: boolean;
branchDetails: BranchDetails;
stackingReorderDropzoneManager: ReorderCommitDzFactory;
roundedTop?: boolean;
active?: boolean;
visibleRange?: { start: number; end: number };

handleUncommit: (commitId: string, branchName: string) => Promise<void>;
startEditingCommitMessage: (branchName: string, commitId: string) => void;
onclick?: () => void;
onFileClick?: (index: number) => void;
}

let {
projectId,
stackId,
laneId,
branchName,
branchDetails,
lastBranch,
stackingReorderDropzoneManager,
roundedTop,
active,
visibleRange,
handleUncommit,
startEditingCommitMessage,
onclick,
onFileClick,
}: Props = $props();
let { branchName, branchDetails, lastBranch, stackingReorderDropzoneManager, roundedTop }: Props =
$props();

const controller = getStackContext();
const stackService = inject(STACK_SERVICE);
const uiState = inject(UI_STATE);
const forge = inject(DEFAULT_FORGE_FACTORY);
const hooksService = inject(HOOKS_SERVICE);
const ircApiService = inject(IRC_API_SERVICE);
const dropzoneRegistry = inject(DROPZONE_REGISTRY);
const dragStateService = inject(DRAG_STATE_SERVICE);

// Reactive aliases for template readability (passed to leaf components)
const projectId = $derived(controller.projectId);
const stackId = $derived(controller.stackId);

const commitReactionsQuery = $derived(ircApiService.commitReactions());
const commitReactions = $derived(commitReactionsQuery?.response ?? {});

const [integrateUpstreamCommits, integrating] = stackService.integrateUpstreamCommits;

const projectState = $derived(uiState.project(projectId));
const exclusiveAction = $derived(projectState.exclusiveAction.current);
const exclusiveAction = $derived(controller.exclusiveAction);
const commitAction = $derived(exclusiveAction?.type === "commit" ? exclusiveAction : undefined);
const isCommitting = $derived(
exclusiveAction?.type === "commit" && exclusiveAction.stackId === stackId,
);
const laneState = $derived(uiState.lane(laneId));
const selection = $derived(laneState.selection);
const selection = $derived(controller.selection);
const runHooks = $derived(projectRunCommitHooks(projectId));

const selectedBranchName = $derived(selection.current?.branchName);
Expand All @@ -113,14 +90,33 @@
let integrationModal = $state<Modal>();

async function handleCommitClick(commitId: string, upstream: boolean) {
const currentSelection = laneState.selection.current;
const currentSelection = controller.selection.current;
// Toggle: if this exact commit is already selected, clear the selection
if (currentSelection?.commitId === commitId && currentSelection?.branchName === branchName) {
laneState.selection.set(undefined);
controller.selection.set(undefined);
} else {
laneState.selection.set({ branchName, commitId, upstream, previewOpen: true });
controller.selection.set({ branchName, commitId, upstream, previewOpen: true });
}
onclick?.();
controller.clearWorktreeSelection();
}

async function handleUncommit(commitId: string) {
await stackService.uncommit({
projectId,
stackId: ensureValue(stackId),
branchName,
commitId,
});
}

function startEditingCommitMessage(commitId: string) {
controller.selection.set({ branchName, commitId, previewOpen: true });
controller.projectState.exclusiveAction.set({
type: "edit-commit-message",
stackId,
branchName,
commitId,
});
}

function kickOffIntegration() {
Expand Down Expand Up @@ -215,7 +211,7 @@
{/snippet}

{#snippet commitReorderDz(dropzone: ReorderCommitDzHandler)}
{#if !isCommitting}
{#if !controller.isCommitting}
<Dropzone handlers={[dropzone]}>
{#snippet overlay({ hovered, activated })}
<CommitLineOverlay {hovered} {activated} />
Expand Down Expand Up @@ -247,7 +243,7 @@
{@const lastCommit = i === upstreamOnlyCommits.length - 1}
{@const selected = commit.id === selectedCommitId && branchName === selectedBranchName}
{@const commitId = commit.id}
{#if !isCommitting}
{#if !controller.isCommitting}
<CommitRow
type="Remote"
{stackId}
Expand All @@ -259,7 +255,7 @@
{first}
{lastCommit}
{selected}
{active}
active={controller.active}
reactions={commitReactions[commit.id]}
onclick={() => handleCommitClick(commit.id, true)}
disableCommitActions={false}
Expand All @@ -283,7 +279,7 @@
{#snippet template(commit, { first, last })}
{@const commitId = commit.id}
{@const selected = commit.id === selectedCommitId && branchName === selectedBranchName}
{#if isCommitting}
{#if controller.isCommitting}
<!-- Only commits to the base can be `last`, see next `CommitGoesHere`. -->
<CommitGoesHere
{commitId}
Expand All @@ -293,7 +289,7 @@
{first}
last={false}
onclick={() => {
projectState.exclusiveAction.set({
controller.projectState.exclusiveAction.set({
type: "commit",
stackId,
branchName,
Expand All @@ -311,17 +307,14 @@
{@const { amendHandler, squashHandler, hunkHandler } = createCommitDropHandlers({
projectId,
stackId,
stackService,
hooksService,
uiState,
commit: dzCommit,
runHooks: $runHooks,
okWithForce: true,
onCommitIdChange: (newId) => {
const wasSelected = laneState.selection.current?.commitId === commitId;
const wasSelected = controller.selection.current?.commitId === commitId;
if (stackId && wasSelected) {
const previewOpen = selection.current?.previewOpen ?? false;
uiState.lane(stackId).selection.set({ branchName, commitId: newId, previewOpen });
controller.laneState.selection.set({ branchName, commitId: newId, previewOpen });
}
},
})}
Expand Down Expand Up @@ -378,7 +371,7 @@
{lastBranch}
{selected}
{tooltip}
{active}
active={controller.active}
reactions={commitReactions[commit.id]}
onclick={() => handleCommitClick(commit.id, false)}
disableCommitActions={false}
Expand All @@ -391,8 +384,8 @@
commitMessage: commit.message,
commitStatus: commit.state.type,
commitUrl: forge.current.commitUrl(commitId),
onUncommitClick: () => handleUncommit(commit.id, branchName),
onEditMessageClick: () => startEditingCommitMessage(branchName, commit.id),
onUncommitClick: () => handleUncommit(commit.id),
onEditMessageClick: () => startEditingCommitMessage(commit.id),
}}
<CommitContextMenu
showOnHover
Expand All @@ -417,7 +410,7 @@
title="Changed files"
{projectId}
{stackId}
{visibleRange}
visibleRange={controller.visibleRange}
draggableFiles
selectionId={createCommitSelection({ commitId: commitId, stackId })}
persistId={`commit-${commitId}`}
Expand All @@ -432,19 +425,19 @@
allowUnselect={false}
onFileClick={(index) => {
// Ensure the commit is selected so the preview shows it
const currentSelection = laneState.selection.current;
const currentSelection = controller.selection.current;
if (
currentSelection?.commitId !== commitId ||
currentSelection?.branchName !== branchName
) {
laneState.selection.set({
controller.selection.set({
branchName,
commitId,
upstream: false,
previewOpen: true,
});
}
onFileClick?.(index);
controller.jumpToIndex(index);
}}
/>
{/snippet}
Expand All @@ -456,7 +449,7 @@
{@render commitReorderDz(
stackingReorderDropzoneManager.belowCommit(branchName, commit.id),
)}
{#if isCommitting && last}
{#if controller.isCommitting && last}
<CommitGoesHere
commitId={branchDetails.baseCommit}
{first}
Expand All @@ -465,7 +458,7 @@
exclusiveAction.parentCommitId === branchDetails.baseCommit &&
commitAction?.branchName === branchName}
onclick={() => {
projectState.exclusiveAction.set({
controller.projectState.exclusiveAction.set({
type: "commit",
stackId,
branchName,
Expand Down
4 changes: 0 additions & 4 deletions apps/desktop/src/components/BranchInsertion.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import Dropzone from "$components/Dropzone.svelte";
import { MoveBranchDzHandler } from "$lib/branches/dropHandler";
import type { ForgePrService } from "$lib/forge/interface/forgePrService";
import type { StackService } from "$lib/stacks/stackService.svelte";

interface Props {
projectId: string;
Expand All @@ -13,7 +12,6 @@
lineColor: string;
isCommitting: boolean;
baseBranchName: string | undefined;
stackService: StackService;
prService: ForgePrService | undefined;
isFirst?: boolean;
}
Expand All @@ -25,15 +23,13 @@
lineColor,
isCommitting,
baseBranchName,
stackService,
prService,
isFirst = false,
}: Props = $props();
</script>

{#if !isCommitting && baseBranchName}
{@const moveBranchHandler = new MoveBranchDzHandler(
stackService,
prService,
projectId,
stackId,
Expand Down
Loading
Loading