@@ -11,7 +11,7 @@ import { Task } from "@lit/task";
1111import { CharmController } from "@commontools/charm/ops" ;
1212import { CellEventTarget , CellUpdateEvent } from "../lib/cell-event-target.ts" ;
1313import { NAME } from "@commontools/runner" ;
14- import { updatePageTitle } from "../lib/navigate.ts" ;
14+ import { navigate , updatePageTitle } from "../lib/navigate.ts" ;
1515
1616export class XAppView extends BaseView {
1717 static override styles = css `
@@ -56,15 +56,78 @@ export class XAppView extends BaseView {
5656 private titleSubscription ?: CellEventTarget < string | undefined > ;
5757
5858 private debuggerController = new DebuggerController ( this ) ;
59+ private _onGlobalKeyDown = ( e : KeyboardEvent ) => {
60+ // Ignore when focusing editable elements
61+ const target = e . target as HTMLElement | null ;
62+ const tag = ( target ?. tagName || "" ) . toLowerCase ( ) ;
63+ const isEditable = ! ! (
64+ target &&
65+ ( target . isContentEditable ||
66+ tag === "input" ||
67+ tag === "textarea" ||
68+ tag === "select" )
69+ ) ;
70+ if ( isEditable ) return ;
71+
72+ // Track modifier state explicitly; some layouts emit separate events
73+ this . _updateModifierState ( e , true ) ;
74+
75+ const isMac = navigator . platform . toLowerCase ( ) . includes ( "mac" ) ;
76+ const hasMod = isMac ? this . _metaDown : this . _ctrlDown ;
77+ const onlyMod = hasMod && ! this . _shiftDown && ! this . _altDown ;
78+ const altOnly = this . _altDown && ! this . _shiftDown && ! this . _metaDown &&
79+ ! this . _ctrlDown ;
80+ if ( onlyMod && e . code === "KeyO" ) {
81+ e . preventDefault ( ) ;
82+ this . command ( { type : "set-show-quick-jump-view" , show : true } ) ;
83+ return ;
84+ }
85+
86+ if ( altOnly && e . code === "KeyW" ) {
87+ e . preventDefault ( ) ;
88+ const spaceName = this . app ?. spaceName ?? "common-knowledge" ;
89+ navigate ( { type : "space" , spaceName } ) ;
90+ }
91+ } ;
92+
93+ private _onGlobalKeyUp = ( e : KeyboardEvent ) => {
94+ this . _updateModifierState ( e , false ) ;
95+ } ;
96+
97+ private _altDown = false ;
98+ private _metaDown = false ;
99+ private _ctrlDown = false ;
100+ private _shiftDown = false ;
101+
102+ private _updateModifierState ( e : KeyboardEvent , down : boolean ) {
103+ switch ( e . key ) {
104+ case "Alt" :
105+ this . _altDown = down ;
106+ break ;
107+ case "Meta" :
108+ this . _metaDown = down ;
109+ break ;
110+ case "Control" :
111+ this . _ctrlDown = down ;
112+ break ;
113+ case "Shift" :
114+ this . _shiftDown = down ;
115+ break ;
116+ }
117+ }
59118
60119 override connectedCallback ( ) {
61120 super . connectedCallback ( ) ;
62121 // Listen for clear telemetry events
63122 this . addEventListener ( "clear-telemetry" , this . handleClearTelemetry ) ;
123+ document . addEventListener ( "keydown" , this . _onGlobalKeyDown ) ;
124+ document . addEventListener ( "keyup" , this . _onGlobalKeyUp ) ;
64125 }
65126
66127 override disconnectedCallback ( ) {
67128 this . removeEventListener ( "clear-telemetry" , this . handleClearTelemetry ) ;
129+ document . removeEventListener ( "keydown" , this . _onGlobalKeyDown ) ;
130+ document . removeEventListener ( "keyup" , this . _onGlobalKeyUp ) ;
68131 super . disconnectedCallback ( ) ;
69132 }
70133
@@ -184,6 +247,10 @@ export class XAppView extends BaseView {
184247 .visible ="${ this . debuggerController . isVisible ( ) } "
185248 .telemetryMarkers ="${ this . debuggerController . getTelemetryMarkers ( ) } "
186249 > </ x-debugger-view >
250+ < x-quick-jump-view
251+ .visible ="${ this . app ?. showQuickJumpView ?? false } "
252+ .rt ="${ this . rt } "
253+ > </ x-quick-jump-view >
187254 `
188255 : "" }
189256 ` ;
0 commit comments