@@ -126,6 +126,56 @@ export function updatePrinterSelector(contexts: PrinterContext[], activeContextI
126126 } ) ;
127127}
128128
129+ /**
130+ * One-shot guard so URL-based selection only runs on the initial page load and
131+ * never re-fires on the context re-fetch that follows every manual switch.
132+ */
133+ let hasAppliedUrlSelection = false ;
134+
135+ /**
136+ * Selects a printer context from URL query parameters (e.g. `?ip=192.168.1.100`
137+ * or `?serial=ABCD1234`). Intended for embedding the WebUI in another tool
138+ * (such as OrcaSlicer's Device tab) so the displayed printer stays in sync with
139+ * the host application.
140+ *
141+ * Matches against connected context data (not the DOM selector), so it works
142+ * even when the printer selector is hidden in single-printer mode. Uses exact
143+ * matching to avoid `192.168.1.1` colliding with `192.168.1.10`. Runs at most
144+ * once per page load and no-ops when the target is already active.
145+ */
146+ export async function applyUrlPrinterSelection ( ) : Promise < void > {
147+ if ( hasAppliedUrlSelection ) {
148+ return ;
149+ }
150+ hasAppliedUrlSelection = true ;
151+
152+ const params = new URLSearchParams ( window . location . search ) ;
153+ const ip = params . get ( 'ip' ) ?. trim ( ) ;
154+ const serial = params . get ( 'serial' ) ?. trim ( ) ;
155+ if ( ! ip && ! serial ) {
156+ return ;
157+ }
158+
159+ const match = Array . from ( contextById . values ( ) ) . find (
160+ ( context ) =>
161+ ( ip !== undefined && ip !== '' && context . ipAddress === ip ) ||
162+ ( serial !== undefined &&
163+ serial !== '' &&
164+ context . serialNumber ?. toLowerCase ( ) === serial . toLowerCase ( ) )
165+ ) ;
166+
167+ if ( ! match ) {
168+ showToast ( `No connected printer matches ${ ip ?? serial } ` , 'error' ) ;
169+ return ;
170+ }
171+
172+ if ( match . id === getCurrentContextId ( ) ) {
173+ return ;
174+ }
175+
176+ await switchPrinterContext ( match . id ) ;
177+ }
178+
129179export async function switchPrinterContext ( contextId : string ) : Promise < void > {
130180 if ( state . authRequired && ! state . authToken ) {
131181 showToast ( 'Not authenticated' , 'error' ) ;
0 commit comments