1+ const LANGUAGE_NAMES : Record < string , string > = {
2+ en : 'English' , zh : 'Chinese' , ja : 'Japanese' , ko : 'Korean' , de : 'German' , fr : 'French' , es : 'Spanish' , it : 'Italian' , pt : 'Portuguese' , ru : 'Russian' , ar : 'Arabic' , hi : 'Hindi' , th : 'Thai' , vi : 'Vietnamese' , id : 'Indonesian' , nl : 'Dutch' , sv : 'Swedish' , pl : 'Polish' , tr : 'Turkish' , he : 'Hebrew' , cs : 'Czech' , hu : 'Hungarian' , ro : 'Romanian' , sk : 'Slovak' , uk : 'Ukrainian' , el : 'Greek' , nb : 'Norwegian' , da : 'Danish' , fi : 'Finnish'
3+ } ;
4+ const COUNTRY_NAMES : Record < string , string > = {
5+ US : 'United States' , GB : 'United Kingdom' , CN : 'China' , TW : 'Taiwan' , HK : 'Hong Kong' , JP : 'Japan' , KR : 'South Korea' , DE : 'Germany' , FR : 'France' , ES : 'Spain' , IT : 'Italy' , BR : 'Brazil' , PT : 'Portugal' , RU : 'Russia' , SA : 'Saudi Arabia' , IN : 'India' , TH : 'Thailand' , VN : 'Vietnam' , ID : 'Indonesia' , NL : 'Netherlands' , SE : 'Sweden' , PL : 'Poland' , TR : 'Turkey' , IL : 'Israel' , CZ : 'Czech Republic' , HU : 'Hungary' , RO : 'Romania' , SK : 'Slovakia' , UA : 'Ukraine' , GR : 'Greece' , NO : 'Norway' , DK : 'Denmark' , FI : 'Finland' , MX : 'Mexico' , CA : 'Canada' , AU : 'Australia' , NZ : 'New Zealand' , IE : 'Ireland' , SG : 'Singapore'
6+ } ;
17const browserUtils = {
28
39 isBrowser : ( ) => typeof window !== 'undefined' ,
@@ -44,8 +50,16 @@ const browserUtils = {
4450 return window . getSelection ( ) . toString ( ) ;
4551 } ,
4652
47- async getPublicIP ( ) : Promise < any > {
48- return fetch ( 'https://api.ipify.org?format=json' )
53+ async getPublicIP ( ) : Promise < string > {
54+ try {
55+ const r : any = await Http . get ( 'https://api.ipify.org?format=json' , { timeoutMs : 3000 , retry : 2 } ) ;
56+ if ( r && typeof r . ip === 'string' ) return r . ip ;
57+ } catch { }
58+ try {
59+ const r : any = await Http . get ( 'https://api.myip.com' , { timeoutMs : 3000 , retry : 2 } ) ;
60+ if ( r && typeof r . ip === 'string' ) return r . ip ;
61+ } catch { }
62+ return '' ;
4963 } ,
5064
5165 async copyToClipboard ( text : string ) : Promise < boolean > {
@@ -181,8 +195,27 @@ const browserUtils = {
181195 window . addEventListener ( 'resize' , fn ) ;
182196 fn ( ) ;
183197 return ( ) => window . removeEventListener ( 'resize' , fn ) ;
198+ } ,
199+
200+ getLocaleInfo ( locale ?: string ) : { code : string ; language : { code : string ; name : string } ; country : { code ?: string ; name ?: string } } {
201+ const raw = ( locale || ( this as any ) . getPreferredLocale ( ) ) . replace ( '_' , '-' ) ;
202+ const parts = raw . split ( '-' ) ;
203+ const lang = ( parts [ 0 ] || '' ) . toLowerCase ( ) ;
204+ const region = parts [ 1 ] ? parts [ 1 ] . toUpperCase ( ) : undefined ;
205+ const languageName = LANGUAGE_NAMES [ lang ] || lang ;
206+ const countryName = region ? ( COUNTRY_NAMES [ region ! ] || region ) : undefined ;
207+ return { code : region ? `${ lang } -${ region } ` : lang , language : { code : lang , name : languageName } , country : { code : region , name : countryName } } ;
208+ } ,
209+
210+ getCommonLocaleTable ( ) : { code : string ; language : string ; country : string } [ ] {
211+ const codes = [ 'zh-CN' , 'zh-TW' , 'zh-HK' , 'en-US' , 'en-GB' , 'ja-JP' , 'ko-KR' , 'de-DE' , 'fr-FR' , 'es-ES' , 'it-IT' , 'pt-BR' , 'pt-PT' , 'ru-RU' , 'ar-SA' , 'hi-IN' , 'th-TH' , 'vi-VN' , 'id-ID' , 'nl-NL' , 'sv-SE' , 'pl-PL' , 'tr-TR' , 'he-IL' , 'cs-CZ' , 'hu-HU' , 'ro-RO' , 'sk-SK' , 'uk-UA' , 'el-GR' , 'nb-NO' , 'da-DK' , 'fi-FI' , 'es-MX' , 'en-CA' , 'en-AU' , 'en-NZ' , 'en-IE' , 'zh-SG' ] ;
212+ return codes . map ( ( c ) => {
213+ const info = ( this as any ) . getLocaleInfo ( c ) ;
214+ return { code : info . code , language : info . language . name , country : info . country . name || '' } ;
215+ } ) ;
184216 }
185217
186218}
187219
188- export default browserUtils
220+ export default browserUtils
221+ import Http from './Http'
0 commit comments