@@ -66,9 +66,15 @@ const TRANSPORTS: TransportFactory[] = [
6666] . filter ( ( t ) => t !== undefined ) ;
6767
6868async function listen_for_notifications (
69- notification_stream : ReadableStream < Notification >
69+ notification_stream : ReadableStream < Notification > ,
70+ signal : AbortSignal
7071) : Promise < void > {
7172 let reader = notification_stream . getReader ( ) ;
73+ const onAbort = ( ) => {
74+ reader . cancel ( ) ;
75+ reader . releaseLock ( ) ;
76+ } ;
77+ signal . addEventListener ( "abort" , onAbort , { once : true } ) ;
7278 do {
7379 let pub = usePub ( ) ;
7480
@@ -104,20 +110,24 @@ async function listen_for_notifications(
104110
105111 pub ( topic , eventData ) ;
106112 } catch ( e ) {
113+ signal . removeEventListener ( "abort" , onAbort ) ;
107114 reader . releaseLock ( ) ;
108115 throw e ;
109116 }
110117 } while ( true ) ;
111118
119+ signal . removeEventListener ( "abort" , onAbort ) ;
112120 reader . releaseLock ( ) ;
121+ notification_stream . cancel ( ) ;
113122}
114123
115124async function connect (
116125 transport : RpcTransport ,
117126 setConn : Dispatch < ConnectionState > ,
118- setConnectedDeviceName : Dispatch < string | undefined >
127+ setConnectedDeviceName : Dispatch < string | undefined > ,
128+ signal : AbortSignal
119129) {
120- let conn = await create_rpc_connection ( transport ) ;
130+ let conn = await create_rpc_connection ( transport , { signal } ) ;
121131
122132 let details = await Promise . race ( [
123133 call_rpc ( conn , { core : { getDeviceInfo : true } } )
@@ -135,7 +145,7 @@ async function connect(
135145 return ;
136146 }
137147
138- listen_for_notifications ( conn . notification_readable )
148+ listen_for_notifications ( conn . notification_readable , signal )
139149 . then ( ( ) => {
140150 setConnectedDeviceName ( undefined ) ;
141151 setConn ( { conn : null } ) ;
@@ -157,6 +167,7 @@ function App() {
157167 const [ doIt , undo , redo , canUndo , canRedo , reset ] = useUndoRedo ( ) ;
158168 const [ showAbout , setShowAbout ] = useState ( false ) ;
159169 const [ showLicenseNotice , setShowLicenseNotice ] = useState ( false ) ;
170+ const [ connectionAbort , setConnectionAbort ] = useState ( new AbortController ( ) ) ;
160171
161172 const [ lockState , setLockState ] = useState < LockState > (
162173 LockState . ZMK_STUDIO_CORE_LOCK_STATE_LOCKED
@@ -225,6 +236,49 @@ function App() {
225236 doDiscard ( ) ;
226237 } , [ conn ] ) ;
227238
239+ const resetSettings = useCallback ( ( ) => {
240+ async function doReset ( ) {
241+ if ( ! conn . conn ) {
242+ return ;
243+ }
244+
245+ let resp = await call_rpc ( conn . conn , {
246+ core : { resetSettings : true } ,
247+ } ) ;
248+ if ( ! resp . core ?. resetSettings ) {
249+ console . error ( "Failed to settings reset" , resp ) ;
250+ }
251+
252+ reset ( ) ;
253+ setConn ( { conn : conn . conn } ) ;
254+ }
255+
256+ doReset ( ) ;
257+ } , [ conn ] ) ;
258+
259+ const disconnect = useCallback ( ( ) => {
260+ async function doDisconnect ( ) {
261+ if ( ! conn . conn ) {
262+ return ;
263+ }
264+
265+ await conn . conn . request_writable . close ( ) ;
266+ connectionAbort . abort ( "User disconnected" ) ;
267+ setConnectionAbort ( new AbortController ( ) ) ;
268+ }
269+
270+ doDisconnect ( ) ;
271+ } , [ conn ] ) ;
272+
273+ const onConnect = useCallback (
274+ ( t : RpcTransport ) => {
275+ const ac = new AbortController ( ) ;
276+ setConnectionAbort ( ac ) ;
277+ connect ( t , setConn , setConnectedDeviceName , ac . signal ) ;
278+ } ,
279+ [ setConn , setConnectedDeviceName , setConnectedDeviceName ]
280+ ) ;
281+
228282 return (
229283 < ConnectionContext . Provider value = { conn } >
230284 < LockStateContext . Provider value = { lockState } >
@@ -233,9 +287,7 @@ function App() {
233287 < ConnectModal
234288 open = { ! conn . conn }
235289 transports = { TRANSPORTS }
236- onTransportCreated = { ( t ) =>
237- connect ( t , setConn , setConnectedDeviceName )
238- }
290+ onTransportCreated = { onConnect }
239291 />
240292 < AboutModal open = { showAbout } onClose = { ( ) => setShowAbout ( false ) } />
241293 < LicenseNoticeModal
@@ -251,6 +303,8 @@ function App() {
251303 onRedo = { redo }
252304 onSave = { save }
253305 onDiscard = { discard }
306+ onDisconnect = { disconnect }
307+ onResetSettings = { resetSettings }
254308 />
255309 < Keyboard />
256310 < AppFooter
0 commit comments