Skip to content
Merged
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
1 change: 1 addition & 0 deletions packages/memory/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,7 @@ export interface MemorySession<Space extends MemorySpace = MemorySpace>
}

export interface Subscriber<Space extends MemorySpace = MemorySpace> {
// Notifies a subscriber of a commit that has been applied
commit(commit: Commit<Space>): AwaitResult<Unit, SystemError>;
close(): AwaitResult<Unit, SystemError>;
}
Expand Down
1 change: 1 addition & 0 deletions packages/memory/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ class MemoryProviderSession<
return { ok: {} };
}
dispose() {
this.memory.unsubscribe(this);
this.controller = undefined;
this.sessions?.delete(this);
this.sessions = null;
Expand Down
9 changes: 9 additions & 0 deletions packages/patterns/default-app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,15 @@ export default recipe<CharmsListInput, CharmsListOutput>(
[NAME]: str`DefaultCharmList (${allCharms.length})`,
[UI]: (
<ct-screen>
<ct-keybind
code="KeyN"
alt
preventDefault
onct-keybind={spawnChatbotNote({
allCharms: allCharms as unknown as OpaqueRef<MentionableCharm[]>,
})}
/>

<ct-vstack gap="4" padding="6">
{/* Quick Launch Toolbar */}
<ct-hstack gap="2" align="center">
Expand Down
6 changes: 5 additions & 1 deletion packages/shell/src/lib/app/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ export type Command =
| { type: "set-space"; spaceName: string }
| { type: "clear-authentication" }
| { type: "set-show-charm-list-view"; show: boolean }
| { type: "set-show-debugger-view"; show: boolean };
| { type: "set-show-debugger-view"; show: boolean }
| { type: "set-show-quick-jump-view"; show: boolean };

export function isCommand(value: unknown): value is Command {
if (
Expand Down Expand Up @@ -36,6 +37,9 @@ export function isCommand(value: unknown): value is Command {
case "set-show-debugger-view": {
return "show" in value && typeof value.show === "boolean";
}
case "set-show-quick-jump-view": {
return "show" in value && typeof value.show === "boolean";
}
}
return false;
}
5 changes: 5 additions & 0 deletions packages/shell/src/lib/app/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface AppState {
apiUrl: URL;
showShellCharmListView?: boolean;
showDebuggerView?: boolean;
showQuickJumpView?: boolean;
}

export type AppStateSerialized = Omit<AppState, "identity" | "apiUrl"> & {
Expand Down Expand Up @@ -55,6 +56,10 @@ export function applyCommand(
next.showDebuggerView = command.show;
break;
}
case "set-show-quick-jump-view": {
next.showQuickJumpView = command.show;
break;
}
}

return next;
Expand Down
69 changes: 68 additions & 1 deletion packages/shell/src/views/AppView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Task } from "@lit/task";
import { CharmController } from "@commontools/charm/ops";
import { CellEventTarget, CellUpdateEvent } from "../lib/cell-event-target.ts";
import { NAME } from "@commontools/runner";
import { updatePageTitle } from "../lib/navigate.ts";
import { navigate, updatePageTitle } from "../lib/navigate.ts";

export class XAppView extends BaseView {
static override styles = css`
Expand Down Expand Up @@ -56,15 +56,78 @@ export class XAppView extends BaseView {
private titleSubscription?: CellEventTarget<string | undefined>;

private debuggerController = new DebuggerController(this);
private _onGlobalKeyDown = (e: KeyboardEvent) => {
// Ignore when focusing editable elements
const target = e.target as HTMLElement | null;
const tag = (target?.tagName || "").toLowerCase();
const isEditable = !!(
target &&
(target.isContentEditable ||
tag === "input" ||
tag === "textarea" ||
tag === "select")
);
if (isEditable) return;

// Track modifier state explicitly; some layouts emit separate events
this._updateModifierState(e, true);

const isMac = navigator.platform.toLowerCase().includes("mac");
const hasMod = isMac ? this._metaDown : this._ctrlDown;
const onlyMod = hasMod && !this._shiftDown && !this._altDown;
const altOnly = this._altDown && !this._shiftDown && !this._metaDown &&
!this._ctrlDown;
if (onlyMod && e.code === "KeyO") {
e.preventDefault();
this.command({ type: "set-show-quick-jump-view", show: true });
return;
}

if (altOnly && e.code === "KeyW") {
e.preventDefault();
const spaceName = this.app?.spaceName ?? "common-knowledge";
navigate({ type: "space", spaceName });
}
};

private _onGlobalKeyUp = (e: KeyboardEvent) => {
this._updateModifierState(e, false);
};

private _altDown = false;
private _metaDown = false;
private _ctrlDown = false;
private _shiftDown = false;

private _updateModifierState(e: KeyboardEvent, down: boolean) {
switch (e.key) {
case "Alt":
this._altDown = down;
break;
case "Meta":
this._metaDown = down;
break;
case "Control":
this._ctrlDown = down;
break;
case "Shift":
this._shiftDown = down;
break;
}
}

override connectedCallback() {
super.connectedCallback();
// Listen for clear telemetry events
this.addEventListener("clear-telemetry", this.handleClearTelemetry);
document.addEventListener("keydown", this._onGlobalKeyDown);
document.addEventListener("keyup", this._onGlobalKeyUp);
}

override disconnectedCallback() {
this.removeEventListener("clear-telemetry", this.handleClearTelemetry);
document.removeEventListener("keydown", this._onGlobalKeyDown);
document.removeEventListener("keyup", this._onGlobalKeyUp);
super.disconnectedCallback();
}

Expand Down Expand Up @@ -184,6 +247,10 @@ export class XAppView extends BaseView {
.visible="${this.debuggerController.isVisible()}"
.telemetryMarkers="${this.debuggerController.getTelemetryMarkers()}"
></x-debugger-view>
<x-quick-jump-view
.visible="${this.app?.showQuickJumpView ?? false}"
.rt="${this.rt}"
></x-quick-jump-view>
`
: ""}
`;
Expand Down
Loading
Loading