1/* 2 * Copyright (c) 2023-2023 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 curves from '@ohos.curves'; 16import { common } from '@kit.AbilityKit'; 17import { BusinessError } from '@kit.BasicServicesKit'; 18import { hilog } from '@kit.PerformanceAnalysisKit'; 19 20const START_TIME = 250; 21const END_TIME = 200; 22const BORDER_RADIUS = 12; 23const ZINDEX_NUM = 9; 24 25 26export enum MarginType { 27 DEFAULT_MARGIN = 0, 28 FIT_MARGIN = 1, 29} 30 31export interface PromptOptions { 32 icon?: ResourceStr, 33 tip?: ResourceStr, 34 marginType: MarginType, 35 actionText?: ResourceStr, 36 marginTop: Dimension, 37 isShown?: boolean 38} 39 40@Component 41export struct ExceptionPrompt { 42 @Prop options: PromptOptions 43 touchBackgroundColor: Resource = $r('sys.color.ohos_id_color_sub_background_transparent') 44 maxAppFontScale: number = 1; 45 isFollowingSystemFontScale: boolean = false; 46 onTipClick: () => void = () => { 47 // Click the text on the left to change into the connecting state 48 } 49 onActionTextClick: () => void = () => { 50 // Click Set Network to open the Set network pop-up interface 51 } 52 53 @Builder 54 TextBuilder() { 55 Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign 56 .Center }) { 57 Row() { 58 Image(this.options.icon ?? $r('sys.media.ohos_ic_public_fail')) 59 .width("24vp") 60 .height('24vp') 61 .fillColor($r('sys.color.ohos_id_color_warning')) 62 Text(this.options.tip) 63 .fontSize($r('sys.float.ohos_id_text_size_body1')) 64 .minFontScale(1) 65 .maxFontScale(Math.min(this.updateFontScale(), 2)) 66 .fontColor($r('sys.color.ohos_id_color_warning')) 67 .textOverflow({ overflow: TextOverflow.Ellipsis }) 68 .maxLines(2) 69 .margin({ 70 left: $r('sys.float.ohos_id_dialog_margin_end'), 71 right: $r('sys.float.ohos_id_dialog_margin_end') 72 }) 73 } 74 .padding({ right: $r('sys.float.ohos_id_default_padding_end') }) 75 .width('100%') 76 .onClick(() => { 77 this.onTipClick() //Click the callback of the prompt text 78 }) 79 80 if (this.options.actionText) { 81 Button({ stateEffect: true, type: ButtonType.Normal }) { 82 Row() { 83 Text(this.options.actionText) 84 .fontSize($r('sys.float.ohos_id_text_size_body2')) 85 .minFontScale(1) 86 .maxFontScale(Math.min(this.updateFontScale(), 2)) 87 .fontColor($r('sys.color.ohos_id_color_text_secondary')) 88 .maxLines(2) 89 .padding(0) 90 .margin({ right: $r('sys.float.ohos_id_text_paragraph_margin_s') }) 91 .textOverflow({ overflow: TextOverflow.Ellipsis }) 92 Image($r('sys.media.ohos_ic_public_arrow_right')) 93 .width('12vp') 94 .height('24vp') 95 .fillColor($r('sys.color.ohos_id_color_tertiary')) 96 } 97 } 98 .backgroundColor(this.touchBackgroundColor) 99 .width(this.options.actionText ? 144 : 0) 100 .borderRadius($r('sys.float.ohos_id_corner_radius_subtab')) 101 .padding({ 102 right: $r('sys.float.ohos_id_elements_margin_vertical_l'), 103 left: $r('sys.float.ohos_id_elements_margin_vertical_l') 104 }) 105 .onTouch((event) => { 106 107 if (event.type === TouchType.Down) { 108 this.touchBackgroundColor = $r('sys.color.ohos_id_color_click_effect') 109 this.onActionTextClick() //Click the icon button on the right for the callback 110 } else if (event.type === TouchType.Up) { 111 this.touchBackgroundColor = $r('sys.color.ohos_id_color_sub_background_transparent') 112 } 113 }) 114 115 } 116 } 117 .padding({ 118 left: $r('sys.float.ohos_id_notification_margin_start'), 119 right: $r('sys.float.ohos_id_text_paragraph_margin_s'), 120 top: $r('sys.float.ohos_id_default_padding_start'), 121 bottom: $r('sys.float.ohos_id_default_padding_end') 122 }) 123 } 124 125 build() { 126 Row() { 127 Column() { 128 Column() { 129 this.TextBuilder() 130 } 131 .width('100%') 132 .borderRadius(BORDER_RADIUS) 133 .backgroundColor($r('sys.color.comp_background_warning_secondary')) 134 .zIndex(ZINDEX_NUM) 135 } 136 .padding(this.options.marginType === MarginType.DEFAULT_MARGIN ? { 137 left: $r('sys.float.ohos_id_card_margin_start'), 138 right: $r('sys.float.ohos_id_card_margin_end') 139 } : { 140 left: $r('sys.float.ohos_id_max_padding_start'), 141 right: $r('sys.float.ohos_id_max_padding_end') 142 }) 143 .transition( 144 TransitionEffect.OPACITY.animation({ 145 curve: curves.cubicBezierCurve(0.33, 0, 0.67, 1), 146 duration: this.options.isShown ? START_TIME : END_TIME 147 }) 148 ) 149 .visibility(this.options.isShown ? Visibility.Visible : Visibility.None) 150 } 151 .width('100%') 152 .position({ y: this.options.marginTop }) 153 .zIndex(ZINDEX_NUM) 154 } 155 156 aboutToAppear() { 157 try { 158 let uiContent: UIContext = this.getUIContext(); 159 this.isFollowingSystemFontScale = uiContent.isFollowingSystemFontScale(); 160 this.maxAppFontScale = uiContent.getMaxFontScale(); 161 } catch (err) { 162 let code: number = (err as BusinessError).code; 163 let message: string = (err as BusinessError).message; 164 hilog.error(0x3900, 'Ace', `Failed to init fontsizescale info, cause, code: ${code}, message: ${message}`); 165 } 166 } 167 168 updateFontScale(): number { 169 let uiContent: UIContext = this.getUIContext(); 170 let systemFontScale = (uiContent.getHostContext() as common.UIAbilityContext)?.config?.fontSizeScale ?? 1; 171 if (!this.isFollowingSystemFontScale) { 172 return 1; 173 } 174 return Math.min(systemFontScale, this.maxAppFontScale); 175 } 176}