1/* 2 * Copyright (c) 2023-2025 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 */ 15 16if (!('finalizeConstruction' in ViewPU.prototype)) { 17 Reflect.set(ViewPU.prototype, 'finalizeConstruction', () => { 18 }); 19} 20const curves = requireNativeModule('ohos.curves'); 21const hilog = requireNapi('hilog'); 22const LengthMetrics = requireNapi('arkui.node').LengthMetrics; 23const i18n = requireNapi('i18n'); 24 25const i14 = 250; 26const j14 = 200; 27const k14 = 12; 28const l14 = 9; 29const n14 = 24; 30const o14 = 2; 31const p14 = 1; 32const q14 = 1; 33 34export var MarginType; 35(function (MarginType) { 36 MarginType[MarginType['DEFAULT_MARGIN'] = 0] = 'DEFAULT_MARGIN'; 37 MarginType[MarginType['FIT_MARGIN'] = 1] = 'FIT_MARGIN'; 38})(MarginType || (MarginType = {})); 39 40export class ExceptionPrompt extends ViewPU { 41 constructor(parent, params, __localStorage, elmtId = -1, paramsLambda = undefined, extraInfo) { 42 super(parent, __localStorage, elmtId, extraInfo); 43 if (typeof paramsLambda === 'function') { 44 this.paramsGenerator_ = paramsLambda; 45 } 46 this.__options = new SynchedPropertyObjectOneWayPU(params.options, this, 'options'); 47 this.__fontSizeScale = new ObservedPropertyObjectPU(undefined, this, 'fontSizeScale'); 48 this.touchBackgroundColor = { 49 'id': -1, 50 'type': 10001, 51 params: ['sys.color.ohos_id_color_sub_background_transparent'], 52 'bundleName': '__harDefaultBundleName__', 53 'moduleName': '__harDefaultModuleName__' 54 }; 55 this.maxAppFontScale = 1; 56 this.isFollowingSystemFontScale = false; 57 this.onTipClick = undefined; 58 this.onActionTextClick = undefined; 59 this.callbackId = undefined; 60 this.callbacks = { 61 onConfigurationUpdated: (config) => { 62 this.fontSizeScale = Math.min(this.updateFontScale(), o14); 63 this.fontSizeScale = Math.max(this.fontSizeScale, p14); 64 }, 65 onMemoryLevel() { 66 } 67 }; 68 this.setInitiallyProvidedValue(params); 69 this.finalizeConstruction(); 70 } 71 72 setInitiallyProvidedValue(params) { 73 if (params.fontSizeScale !== undefined) { 74 this.fontSizeScale = params.fontSizeScale; 75 } 76 if (params.touchBackgroundColor !== undefined) { 77 this.touchBackgroundColor = params.touchBackgroundColor; 78 } 79 if (params.maxAppFontScale !== undefined) { 80 this.maxAppFontScale = params.maxAppFontScale; 81 } 82 if (params.isFollowingSystemFontScale !== undefined) { 83 this.isFollowingSystemFontScale = params.isFollowingSystemFontScale; 84 } 85 if (params.onTipClick !== undefined) { 86 this.onTipClick = params.onTipClick; 87 } 88 if (params.onActionTextClick !== undefined) { 89 this.onActionTextClick = params.onActionTextClick; 90 } 91 if (params.callbackId !== undefined) { 92 this.callbackId = params.callbackId; 93 } 94 if (params.callbacks !== undefined) { 95 this.callbacks = params.callbacks; 96 } 97 } 98 99 updateStateVars(params) { 100 this.__options.reset(params.options); 101 } 102 103 purgeVariableDependenciesOnElmtId(rmElmtId) { 104 this.__options.purgeDependencyOnElmtId(rmElmtId); 105 this.__fontSizeScale.purgeDependencyOnElmtId(rmElmtId); 106 } 107 108 aboutToBeDeleted() { 109 this.__options.aboutToBeDeleted(); 110 this.__fontSizeScale.aboutToBeDeleted(); 111 SubscriberManager.Get().delete(this.id__()); 112 this.aboutToBeDeletedInternal(); 113 } 114 115 get options() { 116 return this.__options.get(); 117 } 118 119 set options(newValue) { 120 this.__options.set(newValue); 121 } 122 123 get fontSizeScale() { 124 return this.__fontSizeScale.get(); 125 } 126 127 set fontSizeScale(newValue) { 128 this.__fontSizeScale.set(newValue); 129 } 130 131 TextBuilder(parent = null) { 132 this.observeComponentCreation2((elmtId, isInitialRender) => { 133 Flex.create({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }); 134 Flex.padding({ 135 left: { 136 'id': -1, 137 'type': 10002, 138 params: ['sys.float.ohos_id_notification_margin_start'], 139 'bundleName': '__harDefaultBundleName__', 140 'moduleName': '__harDefaultModuleName__' 141 }, 142 right: { 143 'id': -1, 144 'type': 10002, 145 params: ['sys.float.ohos_id_text_paragraph_margin_s'], 146 'bundleName': '__harDefaultBundleName__', 147 'moduleName': '__harDefaultModuleName__' 148 }, 149 top: { 150 'id': -1, 151 'type': 10002, 152 params: ['sys.float.ohos_id_default_padding_start'], 153 'bundleName': '__harDefaultBundleName__', 154 'moduleName': '__harDefaultModuleName__' 155 }, 156 bottom: { 157 'id': -1, 158 'type': 10002, 159 params: ['sys.float.ohos_id_default_padding_end'], 160 'bundleName': '__harDefaultBundleName__', 161 'moduleName': '__harDefaultModuleName__' 162 } 163 }); 164 }, Flex); 165 this.observeComponentCreation2((elmtId, isInitialRender) => { 166 Row.create(); 167 Row.padding({ 168 right: { 169 'id': -1, 170 'type': 10002, 171 params: ['sys.float.ohos_id_default_padding_end'], 172 'bundleName': '__harDefaultBundleName__', 173 'moduleName': '__harDefaultModuleName__' 174 } 175 }); 176 Row.width('100%'); 177 Row.accessibilityDescription(this.onTipClick ? '' : ' '); 178 Row.onClick(() => { 179 this.onTipClick && this.onTipClick(); 180 }); 181 }, Row); 182 this.observeComponentCreation2((elmtId, isInitialRender) => { 183 If.create(); 184 if (this.options?.symbolStyle !== undefined) { 185 this.ifElseBranchUpdateFunction(0, () => { 186 this.observeComponentCreation2((elmtId, isInitialRender) => { 187 SymbolGlyph.create(); 188 SymbolGlyph.fontColor([{ 189 'id': -1, 190 'type': 10001, 191 params: ['sys.color.ohos_id_color_warning'], 192 'bundleName': '__harDefaultBundleName__', 193 'moduleName': '__harDefaultModuleName__' 194 }]); 195 SymbolGlyph.attributeModifier.bind(this)(this.options?.symbolStyle); 196 SymbolGlyph.effectStrategy(SymbolEffectStrategy.NONE); 197 SymbolGlyph.symbolEffect(new SymbolEffect(), false); 198 SymbolGlyph.fontSize(`${(this.fontSizeScale ?? q14) * n14}vp`); 199 }, SymbolGlyph); 200 }); 201 } else { 202 this.ifElseBranchUpdateFunction(1, () => { 203 this.observeComponentCreation2((elmtId, isInitialRender) => { 204 If.create(); 205 if (Util.v14(this.options?.icon)) { 206 this.ifElseBranchUpdateFunction(0, () => { 207 this.observeComponentCreation2((elmtId, isInitialRender) => { 208 SymbolGlyph.create(this.options?.icon ?? { 209 'id': -1, 210 'type': 40000, 211 params: ['sys.symbol.exclamationmark_circle'], 212 'bundleName': '__harDefaultBundleName__', 213 'moduleName': '__harDefaultModuleName__' 214 }); 215 SymbolGlyph.fontColor([{ 216 'id': -1, 217 'type': 10001, 218 params: ['sys.color.ohos_id_color_warning'], 219 'bundleName': '__harDefaultBundleName__', 220 'moduleName': '__harDefaultModuleName__' 221 }]); 222 SymbolGlyph.fontSize(`${(this.fontSizeScale ?? q14) * n14}vp`); 223 }, SymbolGlyph); 224 }); 225 } else { 226 this.ifElseBranchUpdateFunction(1, () => { 227 this.observeComponentCreation2((elmtId, isInitialRender) => { 228 Image.create(this.options?.icon); 229 Image.width('24vp'); 230 Image.height('24vp'); 231 Image.fillColor({ 232 'id': -1, 233 'type': 10001, 234 params: ['sys.color.ohos_id_color_warning'], 235 'bundleName': '__harDefaultBundleName__', 236 'moduleName': '__harDefaultModuleName__' 237 }); 238 }, Image); 239 }); 240 } 241 }, If); 242 If.pop(); 243 }); 244 } 245 }, If); 246 If.pop(); 247 this.observeComponentCreation2((elmtId, isInitialRender) => { 248 Text.create(this.options.tip); 249 Text.fontSize({ 250 'id': -1, 251 'type': 10002, 252 params: ['sys.float.ohos_id_text_size_body1'], 253 'bundleName': '__harDefaultBundleName__', 254 'moduleName': '__harDefaultModuleName__' 255 }); 256 Text.minFontScale(1); 257 Text.maxFontScale(Math.min(this.updateFontScale(), 2)); 258 Text.fontColor({ 259 'id': -1, 260 'type': 10001, 261 params: ['sys.color.ohos_id_color_warning'], 262 'bundleName': '__harDefaultBundleName__', 263 'moduleName': '__harDefaultModuleName__' 264 }); 265 Text.textOverflow({ overflow: TextOverflow.Ellipsis }); 266 Text.maxLines(2); 267 Text.margin({ 268 start: LengthMetrics.resource({ 269 'id': -1, 270 'type': 10002, 271 params: ['sys.float.ohos_id_dialog_margin_end'], 272 'bundleName': '__harDefaultBundleName__', 273 'moduleName': '__harDefaultModuleName__' 274 }) 275 }); 276 Text.flexShrink(1); 277 Text.direction(i18n.isRTL(i18n.System.getSystemLanguage()) ? Direction.Rtl : Direction.Ltr); 278 }, Text); 279 Text.pop(); 280 Row.pop(); 281 this.observeComponentCreation2((elmtId, isInitialRender) => { 282 If.create(); 283 if (this.options.actionText) { 284 this.ifElseBranchUpdateFunction(0, () => { 285 this.observeComponentCreation2((elmtId, isInitialRender) => { 286 Button.createWithChild({ stateEffect: false, type: ButtonType.Normal }); 287 Button.backgroundColor(this.touchBackgroundColor); 288 Button.width(this.options.actionText ? 144 : 0); 289 Button.borderRadius({ 290 'id': -1, 291 'type': 10002, 292 params: ['sys.float.ohos_id_corner_radius_subtab'], 293 'bundleName': '__harDefaultBundleName__', 294 'moduleName': '__harDefaultModuleName__' 295 }); 296 Button.padding({ 297 right: { 298 'id': -1, 299 'type': 10002, 300 params: ['sys.float.padding_level2'], 301 'bundleName': '__harDefaultBundleName__', 302 'moduleName': '__harDefaultModuleName__' 303 }, 304 }); 305 Button.accessibilityDescription(this.onActionTextClick ? '' : ' '); 306 Button.accessibilityRole(this.onActionTextClick ? AccessibilityRoleType.BUTTON : 307 AccessibilityRoleType.ROLE_NONE); 308 Button.onClick(() => { 309 this.onActionTextClick && this.onActionTextClick(); 310 }); 311 }, Button); 312 this.observeComponentCreation2((elmtId, isInitialRender) => { 313 Row.create(); 314 Row.width('100%'); 315 Row.justifyContent(FlexAlign.End); 316 }, Row); 317 this.observeComponentCreation2((elmtId, isInitialRender) => { 318 Text.create(this.options.actionText); 319 Text.fontSize({ 320 'id': -1, 321 'type': 10002, 322 params: ['sys.float.ohos_id_text_size_body2'], 323 'bundleName': '__harDefaultBundleName__', 324 'moduleName': '__harDefaultModuleName__' 325 }); 326 Text.minFontScale(1); 327 Text.maxFontScale(Math.min(this.updateFontScale(), 2)); 328 Text.fontColor({ 329 'id': -1, 330 'type': 10001, 331 params: ['sys.color.ohos_id_color_text_secondary'], 332 'bundleName': '__harDefaultBundleName__', 333 'moduleName': '__harDefaultModuleName__' 334 }); 335 Text.maxLines(2); 336 Text.padding(0); 337 Text.margin({ 338 end: LengthMetrics.resource({ 339 'id': -1, 340 'type': 10002, 341 params: ['sys.float.ohos_id_text_paragraph_margin_s'], 342 'bundleName': '__harDefaultBundleName__', 343 'moduleName': '__harDefaultModuleName__' 344 }) 345 }); 346 Text.textOverflow({ overflow: TextOverflow.Ellipsis }); 347 Text.flexShrink(1); 348 Text.textAlign(TextAlign.End); 349 Text.direction(i18n.isRTL(i18n.System.getSystemLanguage()) ? Direction.Rtl : Direction.Ltr); 350 }, Text); 351 Text.pop(); 352 this.observeComponentCreation2((elmtId, isInitialRender) => { 353 SymbolGlyph.create({ 354 'id': -1, 355 'type': 40000, 356 params: ['sys.symbol.chevron_right'], 357 'bundleName': '__harDefaultBundleName__', 358 'moduleName': '__harDefaultModuleName__' 359 }); 360 SymbolGlyph.fontSize(`${(this.fontSizeScale ?? q14) * n14}vp`); 361 SymbolGlyph.fontColor([{ 362 'id': -1, 363 'type': 10001, 364 params: ['sys.color.ohos_id_color_tertiary'], 365 'bundleName': '__harDefaultBundleName__', 366 'moduleName': '__harDefaultModuleName__' 367 }]); 368 }, SymbolGlyph); 369 Row.pop(); 370 Button.pop(); 371 }); 372 } else { 373 this.ifElseBranchUpdateFunction(1, () => { 374 }); 375 } 376 }, If); 377 If.pop(); 378 Flex.pop(); 379 } 380 381 initialRender() { 382 this.observeComponentCreation2((elmtId, isInitialRender) => { 383 Row.create(); 384 Row.width('100%'); 385 Row.position({ y: this.options.marginTop }); 386 Row.zIndex(l14); 387 }, Row); 388 this.observeComponentCreation2((elmtId, isInitialRender) => { 389 Column.create(); 390 Column.padding(this.options.marginType === MarginType.DEFAULT_MARGIN ? { 391 left: { 392 'id': -1, 393 'type': 10002, 394 params: ['sys.float.ohos_id_card_margin_start'], 395 'bundleName': '__harDefaultBundleName__', 396 'moduleName': '__harDefaultModuleName__' 397 }, 398 right: { 399 'id': -1, 400 'type': 10002, 401 params: ['sys.float.ohos_id_card_margin_end'], 402 'bundleName': '__harDefaultBundleName__', 403 'moduleName': '__harDefaultModuleName__' 404 } 405 } : { 406 left: { 407 'id': -1, 408 'type': 10002, 409 params: ['sys.float.ohos_id_max_padding_start'], 410 'bundleName': '__harDefaultBundleName__', 411 'moduleName': '__harDefaultModuleName__' 412 }, 413 right: { 414 'id': -1, 415 'type': 10002, 416 params: ['sys.float.ohos_id_max_padding_end'], 417 'bundleName': '__harDefaultBundleName__', 418 'moduleName': '__harDefaultModuleName__' 419 } 420 }); 421 Column.transition(TransitionEffect.OPACITY.animation({ 422 curve: curves.cubicBezierCurve(0.33, 0, 0.67, 1), 423 duration: this.options.isShown ? i14 : j14 424 })); 425 Column.visibility(this.options.isShown ? Visibility.Visible : Visibility.None); 426 }, Column); 427 this.observeComponentCreation2((elmtId, isInitialRender) => { 428 Column.create(); 429 Column.width('100%'); 430 Column.borderRadius(k14); 431 Column.backgroundColor({ 432 'id': -1, 433 'type': 10001, 434 params: ['sys.color.comp_background_warning_secondary'], 435 'bundleName': '__harDefaultBundleName__', 436 'moduleName': '__harDefaultModuleName__' 437 }); 438 Column.zIndex(l14); 439 }, Column); 440 this.TextBuilder.bind(this)(); 441 Column.pop(); 442 Column.pop(); 443 Row.pop(); 444 } 445 446 aboutToAppear() { 447 try { 448 let u14 = this.getUIContext(); 449 this.isFollowingSystemFontScale = u14.isFollowingSystemFontScale(); 450 this.maxAppFontScale = u14.getMaxFontScale(); 451 this.fontSizeScale = Math.min(this.updateFontScale(), o14); 452 this.fontSizeScale = Math.max(this.fontSizeScale, p14); 453 this.callbackId = u14.getHostContext()?.getApplicationContext()?.on('environment', this.callbacks); 454 } catch (err) { 455 let code = err.code; 456 let message = err.message; 457 hilog.error(0x3900, 'Ace', `Failed to init fontsizescale info, cause, code: ${code}, message: ${message}`); 458 } 459 } 460 461 aboutToDisappear() { 462 if (this.callbackId) { 463 this.getUIContext().getHostContext()?.getApplicationContext()?.off('environment', this.callbackId); 464 this.callbackId = void (0); 465 } 466 } 467 468 updateFontScale() { 469 let s14 = this.getUIContext(); 470 let t14 = s14.getHostContext()?.config?.fontSizeScale ?? 1; 471 if (!this.isFollowingSystemFontScale) { 472 return 1; 473 } 474 return Math.min(t14, this.maxAppFontScale); 475 } 476 477 rerender() { 478 this.updateDirtyElements(); 479 } 480} 481 482class Util { 483 static v14(r14) { 484 if (r14 === undefined) { 485 return true; 486 } 487 if (!Util.w14(r14)) { 488 return false; 489 } 490 let resource = r14; 491 return resource.type === Util.x14; 492 } 493 494 static w14(resource) { 495 if (!resource) { 496 return false; 497 } 498 return typeof resource !== 'string'; 499 } 500} 501 502Util.x14 = 40000; 503 504export default { 505 MarginType, 506 ExceptionPrompt 507}