@@ -87,7 +87,12 @@ export class LocalizationWorkbenchContribution extends Disposable implements IWo
8787
8888 private checkAndInstall ( ) : void {
8989 const language = platform . language ;
90- const locale = platform . locale ;
90+ let locale = platform . locale ?? '' ;
91+ if ( locale . startsWith ( 'zh-hans' ) ) {
92+ locale = 'zh-cn' ;
93+ } else if ( locale . startsWith ( 'zh-hant' ) ) {
94+ locale = 'zh-tw' ;
95+ }
9196 const languagePackSuggestionIgnoreList = < string [ ] > JSON . parse ( this . storageService . get ( LANGUAGEPACK_SUGGESTION_IGNORE_STORAGE_KEY , StorageScope . APPLICATION , '[]' ) ) ;
9297
9398 if ( ! this . galleryService . isEnabled ( ) ) {
@@ -96,118 +101,121 @@ export class LocalizationWorkbenchContribution extends Disposable implements IWo
96101 if ( ! language || ! locale || locale === 'en' || locale . indexOf ( 'en-' ) === 0 ) {
97102 return ;
98103 }
99- if ( language === locale || languagePackSuggestionIgnoreList . indexOf ( locale ) > - 1 ) {
104+ if ( locale . startsWith ( language ) || languagePackSuggestionIgnoreList . includes ( locale ) ) {
100105 return ;
101106 }
102107
103- this . isLanguageInstalled ( locale )
104- . then ( installed => {
108+ this . isLocaleInstalled ( locale )
109+ . then ( async ( installed ) => {
105110 if ( installed ) {
106111 return ;
107112 }
108113
109- this . galleryService . query ( { text : `tag:lp-${ locale } ` } , CancellationToken . None ) . then ( tagResult => {
114+ let searchLocale = locale ;
115+ let tagResult = await this . galleryService . query ( { text : `tag:lp-${ searchLocale } ` } , CancellationToken . None ) ;
116+ if ( tagResult . total === 0 ) {
117+ // Trim the locale and try again.
118+ searchLocale = locale . split ( '-' ) [ 0 ] ;
119+ tagResult = await this . galleryService . query ( { text : `tag:lp-${ searchLocale } ` } , CancellationToken . None ) ;
110120 if ( tagResult . total === 0 ) {
111121 return ;
112122 }
123+ }
113124
114- const extensionToInstall = tagResult . total === 1 ? tagResult . firstPage [ 0 ] : tagResult . firstPage . filter ( e => e . publisher === 'MS-CEINTL' && e . name . indexOf ( 'vscode-language-pack' ) === 0 ) [ 0 ] ;
115- const extensionToFetchTranslationsFrom = extensionToInstall || tagResult . firstPage [ 0 ] ;
125+ const extensionToInstall = tagResult . total === 1 ? tagResult . firstPage [ 0 ] : tagResult . firstPage . find ( e => e . publisher === 'MS-CEINTL' && e . name . startsWith ( 'vscode-language-pack' ) ) ;
126+ const extensionToFetchTranslationsFrom = extensionToInstall ?? tagResult . firstPage [ 0 ] ;
116127
117- if ( ! extensionToFetchTranslationsFrom . assets . manifest ) {
118- return ;
119- }
128+ if ( ! extensionToFetchTranslationsFrom . assets . manifest ) {
129+ return ;
130+ }
120131
121- Promise . all ( [ this . galleryService . getManifest ( extensionToFetchTranslationsFrom , CancellationToken . None ) , this . galleryService . getCoreTranslation ( extensionToFetchTranslationsFrom , locale ) ] )
122- . then ( ( [ manifest , translation ] ) => {
123- const loc = manifest && manifest . contributes && manifest . contributes . localizations && manifest . contributes . localizations . filter ( x => x . languageId . toLowerCase ( ) === locale ) [ 0 ] ;
124- const languageName = loc ? ( loc . languageName || locale ) : locale ;
125- const languageDisplayName = loc ? ( loc . localizedLanguageName || loc . languageName || locale ) : locale ;
126- const translationsFromPack : { [ key : string ] : string } = translation ?. contents ?. [ 'vs/workbench/contrib/localization/electron-sandbox/minimalTranslations' ] ?? { } ;
127- const promptMessageKey = extensionToInstall ? 'installAndRestartMessage' : 'showLanguagePackExtensions' ;
128- const useEnglish = ! translationsFromPack [ promptMessageKey ] ;
132+ Promise . all ( [ this . galleryService . getManifest ( extensionToFetchTranslationsFrom , CancellationToken . None ) , this . galleryService . getCoreTranslation ( extensionToFetchTranslationsFrom , searchLocale ) ] )
133+ . then ( ( [ manifest , translation ] ) => {
134+ const loc = manifest && manifest . contributes && manifest . contributes . localizations && manifest . contributes . localizations . find ( x => locale . startsWith ( x . languageId . toLowerCase ( ) ) ) ;
135+ const languageName = loc ? ( loc . languageName || locale ) : locale ;
136+ const languageDisplayName = loc ? ( loc . localizedLanguageName || loc . languageName || locale ) : locale ;
137+ const translationsFromPack : { [ key : string ] : string } = translation ?. contents ?. [ 'vs/workbench/contrib/localization/electron-sandbox/minimalTranslations' ] ?? { } ;
138+ const promptMessageKey = extensionToInstall ? 'installAndRestartMessage' : 'showLanguagePackExtensions' ;
139+ const useEnglish = ! translationsFromPack [ promptMessageKey ] ;
129140
130- const translations : { [ key : string ] : string } = { } ;
131- Object . keys ( minimumTranslatedStrings ) . forEach ( key => {
132- if ( ! translationsFromPack [ key ] || useEnglish ) {
133- translations [ key ] = minimumTranslatedStrings [ key ] . replace ( '{0}' , languageName ) ;
134- } else {
135- translations [ key ] = `${ translationsFromPack [ key ] . replace ( '{0}' , languageDisplayName ) } (${ minimumTranslatedStrings [ key ] . replace ( '{0}' , languageName ) } )` ;
141+ const translations : { [ key : string ] : string } = { } ;
142+ Object . keys ( minimumTranslatedStrings ) . forEach ( key => {
143+ if ( ! translationsFromPack [ key ] || useEnglish ) {
144+ translations [ key ] = minimumTranslatedStrings [ key ] . replace ( '{0}' , languageName ) ;
145+ } else {
146+ translations [ key ] = `${ translationsFromPack [ key ] . replace ( '{0}' , languageDisplayName ) } (${ minimumTranslatedStrings [ key ] . replace ( '{0}' , languageName ) } )` ;
147+ }
148+ } ) ;
149+
150+ const logUserReaction = ( userReaction : string ) => {
151+ /* __GDPR__
152+ "languagePackSuggestion:popup" : {
153+ "owner": "TylerLeonhardt",
154+ "userReaction" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
155+ "language": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
136156 }
137- } ) ;
157+ */
158+ this . telemetryService . publicLog ( 'languagePackSuggestion:popup' , { userReaction, language : locale } ) ;
159+ } ;
160+
161+ const searchAction = {
162+ label : translations [ 'searchMarketplace' ] ,
163+ run : ( ) => {
164+ logUserReaction ( 'search' ) ;
165+ this . paneCompositeService . openPaneComposite ( EXTENSIONS_VIEWLET_ID , ViewContainerLocation . Sidebar , true )
166+ . then ( viewlet => viewlet ?. getViewPaneContainer ( ) as IExtensionsViewPaneContainer )
167+ . then ( viewlet => {
168+ viewlet . search ( `tag:lp-${ searchLocale } ` ) ;
169+ viewlet . focus ( ) ;
170+ } ) ;
171+ }
172+ } ;
138173
139- const logUserReaction = ( userReaction : string ) => {
140- /* __GDPR__
141- "languagePackSuggestion:popup" : {
142- "owner": "TylerLeonhardt",
143- "userReaction" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
144- "language": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
145- }
146- */
147- this . telemetryService . publicLog ( 'languagePackSuggestion:popup' , { userReaction, language : locale } ) ;
148- } ;
174+ const installAndRestartAction = {
175+ label : translations [ 'installAndRestart' ] ,
176+ run : ( ) => {
177+ logUserReaction ( 'installAndRestart' ) ;
178+ this . installExtension ( extensionToInstall ! ) . then ( ( ) => this . hostService . restart ( ) ) ;
179+ }
180+ } ;
149181
150- const searchAction = {
151- label : translations [ 'searchMarketplace' ] ,
152- run : ( ) => {
153- logUserReaction ( 'search' ) ;
154- this . paneCompositeService . openPaneComposite ( EXTENSIONS_VIEWLET_ID , ViewContainerLocation . Sidebar , true )
155- . then ( viewlet => viewlet ?. getViewPaneContainer ( ) as IExtensionsViewPaneContainer )
156- . then ( viewlet => {
157- viewlet . search ( `tag:lp-${ locale } ` ) ;
158- viewlet . focus ( ) ;
159- } ) ;
160- }
161- } ;
182+ const promptMessage = translations [ promptMessageKey ] ;
162183
163- const installAndRestartAction = {
164- label : translations [ 'installAndRestart' ] ,
184+ this . notificationService . prompt (
185+ Severity . Info ,
186+ promptMessage ,
187+ [ extensionToInstall ? installAndRestartAction : searchAction ,
188+ {
189+ label : localize ( 'neverAgain' , "Don't Show Again" ) ,
190+ isSecondary : true ,
165191 run : ( ) => {
166- logUserReaction ( 'installAndRestart' ) ;
167- this . installExtension ( extensionToInstall ) . then ( ( ) => this . hostService . restart ( ) ) ;
192+ languagePackSuggestionIgnoreList . push ( locale ) ;
193+ this . storageService . store (
194+ LANGUAGEPACK_SUGGESTION_IGNORE_STORAGE_KEY ,
195+ JSON . stringify ( languagePackSuggestionIgnoreList ) ,
196+ StorageScope . APPLICATION ,
197+ StorageTarget . USER
198+ ) ;
199+ logUserReaction ( 'neverShowAgain' ) ;
168200 }
169- } ;
170-
171- const promptMessage = translations [ promptMessageKey ] ;
172-
173- this . notificationService . prompt (
174- Severity . Info ,
175- promptMessage ,
176- [ extensionToInstall ? installAndRestartAction : searchAction ,
177- {
178- label : localize ( 'neverAgain' , "Don't Show Again" ) ,
179- isSecondary : true ,
180- run : ( ) => {
181- languagePackSuggestionIgnoreList . push ( locale ) ;
182- this . storageService . store (
183- LANGUAGEPACK_SUGGESTION_IGNORE_STORAGE_KEY ,
184- JSON . stringify ( languagePackSuggestionIgnoreList ) ,
185- StorageScope . APPLICATION ,
186- StorageTarget . USER
187- ) ;
188- logUserReaction ( 'neverShowAgain' ) ;
189- }
190- } ] ,
191- {
192- onCancel : ( ) => {
193- logUserReaction ( 'cancelled' ) ;
194- }
201+ } ] ,
202+ {
203+ onCancel : ( ) => {
204+ logUserReaction ( 'cancelled' ) ;
195205 }
196- ) ;
197-
198- } ) ;
199- } ) ;
206+ }
207+ ) ;
208+ } ) ;
200209 } ) ;
201-
202210 }
203211
204- private async isLanguageInstalled ( language : string | undefined ) : Promise < boolean > {
212+ private async isLocaleInstalled ( locale : string ) : Promise < boolean > {
205213 const installed = await this . extensionManagementService . getInstalled ( ) ;
206214 return installed . some ( i => ! ! ( i . manifest
207215 && i . manifest . contributes
208216 && i . manifest . contributes . localizations
209217 && i . manifest . contributes . localizations . length
210- && i . manifest . contributes . localizations . some ( l => l . languageId . toLowerCase ( ) === language ) ) ) ;
218+ && i . manifest . contributes . localizations . some ( l => locale . startsWith ( l . languageId . toLowerCase ( ) ) ) ) ) ;
211219 }
212220
213221 private installExtension ( extension : IGalleryExtension ) : Promise < void > {
0 commit comments