import { QuickPickItem , window , QuickPick } from 'vscode' ; import * as nls from 'vscode-nls' ; import { RemoteSourceProvider , RemoteSource , PickRemoteSourceOptions , PickRemoteSourceResult } from './api/git-base' ; import { Model } from './model' ; import { throttle , debounce } from './decorators' ; const localize = nls . loadMessageBundle ( ) ; async function getQuickPickResult < T extends QuickPickItem > ( quickpick ) { const result = await new Promise < T | undefined > ( c => { quickpick . onDidAccept ( ( ) => c ( quickpick . selectedItems [ 0 ] ) ) ; quickpick . onDidHide ( ( ) => c ( undefined ) ) ; quickpick . show ( ) ; } ) ; quickpick . hide ( ) ; return result ; } class RemoteSourceProviderQuickPick { private quickpick : QuickPick < QuickPickItem & { remoteSource ? : RemoteSource ; } > ; constructor ( private provider ) { this . quickpick = window . createQuickPick ( ) ; this . quickpick . ignoreFocusOut = true ; if ( provider . supportsQuery ) { this . quickpick . placeholder = localize ( 'type to search' , "Repository name (type to search)" ) ; this . quickpick . onDidChangeValue ( this . onDidChangeValue , this ) ; } else { this . quickpick . placeholder = localize ( 'type to filter' , "Repository name" ) ; } } @ debounce ( 300 ) private onDidChangeValue ( ) { this . query ( ) ; } @ throttle private async query ( ) { this . quickpick . busy = true ; try { const remoteSources = await this . provider . getRemoteSources ( this . quickpick . value ) || [ ] ; if ( remoteSources . length === 0 ) { this . quickpick . items = [ { label : localize ( 'none found' , "No remote repositories found." ) , alwaysShow : true } ] ; } else { this . quickpick . items = remoteSources . map ( remoteSource => ( { label : remoteSource . name , description : remoteSource . description || ( typeof remoteSource . url === 'string' ? remoteSource . url : remoteSource . url [ 0 ] ) , remoteSource , alwaysShow : true } ) ) ; } } catch ( err ) { this . quickpick . items = [ { label : localize ( 'error' , "$(error) Error: {0}" , err . message ) , alwaysShow : true } ] ; console . error ( err ) ; } finally { this . quickpick . busy = false ; } } async pick ( ) { this . query ( ) ; const result = await getQuickPickResult ( this . quickpick ) ; return result ?. remoteSource ; } } export async function pickRemoteSource ( model , options ) ; export async function pickRemoteSource ( model , options ) ; export async function pickRemoteSource ( model , options = { } ) { const quickpick = window . createQuickPick < ( QuickPickItem & { provider ? : RemoteSourceProvider ; url ? : string ; } ) > ( ) ; quickpick . ignoreFocusOut = true ; if ( options . providerName ) { const provider = model . getRemoteProviders ( ) . filter ( provider => provider . name === options . providerName ) [ 0 ] ; if ( provider ) { return await pickProviderSource ( provider , options ) ; } } const providers = model . getRemoteProviders ( ) . map ( provider => ( { label : ( provider . icon ? `$(${ provider . icon }) ` : '' ) + ( options . providerLabel ? options . providerLabel ( provider ) : provider . name ) , alwaysShow : true , provider } ) ) ; quickpick . placeholder = providers . length === 0 ? localize ( 'provide url' , "Provide repository URL" ) : localize ( 'provide url or pick' , "Provide repository URL or pick a repository source." ) ; const updatePicks = ( value ? ) => { if ( value ) { quickpick . items = [ { label : options . urlLabel ?? localize ( 'url' , "URL" ) , description : value , alwaysShow : true , url : value } , ... providers ] ; } else { quickpick . items = providers ; } } ; quickpick . onDidChangeValue ( updatePicks ) ; updatePicks ( ) ; const result = await getQuickPickResult ( quickpick ) ; if ( result ) { if ( result . url ) { return result . url ; } else if ( result . provider ) { return await pickProviderSource ( result . provider , options ) ; } } return undefined ; } async function pickProviderSource ( provider , options = { } ) { const quickpick = new RemoteSourceProviderQuickPick ( provider ) ; const remote = await quickpick . pick ( ) ; let url ; if ( remote ) { if ( typeof remote . url === 'string' ) { url = remote . url ; } else if ( remote . url . length > 0 ) { url = await window . showQuickPick ( remote . url , { ignoreFocusOut : true , placeHolder : localize ( 'pick url' , "Choose a URL to clone from." ) } ) ; } } if ( ! url || ! options . branch ) { return url ; } if ( ! provider . getBranches ) { return { url } ; } const branches = await provider . getBranches ( url ) ; if ( ! branches ) { return { url } ; } const branch = await window . showQuickPick ( branches , { placeHolder : localize ( 'branch name' , "Branch name" ) } ) ; if ( ! branch ) { return { url } ; } return { url , branch } ; }