1
- import type { QuickPickItem } from 'vscode' ;
1
+ import type { QuickPickItem , SecretStorageChangeEvent } from 'vscode' ;
2
2
import { Disposable , env , EventEmitter , ProgressLocation , Range , Uri , window , workspace } from 'vscode' ;
3
3
import type { OpenCloudPatchCommandArgs } from '../../commands/patches' ;
4
4
import type { StoredDeepLinkContext , StoredNamedRef } from '../../constants.storage' ;
@@ -72,16 +72,43 @@ export class DeepLinkService implements Disposable {
72
72
this . _disposables . push (
73
73
this . _onDeepLinkProgressUpdated ,
74
74
container . uri . onDidReceiveUri ( async ( uri : Uri ) => this . processDeepLinkUri ( uri ) ) ,
75
+ container . storage . onDidChangeSecrets ( this . onDidChangeStorage , this ) ,
75
76
) ;
76
77
77
- const pendingDeepLink = this . container . storage . get ( 'deepLinks:pending' ) ;
78
- void this . processPendingDeepLink ( pendingDeepLink ) ;
78
+ void this . container . storage . getSecret ( 'deepLinks:pending' ) . then ( pendingDeepLink => {
79
+ if ( pendingDeepLink != null ) {
80
+ const link = JSON . parse ( pendingDeepLink ) as StoredDeepLinkContext ;
81
+ void this . processPendingDeepLink ( link ) ;
82
+ }
83
+ } ) ;
79
84
}
80
85
81
86
dispose ( ) : void {
82
87
Disposable . from ( ...this . _disposables ) . dispose ( ) ;
83
88
}
84
89
90
+ private async onDidChangeStorage ( e : SecretStorageChangeEvent ) : Promise < void > {
91
+ if ( e . key === 'deepLinks:pending' ) {
92
+ const pendingDeepLinkStored = await this . container . storage . getSecret ( 'deepLinks:pending' ) ;
93
+ if ( pendingDeepLinkStored == null ) return ;
94
+
95
+ const pendingDeepLink = JSON . parse ( pendingDeepLinkStored ) as StoredDeepLinkContext ;
96
+ if ( pendingDeepLink ?. url == null ) return ;
97
+
98
+ const link = parseDeepLinkUri ( Uri . parse ( pendingDeepLink . url ) ) ;
99
+ if ( link == null ) return ;
100
+
101
+ // TODO: See if we can remove this condition without breaking other link flows
102
+ if ( link . action !== DeepLinkActionType . DeleteBranch ) return ;
103
+
104
+ // see if there is a matching repo in the current window
105
+ await this . findMatchingRepositoryFromCurrentWindow ( link . repoPath , link . remoteUrl , link . mainId , true ) ;
106
+ if ( this . _context . repo != null ) {
107
+ void this . processPendingDeepLink ( pendingDeepLink ) ;
108
+ }
109
+ }
110
+ }
111
+
85
112
private resetContext ( ) {
86
113
this . _context = {
87
114
state : DeepLinkServiceState . Idle ,
@@ -203,14 +230,24 @@ export class DeepLinkService implements Disposable {
203
230
repoPath : string | undefined ,
204
231
remoteUrl : string | undefined ,
205
232
repoId : string | undefined ,
233
+ openOnly : boolean = false ,
206
234
) : Promise < void > {
207
235
if ( repoPath != null ) {
208
236
const repoOpenUri = maybeUri ( repoPath ) ? Uri . parse ( repoPath ) : repoPath ;
209
237
try {
210
- const openRepo = await this . container . git . getOrOpenRepository ( repoOpenUri , { detectNested : false } ) ;
211
- if ( openRepo != null ) {
212
- this . _context . repo = openRepo ;
213
- return ;
238
+ if ( openOnly ) {
239
+ for ( const repo of this . container . git . openRepositories ) {
240
+ if ( repo . path === repoPath || repo . uri . fsPath === repoPath ) {
241
+ this . _context . repo = repo ;
242
+ return ;
243
+ }
244
+ }
245
+ } else {
246
+ const openRepo = await this . container . git . getOrOpenRepository ( repoOpenUri , { detectNested : false } ) ;
247
+ if ( openRepo != null ) {
248
+ this . _context . repo = openRepo ;
249
+ return ;
250
+ }
214
251
}
215
252
} catch { }
216
253
}
@@ -223,7 +260,7 @@ export class DeepLinkService implements Disposable {
223
260
224
261
// Try to match a repo using the remote URL first, since that saves us some steps.
225
262
// As a fallback, try to match using the repo id.
226
- for ( const repo of this . container . git . repositories ) {
263
+ for ( const repo of openOnly ? this . container . git . openRepositories : this . container . git . repositories ) {
227
264
if ( repoPath != null && normalizePath ( repo . path . toLowerCase ( ) ) === normalizePath ( repoPath . toLowerCase ( ) ) ) {
228
265
this . _context . repo = repo ;
229
266
return ;
@@ -254,7 +291,7 @@ export class DeepLinkService implements Disposable {
254
291
@debug ( )
255
292
private async processPendingDeepLink ( pendingDeepLink : StoredDeepLinkContext | undefined ) {
256
293
if ( pendingDeepLink == null ) return ;
257
- void this . container . storage . delete ( 'deepLinks:pending' ) ;
294
+ void this . container . storage . deleteSecret ( 'deepLinks:pending' ) ;
258
295
if ( pendingDeepLink ?. url == null ) return ;
259
296
const link = parseDeepLinkUri ( Uri . parse ( pendingDeepLink . url ) ) ;
260
297
if ( link == null ) return ;
@@ -1061,13 +1098,16 @@ export class DeepLinkService implements Disposable {
1061
1098
action = DeepLinkServiceAction . RepoOpening ;
1062
1099
if ( ! ( repoOpenLocation === 'addToWorkspace' && ( workspace . workspaceFolders ?. length || 0 ) > 1 ) ) {
1063
1100
// Deep link will resolve in a different service instance
1064
- await this . container . storage . store ( 'deepLinks:pending' , {
1065
- url : this . _context . url ,
1066
- repoPath : repoOpenUri . toString ( ) ,
1067
- targetSha : this . _context . targetSha ,
1068
- secondaryTargetSha : this . _context . secondaryTargetSha ,
1069
- useProgress : useProgress ,
1070
- } ) ;
1101
+ await this . container . storage . storeSecret (
1102
+ 'deepLinks:pending' ,
1103
+ JSON . stringify ( {
1104
+ url : this . _context . url ,
1105
+ repoPath : repoOpenUri . toString ( ) ,
1106
+ targetSha : this . _context . targetSha ,
1107
+ secondaryTargetSha : this . _context . secondaryTargetSha ,
1108
+ useProgress : useProgress ,
1109
+ } ) ,
1110
+ ) ;
1071
1111
action = DeepLinkServiceAction . DeepLinkStored ;
1072
1112
}
1073
1113
@@ -1349,9 +1389,11 @@ export class DeepLinkService implements Disposable {
1349
1389
1350
1390
// Storing link info in case the switch causes a new window to open
1351
1391
const onWorkspaceChanging = async ( isNewWorktree ?: boolean ) =>
1352
- this . container . storage . store (
1392
+ this . container . storage . storeSecret (
1353
1393
'deepLinks:pending' ,
1354
- isNewWorktree ? pendingDeepLink : { ...pendingDeepLink , url : nonPrUrl } ,
1394
+ isNewWorktree
1395
+ ? JSON . stringify ( pendingDeepLink )
1396
+ : JSON . stringify ( { ...pendingDeepLink , url : nonPrUrl } ) ,
1355
1397
) ;
1356
1398
1357
1399
await executeGitCommand ( {
@@ -1406,7 +1448,7 @@ export class DeepLinkService implements Disposable {
1406
1448
}
1407
1449
case DeepLinkServiceState . OpenInspect : {
1408
1450
// If we arrive at this step, clear any stored data used for the "new window" option
1409
- await this . container . storage . delete ( 'deepLinks:pending' ) ;
1451
+ await this . container . storage . deleteSecret ( 'deepLinks:pending' ) ;
1410
1452
if ( ! repo ) {
1411
1453
action = DeepLinkServiceAction . DeepLinkErrored ;
1412
1454
message = 'Missing repository.' ;
0 commit comments