Skip to content

Commit

Permalink
Merge pull request gitbutlerapp#4695 from gitbutlerapp/Edit-mode-actions
Browse files Browse the repository at this point in the history
Add edit mode actions
  • Loading branch information
Caleb-T-Owens committed Aug 19, 2024
2 parents daa285f + 4a9114f commit 3379671
Show file tree
Hide file tree
Showing 23 changed files with 571 additions and 39 deletions.
20 changes: 20 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ members = [
"crates/gitbutler-url",
"crates/gitbutler-diff",
"crates/gitbutler-operating-modes",
"crates/gitbutler-edit-mode",
]
resolver = "2"

Expand Down Expand Up @@ -79,6 +80,7 @@ gitbutler-tagged-string = { path = "crates/gitbutler-tagged-string" }
gitbutler-url = { path = "crates/gitbutler-url" }
gitbutler-diff = { path = "crates/gitbutler-diff" }
gitbutler-operating-modes = { path = "crates/gitbutler-operating-modes" }
gitbutler-edit-mode = { path = "crates/gitbutler-edit-mode" }

[profile.release]
codegen-units = 1 # Compile crates one after another so the compiler can optimize better
Expand Down
24 changes: 23 additions & 1 deletion apps/desktop/src/lib/commit/CommitCard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
import { BaseBranch } from '$lib/baseBranch/baseBranch';
import CommitMessageInput from '$lib/commit/CommitMessageInput.svelte';
import { persistedCommitMessage } from '$lib/config/config';
import { featureEditMode } from '$lib/config/uiFeatureFlags';
import { draggableCommit } from '$lib/dragging/draggable';
import { DraggableCommit, nonDraggable } from '$lib/dragging/draggables';
import BranchFilesList from '$lib/file/BranchFilesList.svelte';
import { ModeService } from '$lib/modes/service';
import { copyToClipboard } from '$lib/utils/clipboard';
import { getContext, getContextStore } from '$lib/utils/context';
import { getContext, getContextStore, maybeGetContext } from '$lib/utils/context';
import { openExternalUrl } from '$lib/utils/url';
import { BranchController } from '$lib/vbranches/branchController';
import { createCommitStore } from '$lib/vbranches/contexts';
Expand Down Expand Up @@ -40,6 +42,9 @@
const branchController = getContext(BranchController);
const baseBranch = getContextStore(BaseBranch);
const project = getContext(Project);
const modeService = maybeGetContext(ModeService);
const editModeEnabled = featureEditMode();
const commitStore = createCommitStore(commit);
$: commitStore.set(commit);
Expand Down Expand Up @@ -116,6 +121,20 @@
let dragDirection: 'up' | 'down' | undefined;
let isDragTargeted = false;
function canEdit() {
if (isUnapplied) return false;
if (!modeService) return false;
if (!branch) return false;
return true;
}
async function editPatch() {
if (!canEdit()) return;
modeService!.enterEditMode(commit.id, branch!.refname);
}
</script>

<Modal bind:this={commitMessageModal} width="small">
Expand Down Expand Up @@ -318,6 +337,9 @@
onclick={openCommitMessageModal}>Edit message</Button
>
{/if}
{#if canEdit() && $editModeEnabled}
<Button size="tag" style="ghost" outline onclick={editPatch}>Edit patch</Button>
{/if}
</div>
{/if}
</div>
Expand Down
78 changes: 78 additions & 0 deletions apps/desktop/src/lib/components/EditMode.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<script lang="ts">
import DecorativeSplitView from './DecorativeSplitView.svelte';
import ProjectNameLabel from '../shared/ProjectNameLabel.svelte';
import dzenPc from '$lib/assets/dzen-pc.svg?raw';
import { Project } from '$lib/backend/projects';
import { ModeService, type EditModeMetadata } from '$lib/modes/service';
import { getContext } from '$lib/utils/context';
import Button from '@gitbutler/ui/Button.svelte';
interface Props {
editModeMetadata: EditModeMetadata;
}
const { editModeMetadata }: Props = $props();
const project = getContext(Project);
const modeService = getContext(ModeService);
let modeServiceSaving = $state<'inert' | 'loading' | 'completed'>('inert');
async function save() {
modeServiceSaving = 'loading';
await modeService.saveEditAndReturnToWorkspace();
modeServiceSaving = 'completed';
}
</script>

<DecorativeSplitView img={dzenPc}>
<div class="switchrepo">
<div class="project-name">
<ProjectNameLabel projectName={project?.title} />
</div>
<p class="switchrepo__title text-18 text-body text-bold">
You are currently editing commit <span class="code-string">
{editModeMetadata.commitOid.slice(0, 7)}
</span>
</p>

<p class="switchrepo__message text-13 text-body">Bla bla bla</p>

<div class="switchrepo__actions">
<Button
style="pop"
kind="solid"
icon="undo-small"
reversedDirection
onclick={save}
loading={modeServiceSaving === 'loading'}
>
Save changes
</Button>
</div>
</div>
</DecorativeSplitView>

<style lang="postcss">
.project-name {
margin-bottom: 12px;
}
.switchrepo__title {
color: var(--clr-scale-ntrl-30);
margin-bottom: 12px;
}
.switchrepo__message {
color: var(--clr-scale-ntrl-50);
margin-bottom: 20px;
}
.switchrepo__actions {
display: flex;
gap: 8px;
padding-bottom: 24px;
flex-wrap: wrap;
}
</style>
5 changes: 5 additions & 0 deletions apps/desktop/src/lib/config/uiFeatureFlags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,8 @@ export function featureInlineUnifiedDiffs(): Persisted<boolean> {
const key = 'inlineUnifiedDiffs';
return persisted(false, key);
}

export function featureEditMode(): Persisted<boolean> {
const key = 'editMode';
return persisted(false, key);
}
2 changes: 2 additions & 0 deletions apps/desktop/src/lib/history/SnapshotCard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@
return { text: 'Update workspace base', icon: 'rebase' };
case 'RestoreFromSnapshot':
return { text: 'Revert snapshot', icon: 'empty' };
case 'EnterEditMode':
return { text: 'Enter Edit Mode', icon: 'edit-text' };
default:
return { text: snapshotDetails.operation, icon: 'commit' };
}
Expand Down
3 changes: 2 additions & 1 deletion apps/desktop/src/lib/history/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ export type Operation =
| 'ReorderCommit'
| 'InsertBlankCommit'
| 'MoveCommitFile'
| 'FileChanges';
| 'FileChanges'
| 'EnterEditMode';

export class Trailer {
key!: string;
Expand Down
27 changes: 26 additions & 1 deletion apps/desktop/src/lib/modes/service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
import { invoke, listen } from '$lib/backend/ipc';
import { derived, writable } from 'svelte/store';

type Mode = { type: 'OpenWorkspace' } | { type: 'OutsideWorksapce' } | { type: 'Edit' };
export interface EditModeMetadata {
commitOid: string;
branchReference: string;
}

type Mode =
| { type: 'OpenWorkspace' }
| { type: 'OutsideWorkspace' }
| {
type: 'Edit';
subject: EditModeMetadata;
};
interface HeadAndMode {
head?: string;
operatingMode?: Mode;
Expand Down Expand Up @@ -29,6 +40,20 @@ export class ModeService {

this.headAndMode.set({ head, operatingMode });
}

async enterEditMode(commitOid: string, branchReference: string) {
await invoke('enter_edit_mode', {
projectId: this.projectId,
commitOid,
branchReference
});
}

async saveEditAndReturnToWorkspace() {
await invoke('save_edit_and_return_to_workspace', {
projectId: this.projectId
});
}
}

function subscribeToHead(projectId: string, callback: (headAndMode: HeadAndMode) => void) {
Expand Down
19 changes: 0 additions & 19 deletions apps/desktop/src/lib/navigation/WorkspaceButton.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -38,29 +38,10 @@
</DomainButton>

<style lang="postcss">
.domain-button {
display: flex;
align-items: center;
gap: 10px;
border-radius: var(--radius-m);
padding: 10px;
color: var(--clr-text-1);
transition: background-color var(--transition-fast);
}
.icon {
border-radius: var(--radius-s);
height: 20px;
width: 20px;
flex-shrink: 0;
}
.domain-button:not(.selected):hover,
.domain-button:not(.selected):focus {
background-color: var(--clr-bg-1-muted);
}
.selected {
background-color: var(--clr-bg-2);
}
</style>
1 change: 1 addition & 0 deletions apps/desktop/src/lib/vbranches/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ export class VirtualBranch {
forkPoint!: string;
allowRebasing!: boolean;
pr?: PullRequest;
refname!: string;

get localCommits() {
return this.commits.filter((c) => c.status === 'local');
Expand Down
26 changes: 16 additions & 10 deletions apps/desktop/src/routes/[projectId]/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import { getNameNormalizationServiceContext } from '$lib/branches/nameNormalizationService';
import { BranchService, createBranchServiceStore } from '$lib/branches/service';
import { CommitDragActionsFactory } from '$lib/commits/dragActions';
import EditMode from '$lib/components/EditMode.svelte';
import NoBaseBranch from '$lib/components/NoBaseBranch.svelte';
import NotOnGitButlerBranch from '$lib/components/NotOnGitButlerBranch.svelte';
import ProblemLoadingRepo from '$lib/components/ProblemLoadingRepo.svelte';
Expand All @@ -20,6 +21,7 @@
import History from '$lib/history/History.svelte';
import { HistoryService } from '$lib/history/history';
import MetricsReporter from '$lib/metrics/MetricsReporter.svelte';
import { ModeService } from '$lib/modes/service';
import Navigation from '$lib/navigation/Navigation.svelte';
import { persisted } from '$lib/persisted/persisted';
import { RemoteBranchService } from '$lib/stores/remoteBranches';
Expand Down Expand Up @@ -69,6 +71,7 @@
setContext(ReorderDropzoneManagerFactory, data.reorderDropzoneManagerFactory);
setContext(RemoteBranchService, data.remoteBranchService);
setContext(BranchListingService, data.branchListingService);
setContext(ModeService, data.modeService);
});
let intervalId: any;
Expand Down Expand Up @@ -98,7 +101,6 @@
// Refresh base branch if git fetch event is detected.
const mode = $derived(modeService.mode);
const head = $derived(modeService.head);
const openWorkspace = $derived($mode?.type === 'OpenWorkspace');
// We end up with a `state_unsafe_mutation` when switching projects if we
// don't use $effect.pre here.
Expand Down Expand Up @@ -180,16 +182,20 @@
<ProblemLoadingRepo error={$branchesError} />
{:else if $projectError}
<ProblemLoadingRepo error={$projectError} />
{:else if !openWorkspace && $baseBranch}
<NotOnGitButlerBranch baseBranch={$baseBranch} />
{:else if $baseBranch}
<div class="view-wrap" role="group" ondragover={(e) => e.preventDefault()}>
<Navigation />
{#if $showHistoryView}
<History on:hide={() => ($showHistoryView = false)} />
{/if}
{@render children()}
</div>
{#if $mode?.type === 'OpenWorkspace'}
<div class="view-wrap" role="group" ondragover={(e) => e.preventDefault()}>
<Navigation />
{#if $showHistoryView}
<History on:hide={() => ($showHistoryView = false)} />
{/if}
{@render children()}
</div>
{:else if $mode?.type === 'OutsideWorkspace'}
<NotOnGitButlerBranch baseBranch={$baseBranch} />
{:else if $mode?.type === 'Edit'}
<EditMode editModeMetadata={$mode.subject} />
{/if}
{/if}
<MetricsReporter {projectMetrics} />
{/key}
Expand Down
16 changes: 16 additions & 0 deletions apps/desktop/src/routes/settings/experimental/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
import SectionCard from '$lib/components/SectionCard.svelte';
import {
featureBaseBranchSwitching,
featureEditMode,
featureInlineUnifiedDiffs
} from '$lib/config/uiFeatureFlags';
import ContentWrapper from '$lib/settings/ContentWrapper.svelte';
import Toggle from '$lib/shared/Toggle.svelte';
const baseBranchSwitching = featureBaseBranchSwitching();
const inlineUnifiedDiffs = featureInlineUnifiedDiffs();
const editMode = featureEditMode();
</script>

<ContentWrapper title="Experimental features">
Expand Down Expand Up @@ -45,6 +47,20 @@
/>
</svelte:fragment>
</SectionCard>
<SectionCard labelFor="editMode" orientation="row">
<svelte:fragment slot="title">Edit mode</svelte:fragment>
<svelte:fragment slot="caption">
Provides an "Edit patch" button on each commit which puts you into edit mode. Edit mode checks
out a particular commit so you can make changes to a particular commit, and then have the
child commits automatically rebased on top of the new changes.
<br /><br />
Please note that creating conflicts whilst inside edit mode is currently not supported. This feature
is still experimental and may result in loss of work.
</svelte:fragment>
<svelte:fragment slot="actions">
<Toggle id="editMode" checked={$editMode} on:click={() => ($editMode = !$editMode)} />
</svelte:fragment>
</SectionCard>
</ContentWrapper>

<style>
Expand Down
Loading

0 comments on commit 3379671

Please sign in to comment.