1- import type { Disposable , QuickInputButton } from 'vscode' ;
1+ import type { Disposable , QuickInputButton , QuickPickItem } from 'vscode' ;
22import { env , ThemeIcon , Uri , window } from 'vscode' ;
33import type { OpenOnRemoteCommandArgs } from '../commands/openOnRemote' ;
44import { SetRemoteAsDefaultQuickInputButton } from '../commands/quickCommand.buttons' ;
55import type { Keys } from '../constants' ;
66import { GlyphChars } from '../constants' ;
7+ import type { IntegrationId } from '../constants.integrations' ;
8+ import type { Sources } from '../constants.telemetry' ;
79import { Container } from '../container' ;
10+ import { RequiresIntegrationError } from '../errors' ;
811import type { GitRemote } from '../git/models/remote' ;
912import type { RemoteResource } from '../git/models/remoteResource' ;
1013import { RemoteResourceType } from '../git/models/remoteResource' ;
@@ -13,10 +16,12 @@ import { getDefaultBranchName } from '../git/utils/-webview/branch.utils';
1316import { getBranchNameWithoutRemote , getRemoteNameFromBranchName } from '../git/utils/branch.utils' ;
1417import { getHighlanderProviders } from '../git/utils/remote.utils' ;
1518import { getNameFromRemoteResource } from '../git/utils/remoteResource.utils' ;
19+ import { remoteProviderIdToIntegrationId } from '../plus/integrations/integrationService' ;
20+ import { providersMetadata } from '../plus/integrations/providers/models' ;
1621import { getQuickPickIgnoreFocusOut } from '../system/-webview/vscode' ;
17- import { filterMap } from '../system/array' ;
1822import { getSettledValue } from '../system/promise' ;
19- import { CommandQuickPickItem } from './items/common' ;
23+ import { CommandQuickPickItem , createQuickPickItemOfT } from './items/common' ;
24+ import { createDirectiveQuickPickItem , Directive } from './items/directive' ;
2025
2126export class ConfigureCustomRemoteProviderCommandQuickPickItem extends CommandQuickPickItem {
2227 constructor ( ) {
@@ -68,6 +73,20 @@ export class CopyOrOpenRemoteCommandQuickPickItem extends CommandQuickPickItem {
6873 ...resource ,
6974 base : { branch : branch , remote : { path : this . remote . path , url : this . remote . url } } ,
7075 } ;
76+
77+ if (
78+ resource . base . remote . url !== resource . compare . remote . url &&
79+ ! ( await this . remote . provider . isReadyForForCrossForkPullRequestUrls ( ) )
80+ ) {
81+ const integrationId = remoteProviderIdToIntegrationId ( this . remote . provider . id ) ;
82+ const connected =
83+ integrationId && ( await this . showIntegrationConnectionPicker ( integrationId , 'view' ) ) ;
84+ if ( ! connected ) {
85+ throw new RequiresIntegrationError (
86+ 'Cross-fork pull request URLs are not supported by this provider' ,
87+ ) ;
88+ }
89+ }
7190 } else if (
7291 resource . type === RemoteResourceType . File &&
7392 resource . branchOrTag != null &&
@@ -96,11 +115,68 @@ export class CopyOrOpenRemoteCommandQuickPickItem extends CommandQuickPickItem {
96115 } ) ,
97116 ) ;
98117
99- const resources = filterMap ( resourcesResults , r => getSettledValue ( r ) ) ;
118+ const resources = resourcesResults
119+ . map ( r => {
120+ if ( r . status === 'fulfilled' ) {
121+ return r . value ;
122+ }
123+ if ( r . reason instanceof RequiresIntegrationError ) {
124+ throw r . reason ;
125+ }
126+ return undefined ;
127+ } )
128+ . filter ( ( r ) : r is RemoteResource => r !== undefined ) ;
100129
101130 void ( await ( this . clipboard ? this . remote . provider . copy ( resources ) : this . remote . provider . open ( resources ) ) ) ;
102131 }
103132
133+ async showIntegrationConnectionPicker ( integrationId : IntegrationId , source : Sources ) : Promise < boolean > {
134+ const disposables : Disposable [ ] = [ ] ;
135+ const quickpick = window . createQuickPick < QuickPickItem > ( ) ;
136+ try {
137+ const integrationName = providersMetadata [ integrationId ] . name ;
138+ const connectItem = createQuickPickItemOfT (
139+ {
140+ label : `Connect a ${ integrationName } Integration...` ,
141+ detail : `Connect a ${ integrationName } integration to be able to create cross-fork pull requests` ,
142+ picked : true ,
143+ } ,
144+ true ,
145+ ) ;
146+ const cancelItem = createDirectiveQuickPickItem ( Directive . Cancel , false , { label : 'Cancel' } ) ;
147+ const quickpickPromise = new Promise < undefined | QuickPickItem > ( resolve => {
148+ disposables . push (
149+ quickpick . onDidHide ( ( ) => resolve ( undefined ) ) ,
150+ quickpick . onDidAccept ( ( ) => {
151+ if ( quickpick . activeItems . length !== 0 ) {
152+ resolve ( quickpick . activeItems [ 0 ] ) ;
153+ }
154+ } ) ,
155+ ) ;
156+ } ) ;
157+ quickpick . ignoreFocusOut = getQuickPickIgnoreFocusOut ( ) ;
158+ quickpick . title = `Connect a ${ integrationName } Integration` ;
159+ quickpick . placeholder = `Connect a ${ integrationName } integration to be able to create cross-fork pull requests` ;
160+ quickpick . matchOnDetail = true ;
161+ quickpick . items = [ connectItem , cancelItem ] ;
162+ quickpick . show ( ) ;
163+ const pick = await quickpickPromise ;
164+ if ( pick === connectItem ) {
165+ const connected = await Container . instance . integrations . connectCloudIntegrations (
166+ { integrationIds : [ integrationId ] } ,
167+ {
168+ source : source ,
169+ } ,
170+ ) ;
171+ return connected ;
172+ }
173+ } finally {
174+ quickpick . dispose ( ) ;
175+ disposables . forEach ( d => void d . dispose ( ) ) ;
176+ }
177+ return false ;
178+ }
179+
104180 setAsDefault ( ) : Promise < void > {
105181 return this . remote . setAsDefault ( true ) ;
106182 }
0 commit comments