Skip to content

Commit 0fe5e21

Browse files
committed
Mode: Listen for head and mode
Update the way that the FE listens for the head and mode updates. Additionally, listen for changes in the git SHA that the head points to, updating the stacks and stack details alongside
1 parent 798b317 commit 0fe5e21

File tree

8 files changed

+63
-10
lines changed

8 files changed

+63
-10
lines changed

apps/desktop/src/components/ChromeHeader.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
const useCustomTitleBar = $derived(!($settingsStore?.ui.useNativeTitleBar ?? false));
4545
const backend = inject(BACKEND);
4646
47-
const mode = $derived(modeService.mode({ projectId }));
47+
const mode = $derived(modeService.mode(projectId));
4848
const currentMode = $derived(mode.response);
4949
const currentBranchName = $derived.by(() => {
5050
if (currentMode?.type === 'OpenWorkspace') {

apps/desktop/src/components/NotOnGitButlerBranch.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
const [setBaseBranchTarget, targetBranchSwitch] = baseBranchService.setTarget;
2626
2727
const modeService = inject(MODE_SERVICE);
28-
const mode = $derived(modeService.mode({ projectId }));
28+
const mode = $derived(modeService.mode(projectId));
2929
3030
const worktreeService = inject(WORKTREE_SERVICE);
3131
const changes = $derived(worktreeService.treeChanges(projectId));

apps/desktop/src/components/SnapshotCard.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@
168168
const operation = mapOperation(entry.details);
169169
170170
const modeService = inject(MODE_SERVICE);
171-
const mode = $derived(modeService.mode({ projectId }));
171+
const mode = $derived(modeService.mode(projectId));
172172
173173
const historyService = inject(HISTORY_SERVICE);
174174
const snapshotDiff = $derived(historyService.snapshotDiff({ projectId, snapshotId: entry.id }));

apps/desktop/src/lib/mode/modeService.ts

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ interface HeadAndMode {
3232
operatingMode?: Mode;
3333
}
3434

35+
interface HeadSha {
36+
headSha?: string;
37+
}
38+
3539
export const MODE_SERVICE = new InjectionToken<ModeService>('ModeService');
3640

3741
export class ModeService {
@@ -69,8 +73,18 @@ export class ModeService {
6973
return this.api.endpoints.changesSinceInitialEditState.useQuery;
7074
}
7175

72-
get mode() {
73-
return this.api.endpoints.mode.useQuery;
76+
mode(projectId: string) {
77+
return this.api.endpoints.headAndMode.useQuery(
78+
{ projectId },
79+
{ transform: (response) => response.operatingMode }
80+
);
81+
}
82+
83+
head(projectId: string) {
84+
return this.api.endpoints.headSha.useQuery(
85+
{ projectId },
86+
{ transform: (response) => response.headSha }
87+
);
7488
}
7589
}
7690

@@ -136,7 +150,7 @@ function injectEndpoints(api: ClientState['backendApi']) {
136150
unsubscribe();
137151
}
138152
}),
139-
mode: build.query<Mode, { projectId: string }>({
153+
headAndMode: build.query<HeadAndMode, { projectId: string }>({
140154
extraOptions: { command: 'operating_mode' },
141155
query: (args) => args,
142156
providesTags: [providesList(ReduxTag.HeadMetadata)],
@@ -148,7 +162,26 @@ function injectEndpoints(api: ClientState['backendApi']) {
148162
const unsubscribe = lifecycleApi.extra.backend.listen<HeadAndMode>(
149163
`project://${arg.projectId}/git/head`,
150164
(event) => {
151-
lifecycleApi.updateCachedData(() => event.payload.operatingMode);
165+
lifecycleApi.updateCachedData(() => event.payload);
166+
}
167+
);
168+
await lifecycleApi.cacheEntryRemoved;
169+
unsubscribe();
170+
}
171+
}),
172+
headSha: build.query<HeadSha, { projectId: string }>({
173+
extraOptions: { command: 'head_sha' },
174+
query: (args) => args,
175+
providesTags: [providesList(ReduxTag.HeadMetadata)],
176+
async onCacheEntryAdded(arg, lifecycleApi) {
177+
if (!hasBackendExtra(lifecycleApi.extra)) {
178+
throw new Error('Redux dependency Backend not found!');
179+
}
180+
await lifecycleApi.cacheDataLoaded;
181+
const unsubscribe = lifecycleApi.extra.backend.listen<HeadSha>(
182+
`project://${arg.projectId}/git/activity`,
183+
(event) => {
184+
lifecycleApi.updateCachedData(() => event.payload);
152185
}
153186
);
154187
await lifecycleApi.cacheEntryRemoved;

apps/desktop/src/lib/stacks/stackService.svelte.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -929,10 +929,20 @@ export class StackService {
929929
])
930930
);
931931
}
932+
932933
invalidateStacks() {
933934
this.dispatch(this.api.util.invalidateTags([invalidatesList(ReduxTag.Stacks)]));
934935
}
935936

937+
invalidateStacksAndDetails() {
938+
this.dispatch(
939+
this.api.util.invalidateTags([
940+
invalidatesList(ReduxTag.Stacks),
941+
invalidatesList(ReduxTag.StackDetails)
942+
])
943+
);
944+
}
945+
936946
templates(projectId: string, forgeName: string) {
937947
return this.api.endpoints.templates.useQuery({ projectId, forge: forgeName });
938948
}

apps/desktop/src/routes/[projectId]/+layout.svelte

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@
8282
const stackService = inject(STACK_SERVICE);
8383
const worktreeService = inject(WORKTREE_SERVICE);
8484
85-
const modeQuery = $derived(modeService.mode({ projectId }));
85+
const modeQuery = $derived(modeService.mode(projectId));
8686
const mode = $derived(modeQuery.response);
8787
8888
// Invalidate stacks when switching branches outside workspace
@@ -214,6 +214,16 @@
214214
stackService.stackDetailsUpdateListener(projectId);
215215
});
216216
217+
const headResponse = $derived(modeService.head(projectId));
218+
const head = $derived(headResponse.response);
219+
220+
// If the head changes, invalidate stacks and details
221+
$effect(() => {
222+
if (head) {
223+
stackService.invalidateStacksAndDetails();
224+
}
225+
});
226+
217227
// =============================================================================
218228
// AUTO-REFRESH & SYNCHRONIZATION
219229
// =============================================================================

apps/desktop/src/routes/[projectId]/edit/+page.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// TODO: Refactor so we don't need non-null assertion.
1010
const projectId = $derived(page.params.projectId!);
1111
const modeService = inject(MODE_SERVICE);
12-
const mode = $derived(modeService.mode({ projectId }));
12+
const mode = $derived(modeService.mode(projectId));
1313
1414
let editModeMetadata = $state<EditModeMetadata>();
1515

apps/desktop/src/routes/[projectId]/workspace/+page.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
const modeService = inject(MODE_SERVICE);
1111
1212
const projectId = $derived(page.params.projectId!);
13-
const mode = $derived(modeService.mode({ projectId }));
13+
const mode = $derived(modeService.mode(projectId));
1414
const uiState = inject(UI_STATE);
1515
const stackService = inject(STACK_SERVICE);
1616
const projectState = $derived(uiState.project(projectId));

0 commit comments

Comments
 (0)