1/* 2* Copyright (c) 2024 Huawei Device Co., Ltd. 3* Licensed under the Apache License, Version 2.0 (the "License"); 4* you may not use this file except in compliance with the License. 5* You may obtain a copy of the License at 6* 7* http://www.apache.org/licenses/LICENSE-2.0 8* 9* Unless required by applicable law or agreed to in writing, software 10* distributed under the License is distributed on an "AS IS" BASIS, 11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12* See the License for the specific language governing permissions and 13* limitations under the License. 14*/ 15import common from '@ohos.app.ability.common'; 16import display from '@ohos.display'; 17import settings from '@ohos.settings'; 18import UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession'; 19import deviceInfo from '@ohos.deviceInfo'; 20import { BusinessError } from '@ohos.base'; 21import { EditableLeftIconType, EditableTitleBar } from '@ohos.arkui.advanced.EditableTitleBar'; 22import mediaQuery from '@ohos.mediaquery'; 23import ConfigurationConstant from '@ohos.app.ability.ConfigurationConstant'; 24import CommonConstants, { FontSizeScale } from '../common/constants/CommonConstants'; 25import { logger } from '../utils/Logger'; 26import { TipsJumpUtils } from '../utils/TipsJumpUtils'; 27import systemParameterEnhance from '@ohos.systemParameterEnhance'; 28import i18n from '@ohos.i18n'; 29import { LengthMetrics } from '@ohos.arkui.node'; 30import { DeviceUtil } from '../utils/DeviceUtil'; 31 32const TAG = '[ContinueSwitch_Page] : '; 33let context = getContext(this) as common.UIAbilityContext; 34let localStorage = LocalStorage.getShared(); 35 36interface switchStatus { 37 open: string; 38 close: string; 39} 40 41let switchState: switchStatus = { 42 open: CommonConstants.SWITCH_STATUS_OPEN, 43 close: CommonConstants.SWITCH_STATUS_CLOSE 44} 45 46@Entry(localStorage) 47@Component 48struct ContinueSwitch { 49 @StorageLink('isSwitchOn') isSwitchOn: boolean | undefined = true; 50 @StorageLink('continueSession') continueSession: UIExtensionContentSession | undefined = undefined; 51 @State title: string = ''; 52 @State screenHeight: number = 0; 53 @State screenWidth: number = 0; 54 @State shortSideSize: number = 0; 55 @State imageAnimatorHeight: number = this.getImageAnimatorHeight(); 56 @State imageAnimatorWidth: number = this.getImageAnimatorWidth(); 57 @State textWidth: number = 0; 58 @State gapLength: number = 0; 59 @State isShow: boolean = false; 60 @State is2in1: boolean = false; 61 @State portraitFunc: mediaQuery.MediaQueryResult | void | null = null; 62 @State isVideoVisible: Visibility = Visibility.Hidden; 63 @State contentHeight: number = 0; 64 @State imageArray: Array<ImageFrameInfo> = []; 65 @State animationState: AnimationStatus = AnimationStatus.Running; 66 @State reverse: boolean = false; 67 @State iterations: number = -1; 68 @State isEnabled: boolean = true; 69 @State isShowBack: boolean = true; 70 @State isAnimatorDone: boolean = false; 71 @StorageProp('currentFontSizeScale') @Watch('onFontSizeScaleChange') fontSizeScale: number = 1; 72 @State phoneSwitchTextTopMargin: string = '17vp'; 73 @State phoneSwitchTextBottomMargin: string = '18vp'; 74 @State titleBarMargin: LocalizedMargin = { 75 start: LengthMetrics.resource($r('sys.float.margin_left')), 76 } 77 @State titleBarMarginPc: LocalizedMargin = { 78 start: LengthMetrics.vp(16), 79 } 80 @State paddingStartNormal: LengthMetrics = LengthMetrics.resource($r('sys.float.margin_left')); 81 @State paddingStartPc: LengthMetrics = LengthMetrics.vp(16); 82 @State isBacked: boolean = false; 83 private listener: mediaQuery.MediaQueryListener = mediaQuery.matchMediaSync('(dark-mode:true)'); 84 private extContext?: common.UIExtensionContext; 85 private scroller: Scroller = new Scroller(); 86 private learnMore: ResourceStr = $r('app.string.learn_more'); 87 private continueDesc: ResourceStr = $r('app.string.continue_desc_text', ''); 88 private startReason?: string = ''; 89 private isSmallFoldProduct: boolean = DeviceUtil.isSmallFoldProduct(); 90 91 onPortrait(mediaQueryResult: mediaQuery.MediaQueryResult): void { 92 logger.info(`${TAG} 'onPortrait in`); 93 if (mediaQueryResult.matches as boolean) { 94 this.extContext?.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_DARK); 95 } else { 96 this.extContext?.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT); 97 } 98 } 99 100 onFontSizeScaleChange(): void { 101 logger.info(`${TAG} onFontSizeScaleChange`); 102 this.phoneSwitchTextTopMargin = this.UpdateMarginBasedOnFontSize(17, this.fontSizeScale); 103 this.phoneSwitchTextBottomMargin = this.UpdateMarginBasedOnFontSize(18, this.fontSizeScale); 104 } 105 106 /** 107 * Update the margins of the switch list according to the font size. 108 */ 109 public UpdateMarginBasedOnFontSize(fontFp: number, fontSizeScale: number): string { 110 logger.info(`${TAG} getlistSpace, fontSizeScale: ${fontSizeScale} ; fontFp: ${fontFp}`); 111 switch (fontSizeScale) { 112 case FontSizeScale.XXL1: 113 return '16vp'; 114 case FontSizeScale.XXL2: 115 return '20vp'; 116 case FontSizeScale.XXL3: 117 return '24vp'; 118 default: 119 return `${fontFp}vp`; 120 } 121 } 122 123 /** 124 * Initialize the switch list spacing size 125 */ 126 public phoneSwitchTextMarginInit(): void { 127 let fontSizeScale = parseFloat(systemParameterEnhance.getSync(CommonConstants.FONT_SIZE_SCALE_PARAM, '1')); 128 this.phoneSwitchTextTopMargin = this.UpdateMarginBasedOnFontSize(17, fontSizeScale); 129 this.phoneSwitchTextBottomMargin = this.UpdateMarginBasedOnFontSize(18, fontSizeScale); 130 } 131 132 getStringSync(): void { 133 logger.info(`${TAG} getStringSync in`); 134 try { 135 context.resourceManager.getStringValue($r('app.string.continue_title') 136 .id, (error: BusinessError, value: string) => { 137 if (error != null) { 138 logger.error(TAG + 'error is ' + error); 139 } else { 140 this.title = value; 141 logger.info(`${TAG} <aboutToAppear> this.title : ${this.title}`); 142 } 143 }) 144 } catch (error) { 145 let code: number = (error as BusinessError).code; 146 let message: string = (error as BusinessError).message; 147 logger.error(`${TAG} callback getStringValue failed,error code: ${code},message: ${message}.`); 148 } 149 } 150 151 getImageArray(): void { 152 logger.info(`${TAG} getImageArray in`); 153 if (deviceInfo.deviceType === '2in1') { 154 for (let i = 0; i <= CommonConstants.IMAGE_COUNT; ++i) { 155 this.imageArray.push({ 156 src: $r(`app.media.continuePC_${i}`), 157 duration: (i == CommonConstants.IMAGE_COUNT) ? CommonConstants.IMG_ANIMATOR_OVER_DURATION 158 : CommonConstants.IMG_ANIMATOR_NORMAL_DURATION 159 }) 160 } 161 } else { 162 for (let i = 0; i <= CommonConstants.IMAGE_COUNT; ++i) { 163 this.imageArray.push({ 164 src: $r(`app.media.continue_${i}`), 165 duration: (i == CommonConstants.IMAGE_COUNT) ? CommonConstants.IMG_ANIMATOR_OVER_DURATION 166 : CommonConstants.IMG_ANIMATOR_NORMAL_DURATION 167 }) 168 } 169 } 170 } 171 172 getGapLength(): void { 173 logger.info(`${TAG} getGapLength in, deviceInfo.deviceType : ${deviceInfo.deviceType}`); 174 if (deviceInfo.deviceType == 'phone') { 175 this.gapLength = CommonConstants.GENERAL_PHONE_GAP_LENGTH; 176 } else if (deviceInfo.deviceType == '2in1' || deviceInfo.deviceType == 'tablet') { 177 this.gapLength = CommonConstants.PC_PAD_GAP_LENGTH; 178 } 179 logger.info(`${TAG} this.gapLength : ${this.gapLength}`); 180 } 181 182 initSwitchStatus(): void { 183 logger.info(`${TAG} initSwitchStatus in`); 184 try { 185 let value = settings.getValueSync(context, CommonConstants.CONTINUE_SWITCH_KEY, switchState.open, 186 settings.domainName.USER_SECURITY); 187 this.isSwitchOn = value != switchState.close ? true : false; 188 logger.info(`${TAG} <initSwitchStatus> this.isSwitchOn : ${this.isSwitchOn}; value: ${value}`); 189 190 AppStorage.setOrCreate('isSwitchOn', this.isSwitchOn); 191 logger.info(`${TAG} AppStorage.get<boolean>(isSwitchOn) : ${AppStorage.get<boolean>('isSwitchOn')}`); 192 193 if (this.isSwitchOn) { 194 let status: boolean = settings.setValueSync(context, CommonConstants.CONTINUE_SWITCH_KEY, switchState.open, 195 settings.domainName.USER_SECURITY); 196 logger.info(`${TAG} set value success :${status}; set:Continue_Switch_Status is 1`); 197 } 198 } catch (error) { 199 logger.error(`${TAG} settings set or get failed. error.message: ${error.message}`); 200 } 201 } 202 203 onPageShow() { 204 logger.info(`${TAG} onPageShow in`); 205 this.getGapLength(); 206 display.getAllDisplays((err, data) => { 207 this.screenWidth = px2vp(data[0].width); 208 this.screenHeight = px2vp(data[0].height); 209 this.contentHeight = this.screenHeight; 210 logger.info(`${TAG} screenWidth = ${this.screenWidth}; screenHeight = ${this.screenHeight}`); 211 }) 212 this.is2in1 = deviceInfo.deviceType === '2in1' ? true : false; 213 } 214 215 aboutToAppear() { 216 logger.info(`${TAG} aboutToAppear in`); 217 this.initSwitchStatus(); 218 this.getStringSync(); 219 this.getImageArray(); 220 this.listener.on('change', (mediaQueryResult: mediaQuery.MediaQueryResult) => { 221 this.onPortrait(mediaQueryResult); 222 }) 223 this.registerFoldChangeListener(); 224 this.extContext = localStorage.get<common.UIExtensionContext>('context'); 225 this.startReason = AppStorage.get<string>('startReason'); 226 this.isShowBack = AppStorage.get<boolean>('isShowBack') ?? true; 227 logger.info(`${TAG} aboutToAppear: startReason is ${this.startReason}, isShowBack: ${this.isShowBack}`); 228 this.phoneSwitchTextMarginInit(); 229 setTimeout(() => { 230 this.isAnimatorDone = true; 231 }, 20) 232 } 233 234 aboutToDisappear() { 235 logger.info(`${TAG} aboutToDisappear in`); 236 this.unRegisterFoldChangeListener(); 237 } 238 239 onBackPress() { 240 logger.info(`${TAG} onBackPress in`); 241 } 242 243 @Builder 244 NormalRootContent() { 245 this.titleBar(); 246 this.ContentBuilder(); 247 } 248 249 @Builder 250 SearchRootContent() { 251 NavDestination() { 252 this.ContentBuilder(); 253 } 254 .hideTitleBar(false) 255 .title(this.title, { 256 paddingStart: this.is2in1 ? this.paddingStartPc : this.paddingStartNormal, 257 }) 258 .backgroundColor($r('sys.color.ohos_id_color_titlebar_sub_bg')) 259 } 260 261 @Builder 262 titleBar() { 263 Column() { 264 EditableTitleBar({ 265 leftIconStyle: EditableLeftIconType.Back, 266 title: $r('app.string.continue_title'), 267 isSaveIconRequired: false, 268 contentMargin: this.is2in1 ? this.titleBarMarginPc : this.titleBarMargin, 269 onCancel: () => { 270 logger.info(`${TAG} onCancel in.`); 271 if (this.isBacked) { 272 logger.info(`${TAG} onCancel: The back button has been clicked.`); 273 return; 274 } 275 try { 276 if (this.continueSession) { 277 this.continueSession.sendData({ 'action': 'pop' }); 278 this.isBacked = true; 279 } else { 280 logger.error(`${TAG} continueSession is undefined`); 281 } 282 } catch (error) { 283 logger.error(`${TAG} continueSession sendData failed. error.message: ${error.message}`); 284 } 285 } 286 }) 287 } 288 } 289 290 @Builder 291 ContentBuilder() { 292 Scroll(this.scroller) { 293 Column() { 294 ImageAnimator() 295 .images(this.imageArray) 296 .state(this.animationState) 297 .reverse(this.reverse) 298 .fillMode(this.iterations) 299 .iterations(this.iterations) 300 .width(this.imageAnimatorWidth) 301 .height(this.imageAnimatorHeight) 302 .onStart(() => { 303 logger.info(`${TAG} ImageAnimator Start`); 304 }) 305 .onFinish(() => { 306 logger.info(`${TAG} ImageAnimator Finish`); 307 }) 308 309 Text() { 310 Span(this.continueDesc) 311 .fontFamily('HarmonyHeiTi') 312 .fontSize($r('sys.float.ohos_id_text_size_body2')) 313 .fontColor($r('sys.color.ohos_id_color_text_secondary')) 314 .fontWeight(FontWeight.Regular) 315 Span(this.learnMore) 316 .fontFamily('HarmonyHeiTi') 317 .fontSize($r('sys.float.ohos_id_text_size_body2')) 318 .fontColor($r('sys.color.ohos_id_color_text_primary_activated')) 319 .fontWeight(FontWeight.Medium) 320 .onClick(() => { 321 TipsJumpUtils.jumpTips(getContext(this) as common.UIAbilityContext, CommonConstants.FUN_NUM, 322 CommonConstants.TIPS_TYPE); 323 }) 324 } 325 .margin({ 326 bottom: CommonConstants.CONTINUE_DESC_TEXT_MARGIN_BOTTOM, 327 top: CommonConstants.CONTINUE_DESC_TEXT_MARGIN_TOP, 328 left: $r('app.float.margin_8'), 329 right: $r('app.float.margin_8') 330 }) 331 .textAlign(TextAlign.Center) 332 .width('100%') 333 334 Column() { 335 Flex({ 336 direction: FlexDirection.Row, 337 justifyContent: FlexAlign.SpaceBetween, 338 alignItems: ItemAlign.Center 339 }) { 340 Text($r('app.string.continue_title')) 341 .fontSize($r('sys.float.ohos_id_text_size_sub_title2')) 342 .fontWeight(FontWeight.Medium) 343 .fontColor($r('sys.color.ohos_id_color_text_primary')) 344 .accessibilityLevel('no') 345 .padding({ 346 top: this.is2in1 ? CommonConstants.ITEM_LIST_PADDING_TOP_PC : this.phoneSwitchTextTopMargin, 347 bottom: this.is2in1 ? CommonConstants.ITEM_LIST_PADDING_BOTTOM_PC : this.phoneSwitchTextBottomMargin 348 }) 349 350 Toggle({ type: ToggleType.Switch, isOn: this.isSwitchOn }) 351 .width(CommonConstants.CONTINUE_SWITCH_WIDTH) 352 .height(CommonConstants.CONTINUE_SWITCH_HEIGHT) 353 .hoverEffect(HoverEffect.None) 354 .enabled(this.isEnabled) 355 .onChange((isOn: boolean) => { 356 logger.info(`${TAG} isOn: ${isOn}`); 357 this.isSwitchOn = isOn; 358 AppStorage.setAndLink('isSwitchOn', isOn); 359 try { 360 if (isOn) { 361 let status: boolean = settings.setValueSync(context, CommonConstants.CONTINUE_SWITCH_KEY, 362 switchState.open, settings.domainName.USER_SECURITY); 363 logger.info(`${TAG} is set success :${status}; set:Continue_Switch_Status is open`); 364 } else { 365 let status: boolean = settings.setValueSync(context, CommonConstants.CONTINUE_SWITCH_KEY, 366 switchState.close, settings.domainName.USER_SECURITY); 367 logger.info(`${TAG} is set success :${status}; set:Continue_Switch_Status is close`); 368 } 369 } catch (error) { 370 logger.error(`${TAG} settings.setValueSync failed. error.message: ${error.message}`); 371 } 372 }) 373 } 374 .width('100%') 375 .padding({ 376 left: CommonConstants.TEXT_LIST_ALIGN_DISTANCE, 377 right: CommonConstants.TEXT_LIST_ALIGN_DISTANCE 378 }) 379 .backgroundColor($r('sys.color.ohos_id_color_list_card_bg')) 380 .borderRadius(this.is2in1 ? CommonConstants.PC_BORDER_RADIUS : CommonConstants.NON_PC_BORDER_RADIUS) 381 .accessibilityText(this.title) 382 } 383 .width('100%') 384 .constraintSize({ 385 minHeight: CommonConstants.PC_LIST_HEIGHT 386 }) 387 388 Column() { 389 Flex({ 390 direction: FlexDirection.Row, 391 justifyContent: FlexAlign.Start, 392 alignItems: ItemAlign.Center 393 }) { 394 SymbolGlyph($r('sys.symbol.info_circle_fill')) 395 .fontWeight(FontWeight.Medium) 396 .fontSize(CommonConstants.SYMBOL_INFO_CIRCLE) 397 .fontColor([$r('sys.color.ohos_id_color_activated')]) 398 .margin(this.isMirrorLanguages() ? { left: CommonConstants.SYMBOL_MARGIN_RIGHT } : 399 { right: CommonConstants.SYMBOL_MARGIN_RIGHT }) 400 .width(CommonConstants.SYMBOL_INFO_CIRCLE) 401 .height(CommonConstants.SYMBOL_INFO_CIRCLE) 402 .accessibilityLevel('no') 403 404 Text($r('app.string.update_version_prompt')) 405 .fontSize($r('sys.float.ohos_id_text_size_body3')) 406 .fontWeight(FontWeight.Medium) 407 .fontColor($r('sys.color.ohos_id_color_text_primary')) 408 .textAlign(TextAlign.Start) 409 .lineHeight(-1) 410 } 411 .margin({ top: CommonConstants.UPDATE_PROMPT_MARGIN_TOP }) 412 } 413 .padding({ 414 left: CommonConstants.TEXT_LIST_ALIGN_DISTANCE, 415 right: CommonConstants.TEXT_LIST_ALIGN_DISTANCE 416 }) 417 418 Column() { 419 Row() { 420 Text($r('app.string.continue_privacy_text')) 421 .fontSize($r('sys.float.ohos_id_text_size_body3')) 422 .fontWeight(FontWeight.Regular) 423 .margin({ top: CommonConstants.CONTINUE_PRIVACY_TEXT_MARGIN_TOP }) 424 .fontColor($r('sys.color.ohos_id_color_text_secondary')) 425 .textAlign(TextAlign.Start) 426 .width('100%') 427 .lineHeight(this.isTibetanLanguages() ? 19 : 0) 428 } 429 .padding({ 430 left: CommonConstants.TEXT_LIST_ALIGN_DISTANCE, 431 right: CommonConstants.TEXT_LIST_ALIGN_DISTANCE 432 }) 433 }.width('100%') 434 435 } 436 .width('100%') 437 .padding({ left: this.gapLength, right: this.gapLength }) 438 .margin({ bottom: this.contentHeight * 0.09 }) 439 .backgroundColor($r('sys.color.ohos_id_color_sub_background')) 440 .visibility(this.getContentVisibility()) 441 } 442 .width('100%') 443 .height(this.screenHeight) 444 .scrollable(ScrollDirection.Vertical) 445 .scrollBar(BarState.Off) 446 .align(Alignment.TopStart) 447 .friction(0.6) 448 .edgeEffect(EdgeEffect.Spring) 449 .onScrollEdge(() => { 450 logger.info('To the edge'); 451 }) 452 .onScrollStop(() => { 453 logger.info('Scroll Stop'); 454 }) 455 .onAreaChange((oldArea: Area, newArea: Area) => { 456 logger.info(`${TAG} Scroll, oldArea.height = ${oldArea.height}, newArea.height = ${newArea.height}`); 457 }) 458 459 ScrollBar({ scroller: this.scroller, direction: ScrollBarDirection.Vertical, state: BarState.Auto }) 460 .position({ right: 0, bottom: 16 }) 461 } 462 463 build() { 464 Column() { 465 if (this.isShowBack) { 466 this.NormalRootContent(); 467 } else { 468 this.SearchRootContent(); 469 } 470 } 471 .width('100%') 472 .height('100%') 473 .backgroundColor($r('sys.color.ohos_id_color_sub_background')) 474 .onAreaChange((oldArea: Area, newArea: Area) => { 475 logger.info(`${TAG} onAreaChange: newArea.width = ${newArea.width}, newArea.height = ${newArea.height}`); 476 if (typeof newArea.width === 'number' && typeof newArea.height === 'number') { 477 let width = newArea.width as number; 478 let halfHeight = (newArea.height as number) / 2; 479 try { 480 let displayInfo: display.Display | undefined = display.getDefaultDisplaySync(); 481 if (displayInfo) { 482 halfHeight = !this.is2in1 && displayInfo.height > 0 ? px2vp(displayInfo.height / 2) : (newArea.height / 2); 483 logger.info(`${TAG} display: halfHeight = ${halfHeight}`); 484 } 485 } catch (error) { 486 logger.error(`${TAG} getDefaultDisplaySync failed. error.message: ${error.message}`); 487 } 488 if (width > halfHeight) { 489 this.imageAnimatorWidth = halfHeight * 0.8; 490 this.imageAnimatorHeight = this.imageAnimatorWidth * 2 / 3; 491 } else { 492 this.imageAnimatorWidth = width * 0.8; 493 this.imageAnimatorHeight = this.imageAnimatorWidth * 2 / 3; 494 } 495 } 496 logger.info(`${TAG} this.imageAnimatorWidth = ${this.imageAnimatorWidth}, this.imageAnimatorHeight = ${this.imageAnimatorHeight}`); 497 }) 498 .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) 499 .padding({ bottom: $r('app.float.margin_16') }) 500 } 501 502 private getContentVisibility(): Visibility { 503 return (this.imageAnimatorWidth !== 0 && this.isAnimatorDone) ? Visibility.Visible : Visibility.Hidden; 504 } 505 506 private getImageAnimatorHeight(): number { 507 if (deviceInfo.deviceType === 'phone') { 508 return CommonConstants.ANIMATOR_HEIGHT_PHONE; 509 } else if (deviceInfo.deviceType === '2in1') { 510 return CommonConstants.ANIMATOR_HEIGHT_PC; 511 } else if (deviceInfo.deviceType === 'tablet') { 512 return CommonConstants.ANIMATOR_HEIGHT_PAD; 513 } 514 return CommonConstants.ANIMATOR_HEIGHT_PHONE; 515 } 516 517 private getImageAnimatorWidth(): number { 518 if (deviceInfo.deviceType === 'phone') { 519 return CommonConstants.ANIMATOR_WIDTH_PHONE; 520 } else if (deviceInfo.deviceType === '2in1') { 521 return CommonConstants.ANIMATOR_WIDTH_PC; 522 } else if (deviceInfo.deviceType === 'tablet') { 523 return CommonConstants.ANIMATOR_WIDTH_PAD; 524 } 525 return CommonConstants.ANIMATOR_WIDTH_PHONE; 526 } 527 528 private isPhone(): boolean { 529 logger.info(`${TAG} isPhone in`); 530 return (deviceInfo.deviceType === 'phone' || deviceInfo.deviceType === 'default'); 531 } 532 533 /** 534 * 根据折叠状态更新是否显示返回按钮 535 */ 536 private refreshFoldStatus(foldStatus: display.FoldStatus): void { 537 logger.info(`${TAG} refreshFoldStatus in. foldStatus: ${foldStatus}. startReason: ${this.startReason}`); 538 this.isShowBack = (this.startReason !== 'from_search' || foldStatus === display.FoldStatus.FOLD_STATUS_FOLDED); 539 logger.info(`${TAG} refreshFoldStatus end. this.isShowBack: ${this.isShowBack}.`); 540 } 541 542 /** 543 * 折叠状态发生变化 544 */ 545 private displayCallback: Callback<display.FoldStatus> = (data: display.FoldStatus) => { 546 this.refreshFoldStatus(data); 547 } 548 549 private registerFoldChangeListener(): void { 550 logger.info(`${TAG} registerFoldChangeListener in.isSmallFoldProduct: ${this.isSmallFoldProduct}`); 551 try { 552 // 首次非L+V折叠刷新isShowBack 553 if (!this.isSmallFoldProduct && display.isFoldable()) { 554 let data: display.FoldStatus = display.getFoldStatus(); 555 this.refreshFoldStatus(data); 556 } 557 display.on('foldStatusChange', this.displayCallback); 558 } catch (err) { 559 logger.error(`${TAG} registerFoldChangeListener failed. err.message: ${err.message}`); 560 } 561 } 562 563 private unRegisterFoldChangeListener(): void { 564 logger.info(`${TAG} unRegisterFoldChangeListener in.`); 565 try { 566 display.off('foldStatusChange', this.displayCallback); 567 } catch (err) { 568 logger.error(`${TAG} unRegisterFoldChangeListener failed. err.message: ${err.message}`); 569 } 570 } 571 572 private isMirrorLanguages(): 573 boolean { 574 logger.info(`${TAG} isMirrorLanguages in`); 575 let locale = new Intl.Locale(i18n.System.getSystemLanguage()).toString(); 576 return CommonConstants.MIRROR_LANGUAGES.includes(locale); 577 } 578 579 private isTibetanLanguages(): 580 boolean { 581 logger.info(`${TAG} isTibetanLanguages in`); 582 let locale = new Intl.Locale(i18n.System.getSystemLanguage()).toString(); 583 logger.info(`${TAG} isTibetanLanguages: ${locale}`); 584 return CommonConstants.TIBETAN_LANGUAGES.includes(locale); 585 } 586}