提交 91198d94 编写于 作者: R Rob Lourens

Request settings for new extensions

上级 1c6d46db
......@@ -111,7 +111,7 @@ export class PreferencesEditor extends BaseEditor {
private preferencesRenderers: PreferencesRenderersController;
private delayedFilterLogging: Delayer<void>;
private remoteSearchThrottle: ThrottledDelayer<IFilterOrSearchResult>;
private remoteSearchThrottle: ThrottledDelayer<void>;
private _lastReportedFilter: string;
private lastFocusedWidget: SearchWidget | SideBySidePreferencesWidget = null;
......@@ -243,18 +243,18 @@ export class PreferencesEditor extends BaseEditor {
TPromise.join([
this.preferencesRenderers.localFilterPreferences(query),
this.triggerThrottledSearch(query)
]).then(results => {
if (results) {
const [localResult, remoteResult] = results;
]).then(() => {
const result = this.preferencesRenderers.lastFilterResult;
if (result) {
this.delayedFilterLogging.trigger(() => this.reportFilteringUsed(
query,
remoteResult ? remoteResult.defaultSettingsGroupCounts : localResult.defaultSettingsGroupCounts,
remoteResult && remoteResult.metadata));
result.defaultSettingsGroupCounts,
result.metadata));
}
});
}
private triggerThrottledSearch(query: string): TPromise<IFilterOrSearchResult> {
private triggerThrottledSearch(query: string): TPromise<void> {
if (query) {
return this.remoteSearchThrottle.trigger(() => this.preferencesRenderers.remoteSearchPreferences(query));
} else {
......@@ -366,11 +366,13 @@ class PreferencesRenderersController extends Disposable {
private _editablePreferencesRendererDisposables: IDisposable[] = [];
private _settingsNavigator: SettingsNavigator;
private _filtersInProgress: TPromise<IFilterResult>[];
private _remoteFiltersInProgress: TPromise<any>[];
private _currentLocalSearchProvider: ISearchProvider;
private _currentRemoteSearchProvider: ISearchProvider;
private _currentNewExtensionsSearchProvider: ISearchProvider;
private _lastQuery: string;
private _lastFilterResult: IFilterOrSearchResult;
private _onDidFilterResultsCountChange: Emitter<number> = this._register(new Emitter<number>());
public onDidFilterResultsCountChange: Event<number> = this._onDidFilterResultsCountChange.event;
......@@ -382,6 +384,10 @@ class PreferencesRenderersController extends Disposable {
super();
}
get lastFilterResult(): IFilterOrSearchResult {
return this._lastFilterResult;
}
get defaultPreferencesRenderer(): IPreferencesRenderer<ISetting> {
return this._defaultPreferencesRenderer;
}
......@@ -415,34 +421,48 @@ class PreferencesRenderersController extends Disposable {
}
}
async _onEditableContentDidChange(): TPromise<void> {
private async _onEditableContentDidChange(): TPromise<void> {
await this.localFilterPreferences(this._lastQuery, true);
await this.remoteSearchPreferences(this._lastQuery, true);
}
remoteSearchPreferences(query: string, updateCurrentResults?: boolean): TPromise<IFilterOrSearchResult> {
remoteSearchPreferences(query: string, updateCurrentResults?: boolean): TPromise<void> {
if (this._remoteFiltersInProgress) {
// Resolved/rejected promises have no .cancel()
this._remoteFiltersInProgress.forEach(p => p.cancel && p.cancel());
}
this._currentRemoteSearchProvider = (updateCurrentResults && this._currentRemoteSearchProvider) || this.preferencesSearchService.getRemoteSearchProvider(query);
return this.filterOrSearchPreferences(query, this._currentRemoteSearchProvider, 'nlpResult', nls.localize('nlpResult', "Natural Language Results"));
this._currentNewExtensionsSearchProvider = (updateCurrentResults && this._currentNewExtensionsSearchProvider) || this.preferencesSearchService.getRemoteSearchProvider(query, true);
this._remoteFiltersInProgress = [
this.filterOrSearchPreferences(query, this._currentNewExtensionsSearchProvider, 'newExtensionsResult', nls.localize('newExtensionsResult', "Other Extension Results")),
this.filterOrSearchPreferences(query, this._currentRemoteSearchProvider, 'nlpResult', nls.localize('nlpResult', "Natural Language Results"))
];
return TPromise.join(this._remoteFiltersInProgress).then(() => {
this._remoteFiltersInProgress = null;
}, err => {
if (isPromiseCanceledError(err)) {
return null;
} else {
onUnexpectedError(err);
}
});
}
localFilterPreferences(query: string, updateCurrentResults?: boolean): TPromise<IFilterOrSearchResult> {
localFilterPreferences(query: string, updateCurrentResults?: boolean): TPromise<void> {
this._currentLocalSearchProvider = (updateCurrentResults && this._currentLocalSearchProvider) || this.preferencesSearchService.getLocalSearchProvider(query);
return this.filterOrSearchPreferences(query, this._currentLocalSearchProvider, 'filterResult', nls.localize('filterResult', "Filtered Results"));
}
filterOrSearchPreferences(query: string, searchProvider: ISearchProvider, groupId: string, groupLabel: string): TPromise<IFilterOrSearchResult> {
private filterOrSearchPreferences(query: string, searchProvider: ISearchProvider, groupId: string, groupLabel: string): TPromise<void> {
this._lastQuery = query;
if (this._filtersInProgress) {
// Resolved/rejected promises have no .cancel()
this._filtersInProgress.forEach(p => p.cancel && p.cancel());
}
this._filtersInProgress = [
return TPromise.join([
this._filterOrSearchPreferences(query, this.defaultPreferencesRenderer, searchProvider, groupId, groupLabel),
this._filterOrSearchPreferences(query, this.editablePreferencesRenderer, searchProvider, groupId, groupLabel)];
return TPromise.join(this._filtersInProgress).then(results => {
this._filtersInProgress = null;
this._filterOrSearchPreferences(query, this.editablePreferencesRenderer, searchProvider, groupId, groupLabel)]
).then(results => {
const [defaultFilterResult, editableFilterResult] = results;
this.consolidateAndUpdate(defaultFilterResult, editableFilterResult);
......@@ -451,13 +471,7 @@ class PreferencesRenderersController extends Disposable {
defaultSettingsGroupCounts: defaultFilterResult && this._countById(defaultFilterResult.filteredGroups)
};
return result;
}, err => {
if (isPromiseCanceledError(err)) {
return null;
} else {
onUnexpectedError(err);
}
this._lastFilterResult = result;
});
}
......
......@@ -177,7 +177,7 @@ export interface IPreferencesSearchService {
_serviceBrand: any;
getLocalSearchProvider(filter: string): ISearchProvider;
getRemoteSearchProvider(filter: string): ISearchProvider;
getRemoteSearchProvider(filter: string, newExtensionsOnly?: boolean): ISearchProvider;
}
export interface ISearchProvider {
......
......@@ -67,8 +67,8 @@ export class PreferencesSearchService extends Disposable implements IPreferences
}
}
getRemoteSearchProvider(filter: string): RemoteSearchProvider {
return this.remoteSearchAllowed && this.instantiationService.createInstance(RemoteSearchProvider, filter, this._endpoint, this._installedExtensions);
getRemoteSearchProvider(filter: string, newExtensionsOnly = false): RemoteSearchProvider {
return this.remoteSearchAllowed && this.instantiationService.createInstance(RemoteSearchProvider, filter, this._endpoint, this._installedExtensions, newExtensionsOnly);
}
getLocalSearchProvider(filter: string): LocalSearchProvider {
......@@ -117,7 +117,7 @@ export class RemoteSearchProvider implements ISearchProvider {
private _filter: string;
private _remoteSearchP: TPromise<IFilterMetadata>;
constructor(filter: string, endpoint: IEndpointDetails, private installedExtensions: TPromise<ILocalExtension[]>,
constructor(filter: string, private endpoint: IEndpointDetails, private installedExtensions: TPromise<ILocalExtension[]>, private newExtensionsOnly: boolean,
@IEnvironmentService private environmentService: IEnvironmentService,
@IRequestService private requestService: IRequestService,
) {
......@@ -125,7 +125,7 @@ export class RemoteSearchProvider implements ISearchProvider {
// @queries are always handled by local filter
this._remoteSearchP = filter && !strings.startsWith(filter, '@') ?
this.getSettingsFromBing(filter, endpoint) :
this.getSettingsFromBing(filter) :
TPromise.wrap(null);
}
......@@ -148,15 +148,15 @@ export class RemoteSearchProvider implements ISearchProvider {
});
}
private getSettingsFromBing(filter: string, endpoint: IEndpointDetails): TPromise<IFilterMetadata> {
private getSettingsFromBing(filter: string): TPromise<IFilterMetadata> {
const start = Date.now();
return this.prepareUrl(filter, endpoint, this.environmentService.settingsSearchBuildId).then(url => {
return this.prepareUrl(filter).then(url => {
return this.requestService.request({
url,
headers: {
'User-Agent': 'request',
'Content-Type': 'application/json; charset=utf-8',
'api-key': endpoint.key
'api-key': this.endpoint.key
},
timeout: 5000
}).then(context => {
......@@ -205,7 +205,7 @@ export class RemoteSearchProvider implements ISearchProvider {
};
}
private prepareUrl(query: string, endpoint: IEndpointDetails, buildNumber: number): TPromise<string> {
private prepareUrl(query: string): TPromise<string> {
query = escapeSpecialChars(query);
const boost = 10;
const userQuery = `(${query})^${boost}`;
......@@ -214,41 +214,55 @@ export class RemoteSearchProvider implements ISearchProvider {
query = query.replace(/\ +/g, '~ ') + '~';
const encodedQuery = encodeURIComponent(userQuery + ' || ' + query);
let url = `${endpoint.urlBase}?`;
let url = `${this.endpoint.urlBase}?`;
return this.installedExtensions.then(exts => {
if (endpoint.key) {
url += `${API_VERSION}`;
url += `&search=${encodedQuery}`;
const filters = exts.map(ext => {
const uuid = ext.identifier.uuid;
const versionString = ext.manifest.version
.split('.')
.map(versionPart => strings.pad(<any>versionPart, 10))
.join('');
return `(packageid eq '${uuid}' and startbuildno le '${versionString}' and endbuildno ge '${versionString}')`;
});
const buildNumber = this.environmentService.settingsSearchBuildId;
if (this.endpoint.key) {
url += `${API_VERSION}&${QUERY_TYPE}`;
url += `&search=${encodedQuery}`;
if (buildNumber) {
filters.push(`(packageid eq 'core' and startbuildno le '${buildNumber}' and endbuildno ge '${buildNumber}')`);
url += `&$filter=${filters.join(' or ')}`;
}
if (this.newExtensionsOnly) {
return TPromise.wrap(url);
} else {
url += `query=${encodedQuery}`;
return this.getVersionAndExtensionFilters(buildNumber).then(filters => {
url += `&$filter=${filters.join(' or ')}`;
return url;
});
}
} else {
url += `query=${encodedQuery}`;
if (buildNumber) {
url += `&build=${buildNumber}`;
}
if (buildNumber) {
url += `&build=${buildNumber}`;
}
}
return TPromise.wrap(url);
}
private getVersionAndExtensionFilters(buildNumber?: number): TPromise<string[]> {
return this.installedExtensions.then(exts => {
const filters = exts.map(ext => {
const uuid = ext.identifier.uuid;
const versionString = ext.manifest.version
.split('.')
.map(versionPart => strings.pad(<any>versionPart, 10))
.join('');
return `(packageid eq '${uuid}' and startbuildno le '${versionString}' and endbuildno ge '${versionString}')`;
});
if (buildNumber) {
filters.push(`(packageid eq 'core' and startbuildno le '${buildNumber}' and endbuildno ge '${buildNumber}')`);
}
return url;
return filters;
});
}
}
const API_VERSION = 'api-version=2016-09-01-Preview';
const QUERY_TYPE = 'querytype=full';
function escapeSpecialChars(query: string): string {
return query.replace(/\./g, ' ')
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册